OSDN Git Service

DO NOT MERGE. KEY_INTENT shouldn't grant permissions. am: 1f2a5d3622 -s ours am...
[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.FULLSCREEN_WORKSPACE_STACK_ID;
32 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
33 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
34 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
35 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
36 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
37 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
38 import static android.content.pm.PackageManager.GET_PROVIDERS;
39 import static android.content.pm.PackageManager.MATCH_ANY_USER;
40 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
41 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
43 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
44 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
45 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
46 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
47 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
49 import static android.os.Build.VERSION_CODES.N;
50 import static android.os.Process.BLUETOOTH_UID;
51 import static android.os.Process.FIRST_APPLICATION_UID;
52 import static android.os.Process.FIRST_ISOLATED_UID;
53 import static android.os.Process.LAST_ISOLATED_UID;
54 import static android.os.Process.NFC_UID;
55 import static android.os.Process.PHONE_UID;
56 import static android.os.Process.PROC_CHAR;
57 import static android.os.Process.PROC_OUT_LONG;
58 import static android.os.Process.PROC_PARENS;
59 import static android.os.Process.PROC_SPACE_TERM;
60 import static android.os.Process.ProcessStartResult;
61 import static android.os.Process.ROOT_UID;
62 import static android.os.Process.SCHED_FIFO;
63 import static android.os.Process.SCHED_OTHER;
64 import static android.os.Process.SCHED_RESET_ON_FORK;
65 import static android.os.Process.SHELL_UID;
66 import static android.os.Process.SIGNAL_QUIT;
67 import static android.os.Process.SIGNAL_USR1;
68 import static android.os.Process.SYSTEM_UID;
69 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
70 import static android.os.Process.THREAD_GROUP_DEFAULT;
71 import static android.os.Process.THREAD_GROUP_TOP_APP;
72 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
73 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
74 import static android.os.Process.getFreeMemory;
75 import static android.os.Process.getTotalMemory;
76 import static android.os.Process.isThreadInProcess;
77 import static android.os.Process.killProcess;
78 import static android.os.Process.killProcessQuiet;
79 import static android.os.Process.myPid;
80 import static android.os.Process.myUid;
81 import static android.os.Process.readProcFile;
82 import static android.os.Process.removeAllProcessGroups;
83 import static android.os.Process.sendSignal;
84 import static android.os.Process.setProcessGroup;
85 import static android.os.Process.setThreadPriority;
86 import static android.os.Process.setThreadScheduler;
87 import static android.os.Process.startWebView;
88 import static android.os.Process.zygoteProcess;
89 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
90 import static android.provider.Settings.Global.DEBUG_APP;
91 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
92 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
94 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
95 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
96 import static android.provider.Settings.System.FONT_SCALE;
97 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
98 import static android.view.Display.DEFAULT_DISPLAY;
99 import static android.view.Display.INVALID_DISPLAY;
100 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
101 import static com.android.internal.util.XmlUtils.readIntAttribute;
102 import static com.android.internal.util.XmlUtils.readLongAttribute;
103 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
104 import static com.android.internal.util.XmlUtils.writeIntAttribute;
105 import static com.android.internal.util.XmlUtils.writeLongAttribute;
106 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
107 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
140 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
165 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
167 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
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.IActivityContainer;
215 import android.app.IActivityContainerCallback;
216 import android.app.IActivityController;
217 import android.app.IActivityManager;
218 import android.app.IAppTask;
219 import android.app.IApplicationThread;
220 import android.app.IInstrumentationWatcher;
221 import android.app.INotificationManager;
222 import android.app.IProcessObserver;
223 import android.app.IServiceConnection;
224 import android.app.IStopUserCallback;
225 import android.app.ITaskStackListener;
226 import android.app.IUiAutomationConnection;
227 import android.app.IUidObserver;
228 import android.app.IUserSwitchObserver;
229 import android.app.Instrumentation;
230 import android.app.Notification;
231 import android.app.NotificationManager;
232 import android.app.PendingIntent;
233 import android.app.PictureInPictureParams;
234 import android.app.ProfilerInfo;
235 import android.app.RemoteAction;
236 import android.app.WaitResult;
237 import android.app.admin.DevicePolicyManager;
238 import android.app.assist.AssistContent;
239 import android.app.assist.AssistStructure;
240 import android.app.backup.IBackupManager;
241 import android.app.usage.UsageEvents;
242 import android.app.usage.UsageStatsManagerInternal;
243 import android.appwidget.AppWidgetManager;
244 import android.content.ActivityNotFoundException;
245 import android.content.BroadcastReceiver;
246 import android.content.ClipData;
247 import android.content.ComponentCallbacks2;
248 import android.content.ComponentName;
249 import android.content.ContentProvider;
250 import android.content.ContentResolver;
251 import android.content.Context;
252 import android.content.DialogInterface;
253 import android.content.IContentProvider;
254 import android.content.IIntentReceiver;
255 import android.content.IIntentSender;
256 import android.content.Intent;
257 import android.content.IntentFilter;
258 import android.content.IntentSender;
259 import android.content.pm.ActivityInfo;
260 import android.content.pm.ApplicationInfo;
261 import android.content.pm.ConfigurationInfo;
262 import android.content.pm.IPackageDataObserver;
263 import android.content.pm.IPackageManager;
264 import android.content.pm.InstrumentationInfo;
265 import android.content.pm.PackageInfo;
266 import android.content.pm.PackageManager;
267 import android.content.pm.PackageManager.NameNotFoundException;
268 import android.content.pm.PackageManagerInternal;
269 import android.content.pm.ParceledListSlice;
270 import android.content.pm.PathPermission;
271 import android.content.pm.PermissionInfo;
272 import android.content.pm.ProviderInfo;
273 import android.content.pm.ResolveInfo;
274 import android.content.pm.SELinuxUtil;
275 import android.content.pm.ServiceInfo;
276 import android.content.pm.UserInfo;
277 import android.content.res.CompatibilityInfo;
278 import android.content.res.Configuration;
279 import android.content.res.Resources;
280 import android.database.ContentObserver;
281 import android.graphics.Bitmap;
282 import android.graphics.Point;
283 import android.graphics.Rect;
284 import android.location.LocationManager;
285 import android.media.audiofx.AudioEffect;
286 import android.metrics.LogMaker;
287 import android.net.Proxy;
288 import android.net.ProxyInfo;
289 import android.net.Uri;
290 import android.os.BatteryStats;
291 import android.os.Binder;
292 import android.os.Build;
293 import android.os.Bundle;
294 import android.os.Debug;
295 import android.os.DropBoxManager;
296 import android.os.Environment;
297 import android.os.FactoryTest;
298 import android.os.FileObserver;
299 import android.os.FileUtils;
300 import android.os.Handler;
301 import android.os.IBinder;
302 import android.os.IDeviceIdentifiersPolicyService;
303 import android.os.IPermissionController;
304 import android.os.IProcessInfoService;
305 import android.os.IProgressListener;
306 import android.os.LocaleList;
307 import android.os.Looper;
308 import android.os.Message;
309 import android.os.Parcel;
310 import android.os.ParcelFileDescriptor;
311 import android.os.PersistableBundle;
312 import android.os.PowerManager;
313 import android.os.PowerManagerInternal;
314 import android.os.Process;
315 import android.os.RemoteCallbackList;
316 import android.os.RemoteException;
317 import android.os.ResultReceiver;
318 import android.os.ServiceManager;
319 import android.os.ShellCallback;
320 import android.os.StrictMode;
321 import android.os.SystemClock;
322 import android.os.SystemProperties;
323 import android.os.Trace;
324 import android.os.TransactionTooLargeException;
325 import android.os.UpdateLock;
326 import android.os.UserHandle;
327 import android.os.UserManager;
328 import android.os.WorkSource;
329 import android.os.storage.IStorageManager;
330 import android.os.storage.StorageManager;
331 import android.os.storage.StorageManagerInternal;
332 import android.provider.Downloads;
333 import android.provider.Settings;
334 import android.service.voice.IVoiceInteractionSession;
335 import android.service.voice.VoiceInteractionManagerInternal;
336 import android.service.voice.VoiceInteractionSession;
337 import android.telecom.TelecomManager;
338 import android.text.TextUtils;
339 import android.text.format.DateUtils;
340 import android.text.format.Time;
341 import android.text.style.SuggestionSpan;
342 import android.util.ArrayMap;
343 import android.util.ArraySet;
344 import android.util.AtomicFile;
345 import android.util.BootTimingsTraceLog;
346 import android.util.DebugUtils;
347 import android.util.DisplayMetrics;
348 import android.util.EventLog;
349 import android.util.Log;
350 import android.util.Pair;
351 import android.util.PrintWriterPrinter;
352 import android.util.Slog;
353 import android.util.SparseArray;
354 import android.util.SparseIntArray;
355 import android.util.TimeUtils;
356 import android.util.Xml;
357 import android.view.Gravity;
358 import android.view.LayoutInflater;
359 import android.view.View;
360 import android.view.WindowManager;
361
362 import com.android.server.job.JobSchedulerInternal;
363 import com.google.android.collect.Lists;
364 import com.google.android.collect.Maps;
365
366 import com.android.internal.R;
367 import com.android.internal.annotations.GuardedBy;
368 import com.android.internal.annotations.VisibleForTesting;
369 import com.android.internal.app.AssistUtils;
370 import com.android.internal.app.DumpHeapActivity;
371 import com.android.internal.app.IAppOpsCallback;
372 import com.android.internal.app.IAppOpsService;
373 import com.android.internal.app.IVoiceInteractor;
374 import com.android.internal.app.ProcessMap;
375 import com.android.internal.app.SystemUserHomeActivity;
376 import com.android.internal.app.procstats.ProcessStats;
377 import com.android.internal.logging.MetricsLogger;
378 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
379 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
380 import com.android.internal.notification.SystemNotificationChannels;
381 import com.android.internal.os.BackgroundThread;
382 import com.android.internal.os.BatteryStatsImpl;
383 import com.android.internal.os.IResultReceiver;
384 import com.android.internal.os.ProcessCpuTracker;
385 import com.android.internal.os.TransferPipe;
386 import com.android.internal.os.Zygote;
387 import com.android.internal.policy.IKeyguardDismissCallback;
388 import com.android.internal.telephony.TelephonyIntents;
389 import com.android.internal.util.ArrayUtils;
390 import com.android.internal.util.DumpUtils;
391 import com.android.internal.util.FastPrintWriter;
392 import com.android.internal.util.FastXmlSerializer;
393 import com.android.internal.util.MemInfoReader;
394 import com.android.internal.util.Preconditions;
395 import com.android.server.AppOpsService;
396 import com.android.server.AttributeCache;
397 import com.android.server.DeviceIdleController;
398 import com.android.server.IntentResolver;
399 import com.android.server.LocalServices;
400 import com.android.server.LockGuard;
401 import com.android.server.NetworkManagementInternal;
402 import com.android.server.RescueParty;
403 import com.android.server.ServiceThread;
404 import com.android.server.SystemConfig;
405 import com.android.server.SystemService;
406 import com.android.server.SystemServiceManager;
407 import com.android.server.ThreadPriorityBooster;
408 import com.android.server.Watchdog;
409 import com.android.server.am.ActivityStack.ActivityState;
410 import com.android.server.firewall.IntentFirewall;
411 import com.android.server.pm.Installer;
412 import com.android.server.pm.Installer.InstallerException;
413 import com.android.server.statusbar.StatusBarManagerInternal;
414 import com.android.server.vr.VrManagerInternal;
415 import com.android.server.wm.PinnedStackWindowController;
416 import com.android.server.wm.WindowManagerService;
417
418 import org.xmlpull.v1.XmlPullParser;
419 import org.xmlpull.v1.XmlPullParserException;
420 import org.xmlpull.v1.XmlSerializer;
421
422 import java.io.File;
423 import java.io.FileDescriptor;
424 import java.io.FileInputStream;
425 import java.io.FileNotFoundException;
426 import java.io.FileOutputStream;
427 import java.io.IOException;
428 import java.io.InputStreamReader;
429 import java.io.PrintWriter;
430 import java.io.StringWriter;
431 import java.io.UnsupportedEncodingException;
432 import java.lang.ref.WeakReference;
433 import java.nio.charset.StandardCharsets;
434 import java.text.DateFormat;
435 import java.util.ArrayList;
436 import java.util.Arrays;
437 import java.util.Collections;
438 import java.util.Comparator;
439 import java.util.Date;
440 import java.util.HashMap;
441 import java.util.HashSet;
442 import java.util.Iterator;
443 import java.util.List;
444 import java.util.Locale;
445 import java.util.Map;
446 import java.util.Objects;
447 import java.util.Set;
448 import java.util.concurrent.CountDownLatch;
449 import java.util.concurrent.atomic.AtomicBoolean;
450 import java.util.concurrent.atomic.AtomicLong;
451
452 import dalvik.system.VMRuntime;
453 import libcore.io.IoUtils;
454 import libcore.util.EmptyArray;
455
456 public class ActivityManagerService extends IActivityManager.Stub
457         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
458
459     /**
460      * Priority we boost main thread and RT of top app to.
461      */
462     public static final int TOP_APP_PRIORITY_BOOST = -10;
463
464     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
465     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
466     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
467     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
468     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
469     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
470     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
471     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
472     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
473     private static final String TAG_LRU = TAG + POSTFIX_LRU;
474     private static final String TAG_MU = TAG + POSTFIX_MU;
475     private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
476     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
477     private static final String TAG_POWER = TAG + POSTFIX_POWER;
478     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
479     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
480     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
481     private static final String TAG_PSS = TAG + POSTFIX_PSS;
482     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
483     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
484     private static final String TAG_STACK = TAG + POSTFIX_STACK;
485     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
486     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
487     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
488     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
489     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
490
491     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
492     // here so that while the job scheduler can depend on AMS, the other way around
493     // need not be the case.
494     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
495
496     /** Control over CPU and battery monitoring */
497     // write battery stats every 30 minutes.
498     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
499     static final boolean MONITOR_CPU_USAGE = true;
500     // don't sample cpu less than every 5 seconds.
501     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
502     // wait possibly forever for next cpu sample.
503     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
504     static final boolean MONITOR_THREAD_CPU_USAGE = false;
505
506     // The flags that are set for all calls we make to the package manager.
507     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
508
509     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
510
511     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
512
513     // Amount of time after a call to stopAppSwitches() during which we will
514     // prevent further untrusted switches from happening.
515     static final long APP_SWITCH_DELAY_TIME = 5*1000;
516
517     // How long we wait for a launched process to attach to the activity manager
518     // before we decide it's never going to come up for real.
519     static final int PROC_START_TIMEOUT = 10*1000;
520     // How long we wait for an attached process to publish its content providers
521     // before we decide it must be hung.
522     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
523
524     // How long we wait for a launched process to attach to the activity manager
525     // before we decide it's never going to come up for real, when the process was
526     // started with a wrapper for instrumentation (such as Valgrind) because it
527     // could take much longer than usual.
528     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
529
530     // How long we allow a receiver to run before giving up on it.
531     static final int BROADCAST_FG_TIMEOUT = 10*1000;
532     static final int BROADCAST_BG_TIMEOUT = 60*1000;
533
534     // How long we wait until we timeout on key dispatching.
535     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
536
537     // How long we wait until we timeout on key dispatching during instrumentation.
538     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
539
540     // How long to wait in getAssistContextExtras for the activity and foreground services
541     // to respond with the result.
542     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
543
544     // How long top wait when going through the modern assist (which doesn't need to block
545     // on getting this result before starting to launch its UI).
546     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
547
548     // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
549     static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
550
551     // Maximum number of persisted Uri grants a package is allowed
552     static final int MAX_PERSISTED_URI_GRANTS = 128;
553
554     static final int MY_PID = myPid();
555
556     static final String[] EMPTY_STRING_ARRAY = new String[0];
557
558     // How many bytes to write into the dropbox log before truncating
559     static final int DROPBOX_MAX_SIZE = 192 * 1024;
560     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
561     // as one line, but close enough for now.
562     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
563
564     // Access modes for handleIncomingUser.
565     static final int ALLOW_NON_FULL = 0;
566     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
567     static final int ALLOW_FULL_ONLY = 2;
568
569     // Necessary ApplicationInfo flags to mark an app as persistent
570     private static final int PERSISTENT_MASK =
571             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
572
573     // Intent sent when remote bugreport collection has been completed
574     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
575             "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
576
577     // Used to indicate that an app transition should be animated.
578     static final boolean ANIMATE = true;
579
580     // Determines whether to take full screen screenshots
581     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
582
583     /**
584      * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
585      */
586     private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
587
588     /**
589      * State indicating that there is no need for any blocking for network.
590      */
591     @VisibleForTesting
592     static final int NETWORK_STATE_NO_CHANGE = 0;
593
594     /**
595      * State indicating that the main thread needs to be informed about the network wait.
596      */
597     @VisibleForTesting
598     static final int NETWORK_STATE_BLOCK = 1;
599
600     /**
601      * State indicating that any threads waiting for network state to get updated can be unblocked.
602      */
603     @VisibleForTesting
604     static final int NETWORK_STATE_UNBLOCK = 2;
605
606     // Max character limit for a notification title. If the notification title is larger than this
607     // the notification will not be legible to the user.
608     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
609
610     private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
611
612     /** All system services */
613     SystemServiceManager mSystemServiceManager;
614     AssistUtils mAssistUtils;
615
616     private Installer mInstaller;
617
618     /** Run all ActivityStacks through this */
619     final ActivityStackSupervisor mStackSupervisor;
620     private final KeyguardController mKeyguardController;
621
622     final ActivityStarter mActivityStarter;
623
624     final TaskChangeNotificationController mTaskChangeNotificationController;
625
626     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
627
628     final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
629
630     public final IntentFirewall mIntentFirewall;
631
632     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
633     // default action automatically.  Important for devices without direct input
634     // devices.
635     private boolean mShowDialogs = true;
636
637     private final VrController mVrController;
638
639     // VR Vr2d Display Id.
640     int mVr2dDisplayId = INVALID_DISPLAY;
641
642     // Whether we should use SCHED_FIFO for UI and RenderThreads.
643     private boolean mUseFifoUiScheduling = false;
644
645     BroadcastQueue mFgBroadcastQueue;
646     BroadcastQueue mBgBroadcastQueue;
647     // Convenient for easy iteration over the queues. Foreground is first
648     // so that dispatch of foreground broadcasts gets precedence.
649     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
650
651     BroadcastStats mLastBroadcastStats;
652     BroadcastStats mCurBroadcastStats;
653
654     BroadcastQueue broadcastQueueForIntent(Intent intent) {
655         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
656         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
657                 "Broadcast intent " + intent + " on "
658                 + (isFg ? "foreground" : "background") + " queue");
659         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
660     }
661
662     /**
663      * The last resumed activity. This is identical to the current resumed activity most
664      * of the time but could be different when we're pausing one activity before we resume
665      * another activity.
666      */
667     private ActivityRecord mLastResumedActivity;
668
669     /**
670      * If non-null, we are tracking the time the user spends in the currently focused app.
671      */
672     private AppTimeTracker mCurAppTimeTracker;
673
674     /**
675      * List of intents that were used to start the most recent tasks.
676      */
677     final RecentTasks mRecentTasks;
678
679     /**
680      * For addAppTask: cached of the last activity component that was added.
681      */
682     ComponentName mLastAddedTaskComponent;
683
684     /**
685      * For addAppTask: cached of the last activity uid that was added.
686      */
687     int mLastAddedTaskUid;
688
689     /**
690      * For addAppTask: cached of the last ActivityInfo that was added.
691      */
692     ActivityInfo mLastAddedTaskActivity;
693
694     /**
695      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
696      */
697     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
698
699     /**
700      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
701      */
702     String mDeviceOwnerName;
703
704     final UserController mUserController;
705
706     final AppErrors mAppErrors;
707
708     /**
709      * Dump of the activity state at the time of the last ANR. Cleared after
710      * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
711      */
712     String mLastANRState;
713
714     /**
715      * Indicates the maximum time spent waiting for the network rules to get updated.
716      */
717     @VisibleForTesting
718     long mWaitForNetworkTimeoutMs;
719
720     public boolean canShowErrorDialogs() {
721         return mShowDialogs && !mSleeping && !mShuttingDown
722                 && !mKeyguardController.isKeyguardShowing()
723                 && !(UserManager.isDeviceInDemoMode(mContext)
724                         && mUserController.getCurrentUser().isDemo());
725     }
726
727     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
728             THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
729
730     static void boostPriorityForLockedSection() {
731         sThreadPriorityBooster.boost();
732     }
733
734     static void resetPriorityAfterLockedSection() {
735         sThreadPriorityBooster.reset();
736     }
737
738     public class PendingAssistExtras extends Binder implements Runnable {
739         public final ActivityRecord activity;
740         public boolean isHome;
741         public final Bundle extras;
742         public final Intent intent;
743         public final String hint;
744         public final IResultReceiver receiver;
745         public final int userHandle;
746         public boolean haveResult = false;
747         public Bundle result = null;
748         public AssistStructure structure = null;
749         public AssistContent content = null;
750         public Bundle receiverExtras;
751
752         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
753                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
754             activity = _activity;
755             extras = _extras;
756             intent = _intent;
757             hint = _hint;
758             receiver = _receiver;
759             receiverExtras = _receiverExtras;
760             userHandle = _userHandle;
761         }
762
763         @Override
764         public void run() {
765             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
766             synchronized (this) {
767                 haveResult = true;
768                 notifyAll();
769             }
770             pendingAssistExtrasTimedOut(this);
771         }
772     }
773
774     final ArrayList<PendingAssistExtras> mPendingAssistExtras
775             = new ArrayList<PendingAssistExtras>();
776
777     /**
778      * Process management.
779      */
780     final ProcessList mProcessList = new ProcessList();
781
782     /**
783      * All of the applications we currently have running organized by name.
784      * The keys are strings of the application package name (as
785      * returned by the package manager), and the keys are ApplicationRecord
786      * objects.
787      */
788     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
789
790     /**
791      * Tracking long-term execution of processes to look for abuse and other
792      * bad app behavior.
793      */
794     final ProcessStatsService mProcessStats;
795
796     /**
797      * The currently running isolated processes.
798      */
799     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
800
801     /**
802      * Counter for assigning isolated process uids, to avoid frequently reusing the
803      * same ones.
804      */
805     int mNextIsolatedProcessUid = 0;
806
807     /**
808      * The currently running heavy-weight process, if any.
809      */
810     ProcessRecord mHeavyWeightProcess = null;
811
812     /**
813      * Non-persistent appId whitelist for background restrictions
814      */
815     int[] mBackgroundAppIdWhitelist = new int[] {
816             BLUETOOTH_UID
817     };
818
819     /**
820      * Broadcast actions that will always be deliverable to unlaunched/background apps
821      */
822     ArraySet<String> mBackgroundLaunchBroadcasts;
823
824     /**
825      * All of the processes we currently have running organized by pid.
826      * The keys are the pid running the application.
827      *
828      * <p>NOTE: This object is protected by its own lock, NOT the global
829      * activity manager lock!
830      */
831     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
832
833     /**
834      * All of the processes that have been forced to be important.  The key
835      * is the pid of the caller who requested it (we hold a death
836      * link on it).
837      */
838     abstract class ImportanceToken implements IBinder.DeathRecipient {
839         final int pid;
840         final IBinder token;
841         final String reason;
842
843         ImportanceToken(int _pid, IBinder _token, String _reason) {
844             pid = _pid;
845             token = _token;
846             reason = _reason;
847         }
848
849         @Override
850         public String toString() {
851             return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
852                     + " " + reason + " " + pid + " " + token + " }";
853         }
854     }
855     final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
856
857     /**
858      * List of records for processes that someone had tried to start before the
859      * system was ready.  We don't start them at that point, but ensure they
860      * are started by the time booting is complete.
861      */
862     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
863
864     /**
865      * List of persistent applications that are in the process
866      * of being started.
867      */
868     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
869
870     /**
871      * Processes that are being forcibly torn down.
872      */
873     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
874
875     /**
876      * List of running applications, sorted by recent usage.
877      * The first entry in the list is the least recently used.
878      */
879     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
880
881     /**
882      * Where in mLruProcesses that the processes hosting activities start.
883      */
884     int mLruProcessActivityStart = 0;
885
886     /**
887      * Where in mLruProcesses that the processes hosting services start.
888      * This is after (lower index) than mLruProcessesActivityStart.
889      */
890     int mLruProcessServiceStart = 0;
891
892     /**
893      * List of processes that should gc as soon as things are idle.
894      */
895     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
896
897     /**
898      * Processes we want to collect PSS data from.
899      */
900     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
901
902     private boolean mBinderTransactionTrackingEnabled = false;
903
904     /**
905      * Last time we requested PSS data of all processes.
906      */
907     long mLastFullPssTime = SystemClock.uptimeMillis();
908
909     /**
910      * If set, the next time we collect PSS data we should do a full collection
911      * with data from native processes and the kernel.
912      */
913     boolean mFullPssPending = false;
914
915     /**
916      * This is the process holding what we currently consider to be
917      * the "home" activity.
918      */
919     ProcessRecord mHomeProcess;
920
921     /**
922      * This is the process holding the activity the user last visited that
923      * is in a different process from the one they are currently in.
924      */
925     ProcessRecord mPreviousProcess;
926
927     /**
928      * The time at which the previous process was last visible.
929      */
930     long mPreviousProcessVisibleTime;
931
932     /**
933      * Track all uids that have actively running processes.
934      */
935     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
936
937     /**
938      * This is for verifying the UID report flow.
939      */
940     static final boolean VALIDATE_UID_STATES = true;
941     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
942
943     /**
944      * Packages that the user has asked to have run in screen size
945      * compatibility mode instead of filling the screen.
946      */
947     final CompatModePackages mCompatModePackages;
948
949     /**
950      * Set of IntentSenderRecord objects that are currently active.
951      */
952     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
953             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
954
955     /**
956      * Fingerprints (hashCode()) of stack traces that we've
957      * already logged DropBox entries for.  Guarded by itself.  If
958      * something (rogue user app) forces this over
959      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
960      */
961     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
962     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
963
964     /**
965      * Strict Mode background batched logging state.
966      *
967      * The string buffer is guarded by itself, and its lock is also
968      * used to determine if another batched write is already
969      * in-flight.
970      */
971     private final StringBuilder mStrictModeBuffer = new StringBuilder();
972
973     /**
974      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
975      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
976      */
977     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
978
979     /**
980      * Resolver for broadcast intents to registered receivers.
981      * Holds BroadcastFilter (subclass of IntentFilter).
982      */
983     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
984             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
985         @Override
986         protected boolean allowFilterResult(
987                 BroadcastFilter filter, List<BroadcastFilter> dest) {
988             IBinder target = filter.receiverList.receiver.asBinder();
989             for (int i = dest.size() - 1; i >= 0; i--) {
990                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
991                     return false;
992                 }
993             }
994             return true;
995         }
996
997         @Override
998         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
999             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1000                     || userId == filter.owningUserId) {
1001                 return super.newResult(filter, match, userId);
1002             }
1003             return null;
1004         }
1005
1006         @Override
1007         protected BroadcastFilter[] newArray(int size) {
1008             return new BroadcastFilter[size];
1009         }
1010
1011         @Override
1012         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1013             return packageName.equals(filter.packageName);
1014         }
1015     };
1016
1017     /**
1018      * State of all active sticky broadcasts per user.  Keys are the action of the
1019      * sticky Intent, values are an ArrayList of all broadcasted intents with
1020      * that action (which should usually be one).  The SparseArray is keyed
1021      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1022      * for stickies that are sent to all users.
1023      */
1024     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1025             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1026
1027     final ActiveServices mServices;
1028
1029     final static class Association {
1030         final int mSourceUid;
1031         final String mSourceProcess;
1032         final int mTargetUid;
1033         final ComponentName mTargetComponent;
1034         final String mTargetProcess;
1035
1036         int mCount;
1037         long mTime;
1038
1039         int mNesting;
1040         long mStartTime;
1041
1042         // states of the source process when the bind occurred.
1043         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1044         long mLastStateUptime;
1045         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1046                 - ActivityManager.MIN_PROCESS_STATE+1];
1047
1048         Association(int sourceUid, String sourceProcess, int targetUid,
1049                 ComponentName targetComponent, String targetProcess) {
1050             mSourceUid = sourceUid;
1051             mSourceProcess = sourceProcess;
1052             mTargetUid = targetUid;
1053             mTargetComponent = targetComponent;
1054             mTargetProcess = targetProcess;
1055         }
1056     }
1057
1058     /**
1059      * When service association tracking is enabled, this is all of the associations we
1060      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1061      * -> association data.
1062      */
1063     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1064             mAssociations = new SparseArray<>();
1065     boolean mTrackingAssociations;
1066
1067     /**
1068      * Backup/restore process management
1069      */
1070     String mBackupAppName = null;
1071     BackupRecord mBackupTarget = null;
1072
1073     final ProviderMap mProviderMap;
1074
1075     /**
1076      * List of content providers who have clients waiting for them.  The
1077      * application is currently being launched and the provider will be
1078      * removed from this list once it is published.
1079      */
1080     final ArrayList<ContentProviderRecord> mLaunchingProviders
1081             = new ArrayList<ContentProviderRecord>();
1082
1083     /**
1084      * File storing persisted {@link #mGrantedUriPermissions}.
1085      */
1086     private final AtomicFile mGrantFile;
1087
1088     /** XML constants used in {@link #mGrantFile} */
1089     private static final String TAG_URI_GRANTS = "uri-grants";
1090     private static final String TAG_URI_GRANT = "uri-grant";
1091     private static final String ATTR_USER_HANDLE = "userHandle";
1092     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1093     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1094     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1095     private static final String ATTR_TARGET_PKG = "targetPkg";
1096     private static final String ATTR_URI = "uri";
1097     private static final String ATTR_MODE_FLAGS = "modeFlags";
1098     private static final String ATTR_CREATED_TIME = "createdTime";
1099     private static final String ATTR_PREFIX = "prefix";
1100
1101     /**
1102      * Global set of specific {@link Uri} permissions that have been granted.
1103      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1104      * to {@link UriPermission#uri} to {@link UriPermission}.
1105      */
1106     @GuardedBy("this")
1107     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1108             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1109
1110     public static class GrantUri {
1111         public final int sourceUserId;
1112         public final Uri uri;
1113         public boolean prefix;
1114
1115         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1116             this.sourceUserId = sourceUserId;
1117             this.uri = uri;
1118             this.prefix = prefix;
1119         }
1120
1121         @Override
1122         public int hashCode() {
1123             int hashCode = 1;
1124             hashCode = 31 * hashCode + sourceUserId;
1125             hashCode = 31 * hashCode + uri.hashCode();
1126             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1127             return hashCode;
1128         }
1129
1130         @Override
1131         public boolean equals(Object o) {
1132             if (o instanceof GrantUri) {
1133                 GrantUri other = (GrantUri) o;
1134                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1135                         && prefix == other.prefix;
1136             }
1137             return false;
1138         }
1139
1140         @Override
1141         public String toString() {
1142             String result = uri.toString() + " [user " + sourceUserId + "]";
1143             if (prefix) result += " [prefix]";
1144             return result;
1145         }
1146
1147         public String toSafeString() {
1148             String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1149             if (prefix) result += " [prefix]";
1150             return result;
1151         }
1152
1153         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1154             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1155                     ContentProvider.getUriWithoutUserId(uri), false);
1156         }
1157     }
1158
1159     CoreSettingsObserver mCoreSettingsObserver;
1160
1161     FontScaleSettingObserver mFontScaleSettingObserver;
1162
1163     private final class FontScaleSettingObserver extends ContentObserver {
1164         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1165
1166         public FontScaleSettingObserver() {
1167             super(mHandler);
1168             ContentResolver resolver = mContext.getContentResolver();
1169             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1170         }
1171
1172         @Override
1173         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1174             if (mFontScaleUri.equals(uri)) {
1175                 updateFontScaleIfNeeded(userId);
1176             }
1177         }
1178     }
1179
1180     /**
1181      * Thread-local storage used to carry caller permissions over through
1182      * indirect content-provider access.
1183      */
1184     private class Identity {
1185         public final IBinder token;
1186         public final int pid;
1187         public final int uid;
1188
1189         Identity(IBinder _token, int _pid, int _uid) {
1190             token = _token;
1191             pid = _pid;
1192             uid = _uid;
1193         }
1194     }
1195
1196     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1197
1198     /**
1199      * All information we have collected about the runtime performance of
1200      * any user id that can impact battery performance.
1201      */
1202     final BatteryStatsService mBatteryStatsService;
1203
1204     /**
1205      * Information about component usage
1206      */
1207     UsageStatsManagerInternal mUsageStatsService;
1208
1209     /**
1210      * Access to DeviceIdleController service.
1211      */
1212     DeviceIdleController.LocalService mLocalDeviceIdleController;
1213
1214     /**
1215      * Set of app ids that are whitelisted for device idle and thus background check.
1216      */
1217     int[] mDeviceIdleWhitelist = new int[0];
1218
1219     /**
1220      * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1221      */
1222     int[] mDeviceIdleTempWhitelist = new int[0];
1223
1224     static final class PendingTempWhitelist {
1225         final int targetUid;
1226         final long duration;
1227         final String tag;
1228
1229         PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1230             targetUid = _targetUid;
1231             duration = _duration;
1232             tag = _tag;
1233         }
1234     }
1235
1236     final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1237
1238     /**
1239      * Information about and control over application operations
1240      */
1241     final AppOpsService mAppOpsService;
1242
1243     /** Current sequencing integer of the configuration, for skipping old configurations. */
1244     private int mConfigurationSeq;
1245
1246     /**
1247      * Temp object used when global and/or display override configuration is updated. It is also
1248      * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1249      * anyone...
1250      */
1251     private Configuration mTempConfig = new Configuration();
1252
1253     private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1254             new UpdateConfigurationResult();
1255     private static final class UpdateConfigurationResult {
1256         // Configuration changes that were updated.
1257         int changes;
1258         // If the activity was relaunched to match the new configuration.
1259         boolean activityRelaunched;
1260
1261         void reset() {
1262             changes = 0;
1263             activityRelaunched = false;
1264         }
1265     }
1266
1267     boolean mSuppressResizeConfigChanges;
1268
1269     /**
1270      * Hardware-reported OpenGLES version.
1271      */
1272     final int GL_ES_VERSION;
1273
1274     /**
1275      * List of initialization arguments to pass to all processes when binding applications to them.
1276      * For example, references to the commonly used services.
1277      */
1278     HashMap<String, IBinder> mAppBindArgs;
1279     HashMap<String, IBinder> mIsolatedAppBindArgs;
1280
1281     /**
1282      * Temporary to avoid allocations.  Protected by main lock.
1283      */
1284     final StringBuilder mStringBuilder = new StringBuilder(256);
1285
1286     /**
1287      * Used to control how we initialize the service.
1288      */
1289     ComponentName mTopComponent;
1290     String mTopAction = Intent.ACTION_MAIN;
1291     String mTopData;
1292
1293     volatile boolean mProcessesReady = false;
1294     volatile boolean mSystemReady = false;
1295     volatile boolean mOnBattery = false;
1296     volatile int mFactoryTest;
1297
1298     @GuardedBy("this") boolean mBooting = false;
1299     @GuardedBy("this") boolean mCallFinishBooting = false;
1300     @GuardedBy("this") boolean mBootAnimationComplete = false;
1301     @GuardedBy("this") boolean mLaunchWarningShown = false;
1302     @GuardedBy("this") boolean mCheckedForSetup = false;
1303
1304     final Context mContext;
1305
1306     /**
1307      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1308      * change at runtime. Use mContext for non-UI purposes.
1309      */
1310     final Context mUiContext;
1311
1312     /**
1313      * The time at which we will allow normal application switches again,
1314      * after a call to {@link #stopAppSwitches()}.
1315      */
1316     long mAppSwitchesAllowedTime;
1317
1318     /**
1319      * This is set to true after the first switch after mAppSwitchesAllowedTime
1320      * is set; any switches after that will clear the time.
1321      */
1322     boolean mDidAppSwitch;
1323
1324     /**
1325      * Last time (in realtime) at which we checked for power usage.
1326      */
1327     long mLastPowerCheckRealtime;
1328
1329     /**
1330      * Last time (in uptime) at which we checked for power usage.
1331      */
1332     long mLastPowerCheckUptime;
1333
1334     /**
1335      * Set while we are wanting to sleep, to prevent any
1336      * activities from being started/resumed.
1337      *
1338      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1339      *
1340      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1341      * while in the sleep state until there is a pending transition out of sleep, in which case
1342      * mSleeping is set to false, and remains false while awake.
1343      *
1344      * Whether mSleeping can quickly toggled between true/false without the device actually
1345      * display changing states is undefined.
1346      */
1347     private boolean mSleeping = false;
1348
1349     /**
1350      * The process state used for processes that are running the top activities.
1351      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1352      */
1353     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1354
1355     /**
1356      * Set while we are running a voice interaction.  This overrides
1357      * sleeping while it is active.
1358      */
1359     private IVoiceInteractionSession mRunningVoice;
1360
1361     /**
1362      * For some direct access we need to power manager.
1363      */
1364     PowerManagerInternal mLocalPowerManager;
1365
1366     /**
1367      * We want to hold a wake lock while running a voice interaction session, since
1368      * this may happen with the screen off and we need to keep the CPU running to
1369      * be able to continue to interact with the user.
1370      */
1371     PowerManager.WakeLock mVoiceWakeLock;
1372
1373     /**
1374      * State of external calls telling us if the device is awake or asleep.
1375      */
1376     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1377
1378     /**
1379      * A list of tokens that cause the top activity to be put to sleep.
1380      * They are used by components that may hide and block interaction with underlying
1381      * activities.
1382      */
1383     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1384
1385     /**
1386      * Set if we are shutting down the system, similar to sleeping.
1387      */
1388     boolean mShuttingDown = false;
1389
1390     /**
1391      * Current sequence id for oom_adj computation traversal.
1392      */
1393     int mAdjSeq = 0;
1394
1395     /**
1396      * Current sequence id for process LRU updating.
1397      */
1398     int mLruSeq = 0;
1399
1400     /**
1401      * Keep track of the non-cached/empty process we last found, to help
1402      * determine how to distribute cached/empty processes next time.
1403      */
1404     int mNumNonCachedProcs = 0;
1405
1406     /**
1407      * Keep track of the number of cached hidden procs, to balance oom adj
1408      * distribution between those and empty procs.
1409      */
1410     int mNumCachedHiddenProcs = 0;
1411
1412     /**
1413      * Keep track of the number of service processes we last found, to
1414      * determine on the next iteration which should be B services.
1415      */
1416     int mNumServiceProcs = 0;
1417     int mNewNumAServiceProcs = 0;
1418     int mNewNumServiceProcs = 0;
1419
1420     /**
1421      * Allow the current computed overall memory level of the system to go down?
1422      * This is set to false when we are killing processes for reasons other than
1423      * memory management, so that the now smaller process list will not be taken as
1424      * an indication that memory is tighter.
1425      */
1426     boolean mAllowLowerMemLevel = false;
1427
1428     /**
1429      * The last computed memory level, for holding when we are in a state that
1430      * processes are going away for other reasons.
1431      */
1432     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1433
1434     /**
1435      * The last total number of process we have, to determine if changes actually look
1436      * like a shrinking number of process due to lower RAM.
1437      */
1438     int mLastNumProcesses;
1439
1440     /**
1441      * The uptime of the last time we performed idle maintenance.
1442      */
1443     long mLastIdleTime = SystemClock.uptimeMillis();
1444
1445     /**
1446      * Total time spent with RAM that has been added in the past since the last idle time.
1447      */
1448     long mLowRamTimeSinceLastIdle = 0;
1449
1450     /**
1451      * If RAM is currently low, when that horrible situation started.
1452      */
1453     long mLowRamStartTime = 0;
1454
1455     /**
1456      * For reporting to battery stats the current top application.
1457      */
1458     private String mCurResumedPackage = null;
1459     private int mCurResumedUid = -1;
1460
1461     /**
1462      * For reporting to battery stats the apps currently running foreground
1463      * service.  The ProcessMap is package/uid tuples; each of these contain
1464      * an array of the currently foreground processes.
1465      */
1466     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1467             = new ProcessMap<ArrayList<ProcessRecord>>();
1468
1469     /**
1470      * Set if the systemServer made a call to enterSafeMode.
1471      */
1472     boolean mSafeMode;
1473
1474     /**
1475      * If true, we are running under a test environment so will sample PSS from processes
1476      * much more rapidly to try to collect better data when the tests are rapidly
1477      * running through apps.
1478      */
1479     boolean mTestPssMode = false;
1480
1481     String mDebugApp = null;
1482     boolean mWaitForDebugger = false;
1483     boolean mDebugTransient = false;
1484     String mOrigDebugApp = null;
1485     boolean mOrigWaitForDebugger = false;
1486     boolean mAlwaysFinishActivities = false;
1487     boolean mForceResizableActivities;
1488     /**
1489      * Flag that indicates if multi-window is enabled.
1490      *
1491      * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1492      * in {@link com.android.internal.R.bool.config_supportsMultiWindow} config or
1493      * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1494      * At least one of the forms of multi-window must be enabled in order for this flag to be
1495      * initialized to 'true'.
1496      *
1497      * @see #mSupportsSplitScreenMultiWindow
1498      * @see #mSupportsFreeformWindowManagement
1499      * @see #mSupportsPictureInPicture
1500      * @see #mSupportsMultiDisplay
1501      */
1502     boolean mSupportsMultiWindow;
1503     boolean mSupportsSplitScreenMultiWindow;
1504     boolean mSupportsFreeformWindowManagement;
1505     boolean mSupportsPictureInPicture;
1506     boolean mSupportsMultiDisplay;
1507     boolean mSupportsLeanbackOnly;
1508     IActivityController mController = null;
1509     boolean mControllerIsAMonkey = false;
1510     String mProfileApp = null;
1511     ProcessRecord mProfileProc = null;
1512     String mProfileFile;
1513     ParcelFileDescriptor mProfileFd;
1514     int mSamplingInterval = 0;
1515     boolean mAutoStopProfiler = false;
1516     boolean mStreamingOutput = false;
1517     int mProfileType = 0;
1518     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1519     String mMemWatchDumpProcName;
1520     String mMemWatchDumpFile;
1521     int mMemWatchDumpPid;
1522     int mMemWatchDumpUid;
1523     String mTrackAllocationApp = null;
1524     String mNativeDebuggingApp = null;
1525
1526     final long[] mTmpLong = new long[2];
1527
1528     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1529
1530     /**
1531      * A global counter for generating sequence numbers.
1532      * This value will be used when incrementing sequence numbers in individual uidRecords.
1533      *
1534      * Having a global counter ensures that seq numbers are monotonically increasing for a
1535      * particular uid even when the uidRecord is re-created.
1536      */
1537     @GuardedBy("this")
1538     @VisibleForTesting
1539     long mProcStateSeqCounter = 0;
1540
1541     private final Injector mInjector;
1542
1543     static final class ProcessChangeItem {
1544         static final int CHANGE_ACTIVITIES = 1<<0;
1545         int changes;
1546         int uid;
1547         int pid;
1548         int processState;
1549         boolean foregroundActivities;
1550     }
1551
1552     static final class UidObserverRegistration {
1553         final int uid;
1554         final String pkg;
1555         final int which;
1556         final int cutpoint;
1557
1558         final SparseIntArray lastProcStates;
1559
1560         UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1561             uid = _uid;
1562             pkg = _pkg;
1563             which = _which;
1564             cutpoint = _cutpoint;
1565             if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1566                 lastProcStates = new SparseIntArray();
1567             } else {
1568                 lastProcStates = null;
1569             }
1570         }
1571     }
1572
1573     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1574     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1575
1576     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1577     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1578
1579     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1580     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1581
1582     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1583     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1584
1585     /**
1586      * Runtime CPU use collection thread.  This object's lock is used to
1587      * perform synchronization with the thread (notifying it to run).
1588      */
1589     final Thread mProcessCpuThread;
1590
1591     /**
1592      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1593      * Must acquire this object's lock when accessing it.
1594      * NOTE: this lock will be held while doing long operations (trawling
1595      * through all processes in /proc), so it should never be acquired by
1596      * any critical paths such as when holding the main activity manager lock.
1597      */
1598     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1599             MONITOR_THREAD_CPU_USAGE);
1600     final AtomicLong mLastCpuTime = new AtomicLong(0);
1601     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1602     final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1603
1604     long mLastWriteTime = 0;
1605
1606     /**
1607      * Used to retain an update lock when the foreground activity is in
1608      * immersive mode.
1609      */
1610     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1611
1612     /**
1613      * Set to true after the system has finished booting.
1614      */
1615     boolean mBooted = false;
1616
1617     WindowManagerService mWindowManager;
1618     final ActivityThread mSystemThread;
1619
1620     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1621         final ProcessRecord mApp;
1622         final int mPid;
1623         final IApplicationThread mAppThread;
1624
1625         AppDeathRecipient(ProcessRecord app, int pid,
1626                 IApplicationThread thread) {
1627             if (DEBUG_ALL) Slog.v(
1628                 TAG, "New death recipient " + this
1629                 + " for thread " + thread.asBinder());
1630             mApp = app;
1631             mPid = pid;
1632             mAppThread = thread;
1633         }
1634
1635         @Override
1636         public void binderDied() {
1637             if (DEBUG_ALL) Slog.v(
1638                 TAG, "Death received in " + this
1639                 + " for thread " + mAppThread.asBinder());
1640             synchronized(ActivityManagerService.this) {
1641                 appDiedLocked(mApp, mPid, mAppThread, true);
1642             }
1643         }
1644     }
1645
1646     static final int SHOW_ERROR_UI_MSG = 1;
1647     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1648     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1649     static final int UPDATE_CONFIGURATION_MSG = 4;
1650     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1651     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1652     static final int SERVICE_TIMEOUT_MSG = 12;
1653     static final int UPDATE_TIME_ZONE = 13;
1654     static final int SHOW_UID_ERROR_UI_MSG = 14;
1655     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1656     static final int PROC_START_TIMEOUT_MSG = 20;
1657     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1658     static final int KILL_APPLICATION_MSG = 22;
1659     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1660     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1661     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1662     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1663     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1664     static final int CLEAR_DNS_CACHE_MSG = 28;
1665     static final int UPDATE_HTTP_PROXY_MSG = 29;
1666     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1667     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1668     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1669     static final int REPORT_MEM_USAGE_MSG = 33;
1670     static final int REPORT_USER_SWITCH_MSG = 34;
1671     static final int CONTINUE_USER_SWITCH_MSG = 35;
1672     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1673     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1674     static final int PERSIST_URI_GRANTS_MSG = 38;
1675     static final int REQUEST_ALL_PSS_MSG = 39;
1676     static final int START_PROFILES_MSG = 40;
1677     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1678     static final int SYSTEM_USER_START_MSG = 42;
1679     static final int SYSTEM_USER_CURRENT_MSG = 43;
1680     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1681     static final int FINISH_BOOTING_MSG = 45;
1682     static final int START_USER_SWITCH_UI_MSG = 46;
1683     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1684     static final int DISMISS_DIALOG_UI_MSG = 48;
1685     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1686     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1687     static final int DELETE_DUMPHEAP_MSG = 51;
1688     static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1689     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1690     static final int REPORT_TIME_TRACKER_MSG = 54;
1691     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1692     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1693     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1694     static final int IDLE_UIDS_MSG = 58;
1695     static final int SYSTEM_USER_UNLOCK_MSG = 59;
1696     static final int LOG_STACK_STATE = 60;
1697     static final int VR_MODE_CHANGE_MSG = 61;
1698     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1699     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1700     static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1701     static final int NOTIFY_VR_SLEEPING_MSG = 65;
1702     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1703     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1704     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1705     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1706     static final int START_USER_SWITCH_FG_MSG = 712;
1707
1708     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1709     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1710     static final int FIRST_COMPAT_MODE_MSG = 300;
1711     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1712
1713     static ServiceThread sKillThread = null;
1714     static KillHandler sKillHandler = null;
1715
1716     CompatModeDialog mCompatModeDialog;
1717     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1718     long mLastMemUsageReportTime = 0;
1719
1720     /**
1721      * Flag whether the current user is a "monkey", i.e. whether
1722      * the UI is driven by a UI automation tool.
1723      */
1724     private boolean mUserIsMonkey;
1725
1726     /** Flag whether the device has a Recents UI */
1727     boolean mHasRecents;
1728
1729     /** The dimensions of the thumbnails in the Recents UI. */
1730     int mThumbnailWidth;
1731     int mThumbnailHeight;
1732     float mFullscreenThumbnailScale;
1733
1734     final ServiceThread mHandlerThread;
1735     final MainHandler mHandler;
1736     final Handler mUiHandler;
1737
1738     final ActivityManagerConstants mConstants;
1739
1740     PackageManagerInternal mPackageManagerInt;
1741
1742     // VoiceInteraction session ID that changes for each new request except when
1743     // being called for multiwindow assist in a single session.
1744     private int mViSessionId = 1000;
1745
1746     final boolean mPermissionReviewRequired;
1747
1748     /**
1749      * Current global configuration information. Contains general settings for the entire system,
1750      * also corresponds to the merged configuration of the default display.
1751      */
1752     Configuration getGlobalConfiguration() {
1753         return mStackSupervisor.getConfiguration();
1754     }
1755
1756     final class KillHandler extends Handler {
1757         static final int KILL_PROCESS_GROUP_MSG = 4000;
1758
1759         public KillHandler(Looper looper) {
1760             super(looper, null, true);
1761         }
1762
1763         @Override
1764         public void handleMessage(Message msg) {
1765             switch (msg.what) {
1766                 case KILL_PROCESS_GROUP_MSG:
1767                 {
1768                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1769                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1770                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1771                 }
1772                 break;
1773
1774                 default:
1775                     super.handleMessage(msg);
1776             }
1777         }
1778     }
1779
1780     final class UiHandler extends Handler {
1781         public UiHandler() {
1782             super(com.android.server.UiThread.get().getLooper(), null, true);
1783         }
1784
1785         @Override
1786         public void handleMessage(Message msg) {
1787             switch (msg.what) {
1788             case SHOW_ERROR_UI_MSG: {
1789                 mAppErrors.handleShowAppErrorUi(msg);
1790                 ensureBootCompleted();
1791             } break;
1792             case SHOW_NOT_RESPONDING_UI_MSG: {
1793                 mAppErrors.handleShowAnrUi(msg);
1794                 ensureBootCompleted();
1795             } break;
1796             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1797                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1798                 synchronized (ActivityManagerService.this) {
1799                     ProcessRecord proc = (ProcessRecord) data.get("app");
1800                     if (proc == null) {
1801                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1802                         break;
1803                     }
1804                     if (proc.crashDialog != null) {
1805                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1806                         return;
1807                     }
1808                     AppErrorResult res = (AppErrorResult) data.get("result");
1809                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1810                         Dialog d = new StrictModeViolationDialog(mUiContext,
1811                                 ActivityManagerService.this, res, proc);
1812                         d.show();
1813                         proc.crashDialog = d;
1814                     } else {
1815                         // The device is asleep, so just pretend that the user
1816                         // saw a crash dialog and hit "force quit".
1817                         res.set(0);
1818                     }
1819                 }
1820                 ensureBootCompleted();
1821             } break;
1822             case SHOW_FACTORY_ERROR_UI_MSG: {
1823                 Dialog d = new FactoryErrorDialog(
1824                         mUiContext, msg.getData().getCharSequence("msg"));
1825                 d.show();
1826                 ensureBootCompleted();
1827             } break;
1828             case WAIT_FOR_DEBUGGER_UI_MSG: {
1829                 synchronized (ActivityManagerService.this) {
1830                     ProcessRecord app = (ProcessRecord)msg.obj;
1831                     if (msg.arg1 != 0) {
1832                         if (!app.waitedForDebugger) {
1833                             Dialog d = new AppWaitingForDebuggerDialog(
1834                                     ActivityManagerService.this,
1835                                     mUiContext, app);
1836                             app.waitDialog = d;
1837                             app.waitedForDebugger = true;
1838                             d.show();
1839                         }
1840                     } else {
1841                         if (app.waitDialog != null) {
1842                             app.waitDialog.dismiss();
1843                             app.waitDialog = null;
1844                         }
1845                     }
1846                 }
1847             } break;
1848             case SHOW_UID_ERROR_UI_MSG: {
1849                 if (mShowDialogs) {
1850                     AlertDialog d = new BaseErrorDialog(mUiContext);
1851                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1852                     d.setCancelable(false);
1853                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1854                     d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1855                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1856                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1857                     d.show();
1858                 }
1859             } break;
1860             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1861                 if (mShowDialogs) {
1862                     AlertDialog d = new BaseErrorDialog(mUiContext);
1863                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1864                     d.setCancelable(false);
1865                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1866                     d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1867                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1868                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1869                     d.show();
1870                 }
1871             } break;
1872             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1873                 synchronized (ActivityManagerService.this) {
1874                     ActivityRecord ar = (ActivityRecord) msg.obj;
1875                     if (mCompatModeDialog != null) {
1876                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1877                                 ar.info.applicationInfo.packageName)) {
1878                             return;
1879                         }
1880                         mCompatModeDialog.dismiss();
1881                         mCompatModeDialog = null;
1882                     }
1883                     if (ar != null && false) {
1884                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1885                                 ar.packageName)) {
1886                             int mode = mCompatModePackages.computeCompatModeLocked(
1887                                     ar.info.applicationInfo);
1888                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1889                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1890                                 mCompatModeDialog = new CompatModeDialog(
1891                                         ActivityManagerService.this, mUiContext,
1892                                         ar.info.applicationInfo);
1893                                 mCompatModeDialog.show();
1894                             }
1895                         }
1896                     }
1897                 }
1898                 break;
1899             }
1900             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1901                 synchronized (ActivityManagerService.this) {
1902                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1903                     if (mUnsupportedDisplaySizeDialog != null) {
1904                         mUnsupportedDisplaySizeDialog.dismiss();
1905                         mUnsupportedDisplaySizeDialog = null;
1906                     }
1907                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1908                             ar.packageName)) {
1909                         // TODO(multi-display): Show dialog on appropriate display.
1910                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1911                                 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1912                         mUnsupportedDisplaySizeDialog.show();
1913                     }
1914                 }
1915                 break;
1916             }
1917             case START_USER_SWITCH_UI_MSG: {
1918                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1919                 break;
1920             }
1921             case DISMISS_DIALOG_UI_MSG: {
1922                 final Dialog d = (Dialog) msg.obj;
1923                 d.dismiss();
1924                 break;
1925             }
1926             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1927                 dispatchProcessesChanged();
1928                 break;
1929             }
1930             case DISPATCH_PROCESS_DIED_UI_MSG: {
1931                 final int pid = msg.arg1;
1932                 final int uid = msg.arg2;
1933                 dispatchProcessDied(pid, uid);
1934                 break;
1935             }
1936             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1937                 dispatchUidsChanged();
1938             } break;
1939             case PUSH_TEMP_WHITELIST_UI_MSG: {
1940                 pushTempWhitelist();
1941             } break;
1942             }
1943         }
1944     }
1945
1946     final class MainHandler extends Handler {
1947         public MainHandler(Looper looper) {
1948             super(looper, null, true);
1949         }
1950
1951         @Override
1952         public void handleMessage(Message msg) {
1953             switch (msg.what) {
1954             case UPDATE_CONFIGURATION_MSG: {
1955                 final ContentResolver resolver = mContext.getContentResolver();
1956                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1957                         msg.arg1);
1958             } break;
1959             case GC_BACKGROUND_PROCESSES_MSG: {
1960                 synchronized (ActivityManagerService.this) {
1961                     performAppGcsIfAppropriateLocked();
1962                 }
1963             } break;
1964             case SERVICE_TIMEOUT_MSG: {
1965                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1966             } break;
1967             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1968                 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1969             } break;
1970             case SERVICE_FOREGROUND_CRASH_MSG: {
1971                 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1972             } break;
1973             case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1974                 RemoteCallbackList<IResultReceiver> callbacks
1975                         = (RemoteCallbackList<IResultReceiver>)msg.obj;
1976                 int N = callbacks.beginBroadcast();
1977                 for (int i = 0; i < N; i++) {
1978                     try {
1979                         callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1980                     } catch (RemoteException e) {
1981                     }
1982                 }
1983                 callbacks.finishBroadcast();
1984             } break;
1985             case UPDATE_TIME_ZONE: {
1986                 synchronized (ActivityManagerService.this) {
1987                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1988                         ProcessRecord r = mLruProcesses.get(i);
1989                         if (r.thread != null) {
1990                             try {
1991                                 r.thread.updateTimeZone();
1992                             } catch (RemoteException ex) {
1993                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1994                             }
1995                         }
1996                     }
1997                 }
1998             } break;
1999             case CLEAR_DNS_CACHE_MSG: {
2000                 synchronized (ActivityManagerService.this) {
2001                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2002                         ProcessRecord r = mLruProcesses.get(i);
2003                         if (r.thread != null) {
2004                             try {
2005                                 r.thread.clearDnsCache();
2006                             } catch (RemoteException ex) {
2007                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2008                             }
2009                         }
2010                     }
2011                 }
2012             } break;
2013             case UPDATE_HTTP_PROXY_MSG: {
2014                 ProxyInfo proxy = (ProxyInfo)msg.obj;
2015                 String host = "";
2016                 String port = "";
2017                 String exclList = "";
2018                 Uri pacFileUrl = Uri.EMPTY;
2019                 if (proxy != null) {
2020                     host = proxy.getHost();
2021                     port = Integer.toString(proxy.getPort());
2022                     exclList = proxy.getExclusionListAsString();
2023                     pacFileUrl = proxy.getPacFileUrl();
2024                 }
2025                 synchronized (ActivityManagerService.this) {
2026                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2027                         ProcessRecord r = mLruProcesses.get(i);
2028                         if (r.thread != null) {
2029                             try {
2030                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2031                             } catch (RemoteException ex) {
2032                                 Slog.w(TAG, "Failed to update http proxy for: " +
2033                                         r.info.processName);
2034                             }
2035                         }
2036                     }
2037                 }
2038             } break;
2039             case PROC_START_TIMEOUT_MSG: {
2040                 ProcessRecord app = (ProcessRecord)msg.obj;
2041                 synchronized (ActivityManagerService.this) {
2042                     processStartTimedOutLocked(app);
2043                 }
2044             } break;
2045             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2046                 ProcessRecord app = (ProcessRecord)msg.obj;
2047                 synchronized (ActivityManagerService.this) {
2048                     processContentProviderPublishTimedOutLocked(app);
2049                 }
2050             } break;
2051             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2052                 synchronized (ActivityManagerService.this) {
2053                     mActivityStarter.doPendingActivityLaunchesLocked(true);
2054                 }
2055             } break;
2056             case KILL_APPLICATION_MSG: {
2057                 synchronized (ActivityManagerService.this) {
2058                     final int appId = msg.arg1;
2059                     final int userId = msg.arg2;
2060                     Bundle bundle = (Bundle)msg.obj;
2061                     String pkg = bundle.getString("pkg");
2062                     String reason = bundle.getString("reason");
2063                     forceStopPackageLocked(pkg, appId, false, false, true, false,
2064                             false, userId, reason);
2065                 }
2066             } break;
2067             case FINALIZE_PENDING_INTENT_MSG: {
2068                 ((PendingIntentRecord)msg.obj).completeFinalize();
2069             } break;
2070             case POST_HEAVY_NOTIFICATION_MSG: {
2071                 INotificationManager inm = NotificationManager.getService();
2072                 if (inm == null) {
2073                     return;
2074                 }
2075
2076                 ActivityRecord root = (ActivityRecord)msg.obj;
2077                 ProcessRecord process = root.app;
2078                 if (process == null) {
2079                     return;
2080                 }
2081
2082                 try {
2083                     Context context = mContext.createPackageContext(process.info.packageName, 0);
2084                     String text = mContext.getString(R.string.heavy_weight_notification,
2085                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
2086                     Notification notification =
2087                             new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2088                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2089                             .setWhen(0)
2090                             .setOngoing(true)
2091                             .setTicker(text)
2092                             .setColor(mContext.getColor(
2093                                     com.android.internal.R.color.system_notification_accent_color))
2094                             .setContentTitle(text)
2095                             .setContentText(
2096                                     mContext.getText(R.string.heavy_weight_notification_detail))
2097                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2098                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2099                                     new UserHandle(root.userId)))
2100                             .build();
2101                     try {
2102                         inm.enqueueNotificationWithTag("android", "android", null,
2103                                 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2104                                 notification, root.userId);
2105                     } catch (RuntimeException e) {
2106                         Slog.w(ActivityManagerService.TAG,
2107                                 "Error showing notification for heavy-weight app", e);
2108                     } catch (RemoteException e) {
2109                     }
2110                 } catch (NameNotFoundException e) {
2111                     Slog.w(TAG, "Unable to create context for heavy notification", e);
2112                 }
2113             } break;
2114             case CANCEL_HEAVY_NOTIFICATION_MSG: {
2115                 INotificationManager inm = NotificationManager.getService();
2116                 if (inm == null) {
2117                     return;
2118                 }
2119                 try {
2120                     inm.cancelNotificationWithTag("android", null,
2121                             SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2122                 } catch (RuntimeException e) {
2123                     Slog.w(ActivityManagerService.TAG,
2124                             "Error canceling notification for service", e);
2125                 } catch (RemoteException e) {
2126                 }
2127             } break;
2128             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2129                 synchronized (ActivityManagerService.this) {
2130                     checkExcessivePowerUsageLocked(true);
2131                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2132                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2133                     sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
2134                 }
2135             } break;
2136             case REPORT_MEM_USAGE_MSG: {
2137                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2138                 Thread thread = new Thread() {
2139                     @Override public void run() {
2140                         reportMemUsage(memInfos);
2141                     }
2142                 };
2143                 thread.start();
2144                 break;
2145             }
2146             case START_USER_SWITCH_FG_MSG: {
2147                 mUserController.startUserInForeground(msg.arg1);
2148                 break;
2149             }
2150             case REPORT_USER_SWITCH_MSG: {
2151                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2152                 break;
2153             }
2154             case CONTINUE_USER_SWITCH_MSG: {
2155                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2156                 break;
2157             }
2158             case USER_SWITCH_TIMEOUT_MSG: {
2159                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2160                 break;
2161             }
2162             case IMMERSIVE_MODE_LOCK_MSG: {
2163                 final boolean nextState = (msg.arg1 != 0);
2164                 if (mUpdateLock.isHeld() != nextState) {
2165                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2166                             "Applying new update lock state '" + nextState
2167                             + "' for " + (ActivityRecord)msg.obj);
2168                     if (nextState) {
2169                         mUpdateLock.acquire();
2170                     } else {
2171                         mUpdateLock.release();
2172                     }
2173                 }
2174                 break;
2175             }
2176             case PERSIST_URI_GRANTS_MSG: {
2177                 writeGrantedUriPermissions();
2178                 break;
2179             }
2180             case REQUEST_ALL_PSS_MSG: {
2181                 synchronized (ActivityManagerService.this) {
2182                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2183                 }
2184                 break;
2185             }
2186             case START_PROFILES_MSG: {
2187                 synchronized (ActivityManagerService.this) {
2188                     mUserController.startProfilesLocked();
2189                 }
2190                 break;
2191             }
2192             case UPDATE_TIME_PREFERENCE_MSG: {
2193                 // The user's time format preference might have changed.
2194                 // For convenience we re-use the Intent extra values.
2195                 synchronized (ActivityManagerService.this) {
2196                     for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2197                         ProcessRecord r = mLruProcesses.get(i);
2198                         if (r.thread != null) {
2199                             try {
2200                                 r.thread.updateTimePrefs(msg.arg1);
2201                             } catch (RemoteException ex) {
2202                                 Slog.w(TAG, "Failed to update preferences for: "
2203                                         + r.info.processName);
2204                             }
2205                         }
2206                     }
2207                 }
2208                 break;
2209             }
2210             case SYSTEM_USER_START_MSG: {
2211                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2212                         Integer.toString(msg.arg1), msg.arg1);
2213                 mSystemServiceManager.startUser(msg.arg1);
2214                 break;
2215             }
2216             case SYSTEM_USER_UNLOCK_MSG: {
2217                 final int userId = msg.arg1;
2218                 mSystemServiceManager.unlockUser(userId);
2219                 synchronized (ActivityManagerService.this) {
2220                     mRecentTasks.loadUserRecentsLocked(userId);
2221                 }
2222                 if (userId == UserHandle.USER_SYSTEM) {
2223                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2224                 }
2225                 installEncryptionUnawareProviders(userId);
2226                 mUserController.finishUserUnlocked((UserState) msg.obj);
2227                 break;
2228             }
2229             case SYSTEM_USER_CURRENT_MSG: {
2230                 mBatteryStatsService.noteEvent(
2231                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2232                         Integer.toString(msg.arg2), msg.arg2);
2233                 mBatteryStatsService.noteEvent(
2234                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2235                         Integer.toString(msg.arg1), msg.arg1);
2236                 mSystemServiceManager.switchUser(msg.arg1);
2237                 break;
2238             }
2239             case ENTER_ANIMATION_COMPLETE_MSG: {
2240                 synchronized (ActivityManagerService.this) {
2241                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2242                     if (r != null && r.app != null && r.app.thread != null) {
2243                         try {
2244                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2245                         } catch (RemoteException e) {
2246                         }
2247                     }
2248                 }
2249                 break;
2250             }
2251             case FINISH_BOOTING_MSG: {
2252                 if (msg.arg1 != 0) {
2253                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2254                     finishBooting();
2255                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2256                 }
2257                 if (msg.arg2 != 0) {
2258                     enableScreenAfterBoot();
2259                 }
2260                 break;
2261             }
2262             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2263                 try {
2264                     Locale l = (Locale) msg.obj;
2265                     IBinder service = ServiceManager.getService("mount");
2266                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2267                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2268                     storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2269                 } catch (RemoteException e) {
2270                     Log.e(TAG, "Error storing locale for decryption UI", e);
2271                 }
2272                 break;
2273             }
2274             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2275                 final int uid = msg.arg1;
2276                 final byte[] firstPacket = (byte[]) msg.obj;
2277
2278                 synchronized (mPidsSelfLocked) {
2279                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2280                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2281                         if (p.uid == uid) {
2282                             try {
2283                                 p.thread.notifyCleartextNetwork(firstPacket);
2284                             } catch (RemoteException ignored) {
2285                             }
2286                         }
2287                     }
2288                 }
2289                 break;
2290             }
2291             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2292                 final String procName;
2293                 final int uid;
2294                 final long memLimit;
2295                 final String reportPackage;
2296                 synchronized (ActivityManagerService.this) {
2297                     procName = mMemWatchDumpProcName;
2298                     uid = mMemWatchDumpUid;
2299                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2300                     if (val == null) {
2301                         val = mMemWatchProcesses.get(procName, 0);
2302                     }
2303                     if (val != null) {
2304                         memLimit = val.first;
2305                         reportPackage = val.second;
2306                     } else {
2307                         memLimit = 0;
2308                         reportPackage = null;
2309                     }
2310                 }
2311                 if (procName == null) {
2312                     return;
2313                 }
2314
2315                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2316                         "Showing dump heap notification from " + procName + "/" + uid);
2317
2318                 INotificationManager inm = NotificationManager.getService();
2319                 if (inm == null) {
2320                     return;
2321                 }
2322
2323                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2324
2325
2326                 Intent deleteIntent = new Intent();
2327                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2328                 Intent intent = new Intent();
2329                 intent.setClassName("android", DumpHeapActivity.class.getName());
2330                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2331                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2332                 if (reportPackage != null) {
2333                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2334                 }
2335                 int userId = UserHandle.getUserId(uid);
2336                 Notification notification =
2337                         new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2338                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2339                         .setWhen(0)
2340                         .setOngoing(true)
2341                         .setAutoCancel(true)
2342                         .setTicker(text)
2343                         .setColor(mContext.getColor(
2344                                 com.android.internal.R.color.system_notification_accent_color))
2345                         .setContentTitle(text)
2346                         .setContentText(
2347                                 mContext.getText(R.string.dump_heap_notification_detail))
2348                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2349                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2350                                 new UserHandle(userId)))
2351                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2352                                 deleteIntent, 0, UserHandle.SYSTEM))
2353                         .build();
2354
2355                 try {
2356                     inm.enqueueNotificationWithTag("android", "android", null,
2357                             SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2358                             notification, userId);
2359                 } catch (RuntimeException e) {
2360                     Slog.w(ActivityManagerService.TAG,
2361                             "Error showing notification for dump heap", e);
2362                 } catch (RemoteException e) {
2363                 }
2364             } break;
2365             case DELETE_DUMPHEAP_MSG: {
2366                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2367                         null, DumpHeapActivity.JAVA_URI,
2368                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2369                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2370                         UserHandle.myUserId());
2371                 synchronized (ActivityManagerService.this) {
2372                     mMemWatchDumpFile = null;
2373                     mMemWatchDumpProcName = null;
2374                     mMemWatchDumpPid = -1;
2375                     mMemWatchDumpUid = -1;
2376                 }
2377             } break;
2378             case FOREGROUND_PROFILE_CHANGED_MSG: {
2379                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2380             } break;
2381             case REPORT_TIME_TRACKER_MSG: {
2382                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2383                 tracker.deliverResult(mContext);
2384             } break;
2385             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2386                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2387             } break;
2388             case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2389                 mUserController.dispatchLockedBootComplete(msg.arg1);
2390             } break;
2391             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2392                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2393                 try {
2394                     connection.shutdown();
2395                 } catch (RemoteException e) {
2396                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2397                 }
2398                 // Only a UiAutomation can set this flag and now that
2399                 // it is finished we make sure it is reset to its default.
2400                 mUserIsMonkey = false;
2401             } break;
2402             case IDLE_UIDS_MSG: {
2403                 idleUids();
2404             } break;
2405             case VR_MODE_CHANGE_MSG: {
2406                 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2407                     return;
2408                 }
2409                 synchronized (ActivityManagerService.this) {
2410                     final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2411                     mWindowManager.disableNonVrUi(disableNonVrUi);
2412                     if (disableNonVrUi) {
2413                         // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2414                         // then remove the pinned stack.
2415                         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2416                                 PINNED_STACK_ID);
2417                         if (pinnedStack != null) {
2418                             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2419                         }
2420                     }
2421                 }
2422             } break;
2423             case NOTIFY_VR_SLEEPING_MSG: {
2424                 notifyVrManagerOfSleepState(msg.arg1 != 0);
2425             } break;
2426             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2427                 synchronized (ActivityManagerService.this) {
2428                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2429                         ProcessRecord r = mLruProcesses.get(i);
2430                         if (r.thread != null) {
2431                             try {
2432                                 r.thread.handleTrustStorageUpdate();
2433                             } catch (RemoteException ex) {
2434                                 Slog.w(TAG, "Failed to handle trust storage update for: " +
2435                                         r.info.processName);
2436                             }
2437                         }
2438                     }
2439                 }
2440             } break;
2441             }
2442         }
2443     };
2444
2445     static final int COLLECT_PSS_BG_MSG = 1;
2446
2447     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2448         @Override
2449         public void handleMessage(Message msg) {
2450             switch (msg.what) {
2451             case COLLECT_PSS_BG_MSG: {
2452                 long start = SystemClock.uptimeMillis();
2453                 MemInfoReader memInfo = null;
2454                 synchronized (ActivityManagerService.this) {
2455                     if (mFullPssPending) {
2456                         mFullPssPending = false;
2457                         memInfo = new MemInfoReader();
2458                     }
2459                 }
2460                 if (memInfo != null) {
2461                     updateCpuStatsNow();
2462                     long nativeTotalPss = 0;
2463                     final List<ProcessCpuTracker.Stats> stats;
2464                     synchronized (mProcessCpuTracker) {
2465                         stats = mProcessCpuTracker.getStats( (st)-> {
2466                             return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2467                         });
2468                     }
2469                     final int N = stats.size();
2470                     for (int j = 0; j < N; j++) {
2471                         synchronized (mPidsSelfLocked) {
2472                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2473                                 // This is one of our own processes; skip it.
2474                                 continue;
2475                             }
2476                         }
2477                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2478                     }
2479                     memInfo.readMemInfo();
2480                     synchronized (ActivityManagerService.this) {
2481                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2482                                 + (SystemClock.uptimeMillis()-start) + "ms");
2483                         final long cachedKb = memInfo.getCachedSizeKb();
2484                         final long freeKb = memInfo.getFreeSizeKb();
2485                         final long zramKb = memInfo.getZramTotalSizeKb();
2486                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2487                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2488                                 kernelKb*1024, nativeTotalPss*1024);
2489                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2490                                 nativeTotalPss);
2491                     }
2492                 }
2493
2494                 int num = 0;
2495                 long[] tmp = new long[2];
2496                 do {
2497                     ProcessRecord proc;
2498                     int procState;
2499                     int pid;
2500                     long lastPssTime;
2501                     synchronized (ActivityManagerService.this) {
2502                         if (mPendingPssProcesses.size() <= 0) {
2503                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2504                                     "Collected PSS of " + num + " processes in "
2505                                     + (SystemClock.uptimeMillis() - start) + "ms");
2506                             mPendingPssProcesses.clear();
2507                             return;
2508                         }
2509                         proc = mPendingPssProcesses.remove(0);
2510                         procState = proc.pssProcState;
2511                         lastPssTime = proc.lastPssTime;
2512                         if (proc.thread != null && procState == proc.setProcState
2513                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2514                                         < SystemClock.uptimeMillis()) {
2515                             pid = proc.pid;
2516                         } else {
2517                             proc = null;
2518                             pid = 0;
2519                         }
2520                     }
2521                     if (proc != null) {
2522                         long pss = Debug.getPss(pid, tmp, null);
2523                         synchronized (ActivityManagerService.this) {
2524                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2525                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2526                                 num++;
2527                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2528                                         SystemClock.uptimeMillis());
2529                             }
2530                         }
2531                     }
2532                 } while (true);
2533             }
2534             }
2535         }
2536     };
2537
2538     public void setSystemProcess() {
2539         try {
2540             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2541             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2542             ServiceManager.addService("meminfo", new MemBinder(this));
2543             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2544             ServiceManager.addService("dbinfo", new DbBinder(this));
2545             if (MONITOR_CPU_USAGE) {
2546                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2547             }
2548             ServiceManager.addService("permission", new PermissionController(this));
2549             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2550
2551             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2552                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2553             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2554
2555             synchronized (this) {
2556                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2557                 app.persistent = true;
2558                 app.pid = MY_PID;
2559                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2560                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2561                 synchronized (mPidsSelfLocked) {
2562                     mPidsSelfLocked.put(app.pid, app);
2563                 }
2564                 updateLruProcessLocked(app, false, null);
2565                 updateOomAdjLocked();
2566             }
2567         } catch (PackageManager.NameNotFoundException e) {
2568             throw new RuntimeException(
2569                     "Unable to find android system package", e);
2570         }
2571     }
2572
2573     public void setWindowManager(WindowManagerService wm) {
2574         mWindowManager = wm;
2575         mStackSupervisor.setWindowManager(wm);
2576         mActivityStarter.setWindowManager(wm);
2577     }
2578
2579     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2580         mUsageStatsService = usageStatsManager;
2581     }
2582
2583     public void startObservingNativeCrashes() {
2584         final NativeCrashListener ncl = new NativeCrashListener(this);
2585         ncl.start();
2586     }
2587
2588     public IAppOpsService getAppOpsService() {
2589         return mAppOpsService;
2590     }
2591
2592     static class MemBinder extends Binder {
2593         ActivityManagerService mActivityManagerService;
2594         MemBinder(ActivityManagerService activityManagerService) {
2595             mActivityManagerService = activityManagerService;
2596         }
2597
2598         @Override
2599         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2600             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2601                     "meminfo", pw)) return;
2602             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2603         }
2604     }
2605
2606     static class GraphicsBinder extends Binder {
2607         ActivityManagerService mActivityManagerService;
2608         GraphicsBinder(ActivityManagerService activityManagerService) {
2609             mActivityManagerService = activityManagerService;
2610         }
2611
2612         @Override
2613         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2614             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2615                     "gfxinfo", pw)) return;
2616             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2617         }
2618     }
2619
2620     static class DbBinder extends Binder {
2621         ActivityManagerService mActivityManagerService;
2622         DbBinder(ActivityManagerService activityManagerService) {
2623             mActivityManagerService = activityManagerService;
2624         }
2625
2626         @Override
2627         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2628             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2629                     "dbinfo", pw)) return;
2630             mActivityManagerService.dumpDbInfo(fd, pw, args);
2631         }
2632     }
2633
2634     static class CpuBinder extends Binder {
2635         ActivityManagerService mActivityManagerService;
2636         CpuBinder(ActivityManagerService activityManagerService) {
2637             mActivityManagerService = activityManagerService;
2638         }
2639
2640         @Override
2641         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2642             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2643                     "cpuinfo", pw)) return;
2644             synchronized (mActivityManagerService.mProcessCpuTracker) {
2645                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2646                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2647                         SystemClock.uptimeMillis()));
2648             }
2649         }
2650     }
2651
2652     public static final class Lifecycle extends SystemService {
2653         private final ActivityManagerService mService;
2654
2655         public Lifecycle(Context context) {
2656             super(context);
2657             mService = new ActivityManagerService(context);
2658         }
2659
2660         @Override
2661         public void onStart() {
2662             mService.start();
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(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(mContext);
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                                 } else {
3009                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3010                                     if (ps == null || !ps.isActive()) {
3011                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
3012                                                 bstats.mapUid(st.uid), st.name);
3013                                     }
3014                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3015                                 }
3016                             }
3017                             final int userTime = mProcessCpuTracker.getLastUserTime();
3018                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
3019                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3020                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
3021                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3022                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
3023                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3024                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3025                         }
3026                     }
3027                 }
3028
3029                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3030                     mLastWriteTime = now;
3031                     mBatteryStatsService.scheduleWriteToDisk();
3032                 }
3033             }
3034         }
3035     }
3036
3037     @Override
3038     public void batteryNeedsCpuUpdate() {
3039         updateCpuStatsNow();
3040     }
3041
3042     @Override
3043     public void batteryPowerChanged(boolean onBattery) {
3044         // When plugging in, update the CPU stats first before changing
3045         // the plug state.
3046         updateCpuStatsNow();
3047         synchronized (this) {
3048             synchronized(mPidsSelfLocked) {
3049                 mOnBattery = DEBUG_POWER ? true : onBattery;
3050             }
3051         }
3052     }
3053
3054     @Override
3055     public void batterySendBroadcast(Intent intent) {
3056         synchronized (this) {
3057             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3058                     AppOpsManager.OP_NONE, null, false, false,
3059                     -1, SYSTEM_UID, UserHandle.USER_ALL);
3060         }
3061     }
3062
3063     /**
3064      * Initialize the application bind args. These are passed to each
3065      * process when the bindApplication() IPC is sent to the process. They're
3066      * lazily setup to make sure the services are running when they're asked for.
3067      */
3068     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3069         // Isolated processes won't get this optimization, so that we don't
3070         // violate the rules about which services they have access to.
3071         if (isolated) {
3072             if (mIsolatedAppBindArgs == null) {
3073                 mIsolatedAppBindArgs = new HashMap<>();
3074                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3075             }
3076             return mIsolatedAppBindArgs;
3077         }
3078
3079         if (mAppBindArgs == null) {
3080             mAppBindArgs = new HashMap<>();
3081
3082             // Setup the application init args
3083             mAppBindArgs.put("package", ServiceManager.getService("package"));
3084             mAppBindArgs.put("window", ServiceManager.getService("window"));
3085             mAppBindArgs.put(Context.ALARM_SERVICE,
3086                     ServiceManager.getService(Context.ALARM_SERVICE));
3087         }
3088         return mAppBindArgs;
3089     }
3090
3091     /**
3092      * Update AMS states when an activity is resumed. This should only be called by
3093      * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3094      */
3095     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3096         final TaskRecord task = r.getTask();
3097         if (task.isApplicationTask()) {
3098             if (mCurAppTimeTracker != r.appTimeTracker) {
3099                 // We are switching app tracking.  Complete the current one.
3100                 if (mCurAppTimeTracker != null) {
3101                     mCurAppTimeTracker.stop();
3102                     mHandler.obtainMessage(
3103                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3104                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3105                     mCurAppTimeTracker = null;
3106                 }
3107                 if (r.appTimeTracker != null) {
3108                     mCurAppTimeTracker = r.appTimeTracker;
3109                     startTimeTrackingFocusedActivityLocked();
3110                 }
3111             } else {
3112                 startTimeTrackingFocusedActivityLocked();
3113             }
3114         } else {
3115             r.appTimeTracker = null;
3116         }
3117         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3118         // TODO: Probably not, because we don't want to resume voice on switching
3119         // back to this activity
3120         if (task.voiceInteractor != null) {
3121             startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3122         } else {
3123             finishRunningVoiceLocked();
3124
3125             if (mLastResumedActivity != null) {
3126                 final IVoiceInteractionSession session;
3127
3128                 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3129                 if (lastResumedActivityTask != null
3130                         && lastResumedActivityTask.voiceSession != null) {
3131                     session = lastResumedActivityTask.voiceSession;
3132                 } else {
3133                     session = mLastResumedActivity.voiceSession;
3134                 }
3135
3136                 if (session != null) {
3137                     // We had been in a voice interaction session, but now focused has
3138                     // move to something different.  Just finish the session, we can't
3139                     // return to it and retain the proper state and synchronization with
3140                     // the voice interaction service.
3141                     finishVoiceTask(session);
3142                 }
3143             }
3144         }
3145
3146         if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3147             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3148             mHandler.obtainMessage(
3149                     FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3150         }
3151         mLastResumedActivity = r;
3152
3153         mWindowManager.setFocusedApp(r.appToken, true);
3154
3155         applyUpdateLockStateLocked(r);
3156         applyUpdateVrModeLocked(r);
3157
3158         EventLogTags.writeAmSetResumedActivity(
3159                 r == null ? -1 : r.userId,
3160                 r == null ? "NULL" : r.shortComponentName,
3161                 reason);
3162     }
3163
3164     @Override
3165     public void setFocusedStack(int stackId) {
3166         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3167         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3168         final long callingId = Binder.clearCallingIdentity();
3169         try {
3170             synchronized (this) {
3171                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3172                 if (stack == null) {
3173                     return;
3174                 }
3175                 final ActivityRecord r = stack.topRunningActivityLocked();
3176                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3177                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3178                 }
3179             }
3180         } finally {
3181             Binder.restoreCallingIdentity(callingId);
3182         }
3183     }
3184
3185     @Override
3186     public void setFocusedTask(int taskId) {
3187         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3188         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3189         final long callingId = Binder.clearCallingIdentity();
3190         try {
3191             synchronized (this) {
3192                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3193                 if (task == null) {
3194                     return;
3195                 }
3196                 final ActivityRecord r = task.topRunningActivityLocked();
3197                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3198                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3199                 }
3200             }
3201         } finally {
3202             Binder.restoreCallingIdentity(callingId);
3203         }
3204     }
3205
3206     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3207     @Override
3208     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3209         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3210         mTaskChangeNotificationController.registerTaskStackListener(listener);
3211     }
3212
3213     /**
3214      * Unregister a task stack listener so that it stops receiving callbacks.
3215      */
3216     @Override
3217     public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3218          enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3219          mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3220      }
3221
3222     @Override
3223     public void notifyActivityDrawn(IBinder token) {
3224         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3225         synchronized (this) {
3226             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3227             if (r != null) {
3228                 r.getStack().notifyActivityDrawnLocked(r);
3229             }
3230         }
3231     }
3232
3233     final void applyUpdateLockStateLocked(ActivityRecord r) {
3234         // Modifications to the UpdateLock state are done on our handler, outside
3235         // the activity manager's locks.  The new state is determined based on the
3236         // state *now* of the relevant activity record.  The object is passed to
3237         // the handler solely for logging detail, not to be consulted/modified.
3238         final boolean nextState = r != null && r.immersive;
3239         mHandler.sendMessage(
3240                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3241     }
3242
3243     final void applyUpdateVrModeLocked(ActivityRecord r) {
3244         mHandler.sendMessage(
3245                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3246     }
3247
3248     private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3249         mHandler.sendMessage(
3250                 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3251     }
3252
3253     private void notifyVrManagerOfSleepState(boolean isSleeping) {
3254         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3255         if (vrService == null) {
3256             return;
3257         }
3258         vrService.onSleepStateChanged(isSleeping);
3259     }
3260
3261     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3262         Message msg = Message.obtain();
3263         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3264         msg.obj = r.getTask().askedCompatMode ? null : r;
3265         mUiHandler.sendMessage(msg);
3266     }
3267
3268     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3269         final Configuration globalConfig = getGlobalConfiguration();
3270         if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3271                 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3272             final Message msg = Message.obtain();
3273             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3274             msg.obj = r;
3275             mUiHandler.sendMessage(msg);
3276         }
3277     }
3278
3279     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3280             String what, Object obj, ProcessRecord srcApp) {
3281         app.lastActivityTime = now;
3282
3283         if (app.activities.size() > 0) {
3284             // Don't want to touch dependent processes that are hosting activities.
3285             return index;
3286         }
3287
3288         int lrui = mLruProcesses.lastIndexOf(app);
3289         if (lrui < 0) {
3290             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3291                     + what + " " + obj + " from " + srcApp);
3292             return index;
3293         }
3294
3295         if (lrui >= index) {
3296             // Don't want to cause this to move dependent processes *back* in the
3297             // list as if they were less frequently used.
3298             return index;
3299         }
3300
3301         if (lrui >= mLruProcessActivityStart) {
3302             // Don't want to touch dependent processes that are hosting activities.
3303             return index;
3304         }
3305
3306         mLruProcesses.remove(lrui);
3307         if (index > 0) {
3308             index--;
3309         }
3310         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3311                 + " in LRU list: " + app);
3312         mLruProcesses.add(index, app);
3313         return index;
3314     }
3315
3316     static void killProcessGroup(int uid, int pid) {
3317         if (sKillHandler != null) {
3318             sKillHandler.sendMessage(
3319                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3320         } else {
3321             Slog.w(TAG, "Asked to kill process group before system bringup!");
3322             Process.killProcessGroup(uid, pid);
3323         }
3324     }
3325
3326     final void removeLruProcessLocked(ProcessRecord app) {
3327         int lrui = mLruProcesses.lastIndexOf(app);
3328         if (lrui >= 0) {
3329             if (!app.killed) {
3330                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3331                 killProcessQuiet(app.pid);
3332                 killProcessGroup(app.uid, app.pid);
3333             }
3334             if (lrui <= mLruProcessActivityStart) {
3335                 mLruProcessActivityStart--;
3336             }
3337             if (lrui <= mLruProcessServiceStart) {
3338                 mLruProcessServiceStart--;
3339             }
3340             mLruProcesses.remove(lrui);
3341         }
3342     }
3343
3344     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3345             ProcessRecord client) {
3346         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3347                 || app.treatLikeActivity;
3348         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3349         if (!activityChange && hasActivity) {
3350             // The process has activities, so we are only allowing activity-based adjustments
3351             // to move it.  It should be kept in the front of the list with other
3352             // processes that have activities, and we don't want those to change their
3353             // order except due to activity operations.
3354             return;
3355         }
3356
3357         mLruSeq++;
3358         final long now = SystemClock.uptimeMillis();
3359         app.lastActivityTime = now;
3360
3361         // First a quick reject: if the app is already at the position we will
3362         // put it, then there is nothing to do.
3363         if (hasActivity) {
3364             final int N = mLruProcesses.size();
3365             if (N > 0 && mLruProcesses.get(N-1) == app) {
3366                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3367                 return;
3368             }
3369         } else {
3370             if (mLruProcessServiceStart > 0
3371                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3372                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3373                 return;
3374             }
3375         }
3376
3377         int lrui = mLruProcesses.lastIndexOf(app);
3378
3379         if (app.persistent && lrui >= 0) {
3380             // We don't care about the position of persistent processes, as long as
3381             // they are in the list.
3382             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3383             return;
3384         }
3385
3386         /* In progress: compute new position first, so we can avoid doing work
3387            if the process is not actually going to move.  Not yet working.
3388         int addIndex;
3389         int nextIndex;
3390         boolean inActivity = false, inService = false;
3391         if (hasActivity) {
3392             // Process has activities, put it at the very tipsy-top.
3393             addIndex = mLruProcesses.size();
3394             nextIndex = mLruProcessServiceStart;
3395             inActivity = true;
3396         } else if (hasService) {
3397             // Process has services, put it at the top of the service list.
3398             addIndex = mLruProcessActivityStart;
3399             nextIndex = mLruProcessServiceStart;
3400             inActivity = true;
3401             inService = true;
3402         } else  {
3403             // Process not otherwise of interest, it goes to the top of the non-service area.
3404             addIndex = mLruProcessServiceStart;
3405             if (client != null) {
3406                 int clientIndex = mLruProcesses.lastIndexOf(client);
3407                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3408                         + app);
3409                 if (clientIndex >= 0 && addIndex > clientIndex) {
3410                     addIndex = clientIndex;
3411                 }
3412             }
3413             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3414         }
3415
3416         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3417                 + mLruProcessActivityStart + "): " + app);
3418         */
3419
3420         if (lrui >= 0) {
3421             if (lrui < mLruProcessActivityStart) {
3422                 mLruProcessActivityStart--;
3423             }
3424             if (lrui < mLruProcessServiceStart) {
3425                 mLruProcessServiceStart--;
3426             }
3427             /*
3428             if (addIndex > lrui) {
3429                 addIndex--;
3430             }
3431             if (nextIndex > lrui) {
3432                 nextIndex--;
3433             }
3434             */
3435             mLruProcesses.remove(lrui);
3436         }
3437
3438         /*
3439         mLruProcesses.add(addIndex, app);
3440         if (inActivity) {
3441             mLruProcessActivityStart++;
3442         }
3443         if (inService) {
3444             mLruProcessActivityStart++;
3445         }
3446         */
3447
3448         int nextIndex;
3449         if (hasActivity) {
3450             final int N = mLruProcesses.size();
3451             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3452                 // Process doesn't have activities, but has clients with
3453                 // activities...  move it up, but one below the top (the top
3454                 // should always have a real activity).
3455                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3456                         "Adding to second-top of LRU activity list: " + app);
3457                 mLruProcesses.add(N - 1, app);
3458                 // To keep it from spamming the LRU list (by making a bunch of clients),
3459                 // we will push down any other entries owned by the app.
3460                 final int uid = app.info.uid;
3461                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3462                     ProcessRecord subProc = mLruProcesses.get(i);
3463                     if (subProc.info.uid == uid) {
3464                         // We want to push this one down the list.  If the process after
3465                         // it is for the same uid, however, don't do so, because we don't
3466                         // want them internally to be re-ordered.
3467                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3468                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3469                                     "Pushing uid " + uid + " swapping at " + i + ": "
3470                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3471                             ProcessRecord tmp = mLruProcesses.get(i);
3472                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3473                             mLruProcesses.set(i - 1, tmp);
3474                             i--;
3475                         }
3476                     } else {
3477                         // A gap, we can stop here.
3478                         break;
3479                     }
3480                 }
3481             } else {
3482                 // Process has activities, put it at the very tipsy-top.
3483                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3484                 mLruProcesses.add(app);
3485             }
3486             nextIndex = mLruProcessServiceStart;
3487         } else if (hasService) {
3488             // Process has services, put it at the top of the service list.
3489             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3490             mLruProcesses.add(mLruProcessActivityStart, app);
3491             nextIndex = mLruProcessServiceStart;
3492             mLruProcessActivityStart++;
3493         } else  {
3494             // Process not otherwise of interest, it goes to the top of the non-service area.
3495             int index = mLruProcessServiceStart;
3496             if (client != null) {
3497                 // If there is a client, don't allow the process to be moved up higher
3498                 // in the list than that client.
3499                 int clientIndex = mLruProcesses.lastIndexOf(client);
3500                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3501                         + " when updating " + app);
3502                 if (clientIndex <= lrui) {
3503                     // Don't allow the client index restriction to push it down farther in the
3504                     // list than it already is.
3505                     clientIndex = lrui;
3506                 }
3507                 if (clientIndex >= 0 && index > clientIndex) {
3508                     index = clientIndex;
3509                 }
3510             }
3511             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3512             mLruProcesses.add(index, app);
3513             nextIndex = index-1;
3514             mLruProcessActivityStart++;
3515             mLruProcessServiceStart++;
3516         }
3517
3518         // If the app is currently using a content provider or service,
3519         // bump those processes as well.
3520         for (int j=app.connections.size()-1; j>=0; j--) {
3521             ConnectionRecord cr = app.connections.valueAt(j);
3522             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3523                     && cr.binding.service.app != null
3524                     && cr.binding.service.app.lruSeq != mLruSeq
3525                     && !cr.binding.service.app.persistent) {
3526                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3527                         "service connection", cr, app);
3528             }
3529         }
3530         for (int j=app.conProviders.size()-1; j>=0; j--) {
3531             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3532             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3533                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3534                         "provider reference", cpr, app);
3535             }
3536         }
3537     }
3538
3539     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3540         if (uid == SYSTEM_UID) {
3541             // The system gets to run in any process.  If there are multiple
3542             // processes with the same uid, just pick the first (this
3543             // should never happen).
3544             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3545             if (procs == null) return null;
3546             final int procCount = procs.size();
3547             for (int i = 0; i < procCount; i++) {
3548                 final int procUid = procs.keyAt(i);
3549                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3550                     // Don't use an app process or different user process for system component.
3551                     continue;
3552                 }
3553                 return procs.valueAt(i);
3554             }
3555         }
3556         ProcessRecord proc = mProcessNames.get(processName, uid);
3557         if (false && proc != null && !keepIfLarge
3558                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3559                 && proc.lastCachedPss >= 4000) {
3560             // Turn this condition on to cause killing to happen regularly, for testing.
3561             if (proc.baseProcessTracker != null) {
3562                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3563             }
3564             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3565         } else if (proc != null && !keepIfLarge
3566                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3567                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3568             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3569             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3570                 if (proc.baseProcessTracker != null) {
3571                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3572                 }
3573                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3574             }
3575         }
3576         return proc;
3577     }
3578
3579     void notifyPackageUse(String packageName, int reason) {
3580         IPackageManager pm = AppGlobals.getPackageManager();
3581         try {
3582             pm.notifyPackageUse(packageName, reason);
3583         } catch (RemoteException e) {
3584         }
3585     }
3586
3587     boolean isNextTransitionForward() {
3588         int transit = mWindowManager.getPendingAppTransition();
3589         return transit == TRANSIT_ACTIVITY_OPEN
3590                 || transit == TRANSIT_TASK_OPEN
3591                 || transit == TRANSIT_TASK_TO_FRONT;
3592     }
3593
3594     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3595             String processName, String abiOverride, int uid, Runnable crashHandler) {
3596         synchronized(this) {
3597             ApplicationInfo info = new ApplicationInfo();
3598             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3599             // For isolated processes, the former contains the parent's uid and the latter the
3600             // actual uid of the isolated process.
3601             // In the special case introduced by this method (which is, starting an isolated
3602             // process directly from the SystemServer without an actual parent app process) the
3603             // closest thing to a parent's uid is SYSTEM_UID.
3604             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3605             // the |isolated| logic in the ProcessRecord constructor.
3606             info.uid = SYSTEM_UID;
3607             info.processName = processName;
3608             info.className = entryPoint;
3609             info.packageName = "android";
3610             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3611             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3612                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3613                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3614                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3615                     crashHandler);
3616             return proc != null ? proc.pid : 0;
3617         }
3618     }
3619
3620     final ProcessRecord startProcessLocked(String processName,
3621             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3622             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3623             boolean isolated, boolean keepIfLarge) {
3624         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3625                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3626                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3627                 null /* crashHandler */);
3628     }
3629
3630     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3631             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3632             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3633             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3634         long startTime = SystemClock.elapsedRealtime();
3635         ProcessRecord app;
3636         if (!isolated) {
3637             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3638             checkTime(startTime, "startProcess: after getProcessRecord");
3639
3640             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3641                 // If we are in the background, then check to see if this process
3642                 // is bad.  If so, we will just silently fail.
3643                 if (mAppErrors.isBadProcessLocked(info)) {
3644                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3645                             + "/" + info.processName);
3646                     return null;
3647                 }
3648             } else {
3649                 // When the user is explicitly starting a process, then clear its
3650                 // crash count so that we won't make it bad until they see at
3651                 // least one crash dialog again, and make the process good again
3652                 // if it had been bad.
3653                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3654                         + "/" + info.processName);
3655                 mAppErrors.resetProcessCrashTimeLocked(info);
3656                 if (mAppErrors.isBadProcessLocked(info)) {
3657                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3658                             UserHandle.getUserId(info.uid), info.uid,
3659                             info.processName);
3660                     mAppErrors.clearBadProcessLocked(info);
3661                     if (app != null) {
3662                         app.bad = false;
3663                     }
3664                 }
3665             }
3666         } else {
3667             // If this is an isolated process, it can't re-use an existing process.
3668             app = null;
3669         }
3670
3671         // We don't have to do anything more if:
3672         // (1) There is an existing application record; and
3673         // (2) The caller doesn't think it is dead, OR there is no thread
3674         //     object attached to it so we know it couldn't have crashed; and
3675         // (3) There is a pid assigned to it, so it is either starting or
3676         //     already running.
3677         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3678                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3679                 + " thread=" + (app != null ? app.thread : null)
3680                 + " pid=" + (app != null ? app.pid : -1));
3681         if (app != null && app.pid > 0) {
3682             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3683                 // We already have the app running, or are waiting for it to
3684                 // come up (we have a pid but not yet its thread), so keep it.
3685                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3686                 // If this is a new package in the process, add the package to the list
3687                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3688                 checkTime(startTime, "startProcess: done, added package to proc");
3689                 return app;
3690             }
3691
3692             // An application record is attached to a previous process,
3693             // clean it up now.
3694             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3695             checkTime(startTime, "startProcess: bad proc running, killing");
3696             killProcessGroup(app.uid, app.pid);
3697             handleAppDiedLocked(app, true, true);
3698             checkTime(startTime, "startProcess: done killing old proc");
3699         }
3700
3701         String hostingNameStr = hostingName != null
3702                 ? hostingName.flattenToShortString() : null;
3703
3704         if (app == null) {
3705             checkTime(startTime, "startProcess: creating new process record");
3706             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3707             if (app == null) {
3708                 Slog.w(TAG, "Failed making new process record for "
3709                         + processName + "/" + info.uid + " isolated=" + isolated);
3710                 return null;
3711             }
3712             app.crashHandler = crashHandler;
3713             checkTime(startTime, "startProcess: done creating new process record");
3714         } else {
3715             // If this is a new package in the process, add the package to the list
3716             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3717             checkTime(startTime, "startProcess: added package to existing proc");
3718         }
3719
3720         // If the system is not ready yet, then hold off on starting this
3721         // process until it is.
3722         if (!mProcessesReady
3723                 && !isAllowedWhileBooting(info)
3724                 && !allowWhileBooting) {
3725             if (!mProcessesOnHold.contains(app)) {
3726                 mProcessesOnHold.add(app);
3727             }
3728             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3729                     "System not ready, putting on hold: " + app);
3730             checkTime(startTime, "startProcess: returning with proc on hold");
3731             return app;
3732         }
3733
3734         checkTime(startTime, "startProcess: stepping in to startProcess");
3735         startProcessLocked(
3736                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3737         checkTime(startTime, "startProcess: done starting proc!");
3738         return (app.pid != 0) ? app : null;
3739     }
3740
3741     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3742         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3743     }
3744
3745     private final void startProcessLocked(ProcessRecord app,
3746             String hostingType, String hostingNameStr) {
3747         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3748                 null /* entryPoint */, null /* entryPointArgs */);
3749     }
3750
3751     private final void startProcessLocked(ProcessRecord app, String hostingType,
3752             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3753         long startTime = SystemClock.elapsedRealtime();
3754         if (app.pid > 0 && app.pid != MY_PID) {
3755             checkTime(startTime, "startProcess: removing from pids map");
3756             synchronized (mPidsSelfLocked) {
3757                 mPidsSelfLocked.remove(app.pid);
3758                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3759             }
3760             checkTime(startTime, "startProcess: done removing from pids map");
3761             app.setPid(0);
3762         }
3763
3764         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3765                 "startProcessLocked removing on hold: " + app);
3766         mProcessesOnHold.remove(app);
3767
3768         checkTime(startTime, "startProcess: starting to update cpu stats");
3769         updateCpuStats();
3770         checkTime(startTime, "startProcess: done updating cpu stats");
3771
3772         try {
3773             try {
3774                 final int userId = UserHandle.getUserId(app.uid);
3775                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3776             } catch (RemoteException e) {
3777                 throw e.rethrowAsRuntimeException();
3778             }
3779
3780             int uid = app.uid;
3781             int[] gids = null;
3782             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3783             if (!app.isolated) {
3784                 int[] permGids = null;
3785                 try {
3786                     checkTime(startTime, "startProcess: getting gids from package manager");
3787                     final IPackageManager pm = AppGlobals.getPackageManager();
3788                     permGids = pm.getPackageGids(app.info.packageName,
3789                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3790                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
3791                             StorageManagerInternal.class);
3792                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3793                             app.info.packageName);
3794                 } catch (RemoteException e) {
3795                     throw e.rethrowAsRuntimeException();
3796                 }
3797
3798                 /*
3799                  * Add shared application and profile GIDs so applications can share some
3800                  * resources like shared libraries and access user-wide resources
3801                  */
3802                 if (ArrayUtils.isEmpty(permGids)) {
3803                     gids = new int[3];
3804                 } else {
3805                     gids = new int[permGids.length + 3];
3806                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
3807                 }
3808                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3809                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3810                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3811             }
3812             checkTime(startTime, "startProcess: building args");
3813             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3814                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3815                         && mTopComponent != null
3816                         && app.processName.equals(mTopComponent.getPackageName())) {
3817                     uid = 0;
3818                 }
3819                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3820                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3821                     uid = 0;
3822                 }
3823             }
3824             int debugFlags = 0;
3825             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3826                 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3827                 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3828                 // Also turn on CheckJNI for debuggable apps. It's quite
3829                 // awkward to turn on otherwise.
3830                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3831             }
3832             // Run the app in safe mode if its manifest requests so or the
3833             // system is booted in safe mode.
3834             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3835                 mSafeMode == true) {
3836                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3837             }
3838             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3839                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3840             }
3841             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3842             if ("true".equals(genDebugInfoProperty)) {
3843                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3844             }
3845             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3846                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3847             }
3848             if ("1".equals(SystemProperties.get("debug.assert"))) {
3849                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3850             }
3851             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3852                 // Enable all debug flags required by the native debugger.
3853                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3854                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3855                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3856                 mNativeDebuggingApp = null;
3857             }
3858
3859             String invokeWith = null;
3860             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3861                 // Debuggable apps may include a wrapper script with their library directory.
3862                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3863                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3864                 try {
3865                     if (new File(wrapperFileName).exists()) {
3866                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3867                     }
3868                 } finally {
3869                     StrictMode.setThreadPolicy(oldPolicy);
3870                 }
3871             }
3872
3873             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3874             if (requiredAbi == null) {
3875                 requiredAbi = Build.SUPPORTED_ABIS[0];
3876             }
3877
3878             String instructionSet = null;
3879             if (app.info.primaryCpuAbi != null) {
3880                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3881             }
3882
3883             app.gids = gids;
3884             app.requiredAbi = requiredAbi;
3885             app.instructionSet = instructionSet;
3886
3887             // the per-user SELinux context must be set
3888             if (TextUtils.isEmpty(app.info.seInfoUser)) {
3889                 Slog.wtf(TAG, "SELinux tag not defined",
3890                         new IllegalStateException("SELinux tag not defined for "
3891                         + app.info.packageName + " (uid " + app.uid + ")"));
3892             }
3893             final String seInfo = app.info.seInfo
3894                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3895             // Start the process.  It will either succeed and return a result containing
3896             // the PID of the new process, or else throw a RuntimeException.
3897             boolean isActivityProcess = (entryPoint == null);
3898             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3899             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3900                     app.processName);
3901             checkTime(startTime, "startProcess: asking zygote to start proc");
3902             ProcessStartResult startResult;
3903             if (hostingType.equals("webview_service")) {
3904                 startResult = startWebView(entryPoint,
3905                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3906                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3907                         app.info.dataDir, null, entryPointArgs);
3908             } else {
3909                 startResult = Process.start(entryPoint,
3910                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3911                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3912                         app.info.dataDir, invokeWith, entryPointArgs);
3913             }
3914             checkTime(startTime, "startProcess: returned from zygote!");
3915             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3916
3917             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3918             checkTime(startTime, "startProcess: done updating battery stats");
3919
3920             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3921                     UserHandle.getUserId(uid), startResult.pid, uid,
3922                     app.processName, hostingType,
3923                     hostingNameStr != null ? hostingNameStr : "");
3924
3925             try {
3926                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3927                         seInfo, app.info.sourceDir, startResult.pid);
3928             } catch (RemoteException ex) {
3929                 // Ignore
3930             }
3931
3932             if (app.persistent) {
3933                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3934             }
3935
3936             checkTime(startTime, "startProcess: building log message");
3937             StringBuilder buf = mStringBuilder;
3938             buf.setLength(0);
3939             buf.append("Start proc ");
3940             buf.append(startResult.pid);
3941             buf.append(':');
3942             buf.append(app.processName);
3943             buf.append('/');
3944             UserHandle.formatUid(buf, uid);
3945             if (!isActivityProcess) {
3946                 buf.append(" [");
3947                 buf.append(entryPoint);
3948                 buf.append("]");
3949             }
3950             buf.append(" for ");
3951             buf.append(hostingType);
3952             if (hostingNameStr != null) {
3953                 buf.append(" ");
3954                 buf.append(hostingNameStr);
3955             }
3956             Slog.i(TAG, buf.toString());
3957             app.setPid(startResult.pid);
3958             app.usingWrapper = startResult.usingWrapper;
3959             app.removed = false;
3960             app.killed = false;
3961             app.killedByAm = false;
3962             checkTime(startTime, "startProcess: starting to update pids map");
3963             ProcessRecord oldApp;
3964             synchronized (mPidsSelfLocked) {
3965                 oldApp = mPidsSelfLocked.get(startResult.pid);
3966             }
3967             // If there is already an app occupying that pid that hasn't been cleaned up
3968             if (oldApp != null && !app.isolated) {
3969                 // Clean up anything relating to this pid first
3970                 Slog.w(TAG, "Reusing pid " + startResult.pid
3971                         + " while app is still mapped to it");
3972                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3973                         true /*replacingPid*/);
3974             }
3975             synchronized (mPidsSelfLocked) {
3976                 this.mPidsSelfLocked.put(startResult.pid, app);
3977                 if (isActivityProcess) {
3978                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3979                     msg.obj = app;
3980                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3981                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3982                 }
3983             }
3984             checkTime(startTime, "startProcess: done updating pids map");
3985         } catch (RuntimeException e) {
3986             Slog.e(TAG, "Failure starting process " + app.processName, e);
3987
3988             // Something went very wrong while trying to start this process; one
3989             // common case is when the package is frozen due to an active
3990             // upgrade. To recover, clean up any active bookkeeping related to
3991             // starting this process. (We already invoked this method once when
3992             // the package was initially frozen through KILL_APPLICATION_MSG, so
3993             // it doesn't hurt to use it again.)
3994             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3995                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3996         }
3997     }
3998
3999     void updateUsageStats(ActivityRecord component, boolean resumed) {
4000         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4001                 "updateUsageStats: comp=" + component + "res=" + resumed);
4002         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4003         if (resumed) {
4004             if (mUsageStatsService != null) {
4005                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4006                         UsageEvents.Event.MOVE_TO_FOREGROUND);
4007             }
4008             synchronized (stats) {
4009                 stats.noteActivityResumedLocked(component.app.uid);
4010             }
4011         } else {
4012             if (mUsageStatsService != null) {
4013                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4014                         UsageEvents.Event.MOVE_TO_BACKGROUND);
4015             }
4016             synchronized (stats) {
4017                 stats.noteActivityPausedLocked(component.app.uid);
4018             }
4019         }
4020     }
4021
4022     Intent getHomeIntent() {
4023         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4024         intent.setComponent(mTopComponent);
4025         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4026         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4027             intent.addCategory(Intent.CATEGORY_HOME);
4028         }
4029         return intent;
4030     }
4031
4032     boolean startHomeActivityLocked(int userId, String reason) {
4033         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4034                 && mTopAction == null) {
4035             // We are running in factory test mode, but unable to find
4036             // the factory test app, so just sit around displaying the
4037             // error message and don't try to start anything.
4038             return false;
4039         }
4040         Intent intent = getHomeIntent();
4041         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4042         if (aInfo != null) {
4043             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4044             // Don't do this if the home app is currently being
4045             // instrumented.
4046             aInfo = new ActivityInfo(aInfo);
4047             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4048             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4049                     aInfo.applicationInfo.uid, true);
4050             if (app == null || app.instr == null) {
4051                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4052                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4053                 // For ANR debugging to verify if the user activity is the one that actually
4054                 // launched.
4055                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4056                 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4057             }
4058         } else {
4059             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4060         }
4061
4062         return true;
4063     }
4064
4065     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4066         ActivityInfo ai = null;
4067         ComponentName comp = intent.getComponent();
4068         try {
4069             if (comp != null) {
4070                 // Factory test.
4071                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4072             } else {
4073                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4074                         intent,
4075                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4076                         flags, userId);
4077
4078                 if (info != null) {
4079                     ai = info.activityInfo;
4080                 }
4081             }
4082         } catch (RemoteException e) {
4083             // ignore
4084         }
4085
4086         return ai;
4087     }
4088
4089     /**
4090      * Starts the "new version setup screen" if appropriate.
4091      */
4092     void startSetupActivityLocked() {
4093         // Only do this once per boot.
4094         if (mCheckedForSetup) {
4095             return;
4096         }
4097
4098         // We will show this screen if the current one is a different
4099         // version than the last one shown, and we are not running in
4100         // low-level factory test mode.
4101         final ContentResolver resolver = mContext.getContentResolver();
4102         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4103                 Settings.Global.getInt(resolver,
4104                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4105             mCheckedForSetup = true;
4106
4107             // See if we should be showing the platform update setup UI.
4108             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4109             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4110                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4111             if (!ris.isEmpty()) {
4112                 final ResolveInfo ri = ris.get(0);
4113                 String vers = ri.activityInfo.metaData != null
4114                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4115                         : null;
4116                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4117                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4118                             Intent.METADATA_SETUP_VERSION);
4119                 }
4120                 String lastVers = Settings.Secure.getString(
4121                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4122                 if (vers != null && !vers.equals(lastVers)) {
4123                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4124                     intent.setComponent(new ComponentName(
4125                             ri.activityInfo.packageName, ri.activityInfo.name));
4126                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4127                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4128                             null, 0, 0, 0, null, false, false, null, null, null,
4129                             "startSetupActivity");
4130                 }
4131             }
4132         }
4133     }
4134
4135     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4136         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4137     }
4138
4139     void enforceNotIsolatedCaller(String caller) {
4140         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4141             throw new SecurityException("Isolated process not allowed to call " + caller);
4142         }
4143     }
4144
4145     void enforceShellRestriction(String restriction, int userHandle) {
4146         if (Binder.getCallingUid() == SHELL_UID) {
4147             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4148                 throw new SecurityException("Shell does not have permission to access user "
4149                         + userHandle);
4150             }
4151         }
4152     }
4153
4154     @Override
4155     public int getFrontActivityScreenCompatMode() {
4156         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4157         synchronized (this) {
4158             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4159         }
4160     }
4161
4162     @Override
4163     public void setFrontActivityScreenCompatMode(int mode) {
4164         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4165                 "setFrontActivityScreenCompatMode");
4166         synchronized (this) {
4167             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4168         }
4169     }
4170
4171     @Override
4172     public int getPackageScreenCompatMode(String packageName) {
4173         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4174         synchronized (this) {
4175             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4176         }
4177     }
4178
4179     @Override
4180     public void setPackageScreenCompatMode(String packageName, int mode) {
4181         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4182                 "setPackageScreenCompatMode");
4183         synchronized (this) {
4184             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4185         }
4186     }
4187
4188     @Override
4189     public boolean getPackageAskScreenCompat(String packageName) {
4190         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4191         synchronized (this) {
4192             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4193         }
4194     }
4195
4196     @Override
4197     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4198         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4199                 "setPackageAskScreenCompat");
4200         synchronized (this) {
4201             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4202         }
4203     }
4204
4205     private boolean hasUsageStatsPermission(String callingPackage) {
4206         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4207                 Binder.getCallingUid(), callingPackage);
4208         if (mode == AppOpsManager.MODE_DEFAULT) {
4209             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4210                     == PackageManager.PERMISSION_GRANTED;
4211         }
4212         return mode == AppOpsManager.MODE_ALLOWED;
4213     }
4214
4215     @Override
4216     public int getPackageProcessState(String packageName, String callingPackage) {
4217         if (!hasUsageStatsPermission(callingPackage)) {
4218             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4219                     "getPackageProcessState");
4220         }
4221
4222         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4223         synchronized (this) {
4224             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4225                 final ProcessRecord proc = mLruProcesses.get(i);
4226                 if (procState > proc.setProcState) {
4227                     if (proc.pkgList.containsKey(packageName) ||
4228                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4229                         procState = proc.setProcState;
4230                     }
4231                 }
4232             }
4233         }
4234         return procState;
4235     }
4236
4237     @Override
4238     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4239             throws RemoteException {
4240         synchronized (this) {
4241             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4242             if (app == null) {
4243                 throw new IllegalArgumentException("Unknown process: " + process);
4244             }
4245             if (app.thread == null) {
4246                 throw new IllegalArgumentException("Process has no app thread");
4247             }
4248             if (app.trimMemoryLevel >= level) {
4249                 throw new IllegalArgumentException(
4250                         "Unable to set a higher trim level than current level");
4251             }
4252             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4253                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4254                 throw new IllegalArgumentException("Unable to set a background trim level "
4255                     + "on a foreground process");
4256             }
4257             app.thread.scheduleTrimMemory(level);
4258             app.trimMemoryLevel = level;
4259             return true;
4260         }
4261     }
4262
4263     private void dispatchProcessesChanged() {
4264         int N;
4265         synchronized (this) {
4266             N = mPendingProcessChanges.size();
4267             if (mActiveProcessChanges.length < N) {
4268                 mActiveProcessChanges = new ProcessChangeItem[N];
4269             }
4270             mPendingProcessChanges.toArray(mActiveProcessChanges);
4271             mPendingProcessChanges.clear();
4272             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4273                     "*** Delivering " + N + " process changes");
4274         }
4275
4276         int i = mProcessObservers.beginBroadcast();
4277         while (i > 0) {
4278             i--;
4279             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4280             if (observer != null) {
4281                 try {
4282                     for (int j=0; j<N; j++) {
4283                         ProcessChangeItem item = mActiveProcessChanges[j];
4284                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4285                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4286                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4287                                     + item.uid + ": " + item.foregroundActivities);
4288                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4289                                     item.foregroundActivities);
4290                         }
4291                     }
4292                 } catch (RemoteException e) {
4293                 }
4294             }
4295         }
4296         mProcessObservers.finishBroadcast();
4297
4298         synchronized (this) {
4299             for (int j=0; j<N; j++) {
4300                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4301             }
4302         }
4303     }
4304
4305     private void dispatchProcessDied(int pid, int uid) {
4306         int i = mProcessObservers.beginBroadcast();
4307         while (i > 0) {
4308             i--;
4309             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4310             if (observer != null) {
4311                 try {
4312                     observer.onProcessDied(pid, uid);
4313                 } catch (RemoteException e) {
4314                 }
4315             }
4316         }
4317         mProcessObservers.finishBroadcast();
4318     }
4319
4320     @VisibleForTesting
4321     void dispatchUidsChanged() {
4322         int N;
4323         synchronized (this) {
4324             N = mPendingUidChanges.size();
4325             if (mActiveUidChanges.length < N) {
4326                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4327             }
4328             for (int i=0; i<N; i++) {
4329                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4330                 mActiveUidChanges[i] = change;
4331                 if (change.uidRecord != null) {
4332                     change.uidRecord.pendingChange = null;
4333                     change.uidRecord = null;
4334                 }
4335             }
4336             mPendingUidChanges.clear();
4337             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4338                     "*** Delivering " + N + " uid changes");
4339         }
4340
4341         int i = mUidObservers.beginBroadcast();
4342         while (i > 0) {
4343             i--;
4344             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4345                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4346         }
4347         mUidObservers.finishBroadcast();
4348
4349         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4350             for (int j = 0; j < N; ++j) {
4351                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4352                 if (item.change == UidRecord.CHANGE_GONE
4353                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4354                     mValidateUids.remove(item.uid);
4355                 } else {
4356                     UidRecord validateUid = mValidateUids.get(item.uid);
4357                     if (validateUid == null) {
4358                         validateUid = new UidRecord(item.uid);
4359                         mValidateUids.put(item.uid, validateUid);
4360                     }
4361                     if (item.change == UidRecord.CHANGE_IDLE) {
4362                         validateUid.idle = true;
4363                     } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4364                         validateUid.idle = false;
4365                     }
4366                     validateUid.curProcState = validateUid.setProcState = item.processState;
4367                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4368                 }
4369             }
4370         }
4371
4372         synchronized (this) {
4373             for (int j = 0; j < N; j++) {
4374                 mAvailUidChanges.add(mActiveUidChanges[j]);
4375             }
4376         }
4377     }
4378
4379     private void dispatchUidsChangedForObserver(IUidObserver observer,
4380             UidObserverRegistration reg, int changesSize) {
4381         if (observer == null) {
4382             return;
4383         }
4384         try {
4385             for (int j = 0; j < changesSize; j++) {
4386                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4387                 final int change = item.change;
4388                 if (change == UidRecord.CHANGE_IDLE
4389                         || change == UidRecord.CHANGE_GONE_IDLE) {
4390                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4391                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4392                                 "UID idle uid=" + item.uid);
4393                         observer.onUidIdle(item.uid, item.ephemeral);
4394                     }
4395                 } else if (change == UidRecord.CHANGE_ACTIVE) {
4396                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4397                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4398                                 "UID active uid=" + item.uid);
4399                         observer.onUidActive(item.uid);
4400                     }
4401                 }
4402                 if (change == UidRecord.CHANGE_GONE
4403                         || change == UidRecord.CHANGE_GONE_IDLE) {
4404                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4405                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4406                                 "UID gone uid=" + item.uid);
4407                         observer.onUidGone(item.uid, item.ephemeral);
4408                     }
4409                     if (reg.lastProcStates != null) {
4410                         reg.lastProcStates.delete(item.uid);
4411                     }
4412                 } else {
4413                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4414                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4415                                 "UID CHANGED uid=" + item.uid
4416                                         + ": " + item.processState);
4417                         boolean doReport = true;
4418                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4419                             final int lastState = reg.lastProcStates.get(item.uid,
4420                                     ActivityManager.PROCESS_STATE_UNKNOWN);
4421                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4422                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
4423                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
4424                                 doReport = lastAboveCut != newAboveCut;
4425                             } else {
4426                                 doReport = item.processState
4427                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
4428                             }
4429                         }
4430                         if (doReport) {
4431                             if (reg.lastProcStates != null) {
4432                                 reg.lastProcStates.put(item.uid, item.processState);
4433                             }
4434                             observer.onUidStateChanged(item.uid, item.processState,
4435                                     item.procStateSeq);
4436                         }
4437                     }
4438                 }
4439             }
4440         } catch (RemoteException e) {
4441         }
4442     }
4443
4444     @Override
4445     public final int startActivity(IApplicationThread caller, String callingPackage,
4446             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4447             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4448         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4449                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4450                 UserHandle.getCallingUserId());
4451     }
4452
4453     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4454         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4455         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4456                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4457                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4458
4459         // TODO: Switch to user app stacks here.
4460         String mimeType = intent.getType();
4461         final Uri data = intent.getData();
4462         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4463             mimeType = getProviderMimeType(data, userId);
4464         }
4465         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4466
4467         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4468         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null,
4469                 null, null, 0, 0, null, null, null, null, false, userId, container, null,
4470                 "startActivity");
4471     }
4472
4473     @Override
4474     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4475             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4476             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4477         enforceNotIsolatedCaller("startActivity");
4478         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4479                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4480         // TODO: Switch to user app stacks here.
4481         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4482                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4483                 profilerInfo, null, null, bOptions, false, userId, null, null,
4484                 "startActivityAsUser");
4485     }
4486
4487     @Override
4488     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4489             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4490             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4491             int userId) {
4492
4493         // This is very dangerous -- it allows you to perform a start activity (including
4494         // permission grants) as any app that may launch one of your own activities.  So
4495         // we will only allow this to be done from activities that are part of the core framework,
4496         // and then only when they are running as the system.
4497         final ActivityRecord sourceRecord;
4498         final int targetUid;
4499         final String targetPackage;
4500         synchronized (this) {
4501             if (resultTo == null) {
4502                 throw new SecurityException("Must be called from an activity");
4503             }
4504             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4505             if (sourceRecord == null) {
4506                 throw new SecurityException("Called with bad activity token: " + resultTo);
4507             }
4508             if (!sourceRecord.info.packageName.equals("android")) {
4509                 throw new SecurityException(
4510                         "Must be called from an activity that is declared in the android package");
4511             }
4512             if (sourceRecord.app == null) {
4513                 throw new SecurityException("Called without a process attached to activity");
4514             }
4515             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4516                 // This is still okay, as long as this activity is running under the
4517                 // uid of the original calling activity.
4518                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4519                     throw new SecurityException(
4520                             "Calling activity in uid " + sourceRecord.app.uid
4521                                     + " must be system uid or original calling uid "
4522                                     + sourceRecord.launchedFromUid);
4523                 }
4524             }
4525             if (ignoreTargetSecurity) {
4526                 if (intent.getComponent() == null) {
4527                     throw new SecurityException(
4528                             "Component must be specified with ignoreTargetSecurity");
4529                 }
4530                 if (intent.getSelector() != null) {
4531                     throw new SecurityException(
4532                             "Selector not allowed with ignoreTargetSecurity");
4533                 }
4534             }
4535             targetUid = sourceRecord.launchedFromUid;
4536             targetPackage = sourceRecord.launchedFromPackage;
4537         }
4538
4539         if (userId == UserHandle.USER_NULL) {
4540             userId = UserHandle.getUserId(sourceRecord.app.uid);
4541         }
4542
4543         // TODO: Switch to user app stacks here.
4544         try {
4545             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4546                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4547                     null, null, bOptions, ignoreTargetSecurity, userId, null, null,
4548                     "startActivityAsCaller");
4549             return ret;
4550         } catch (SecurityException e) {
4551             // XXX need to figure out how to propagate to original app.
4552             // A SecurityException here is generally actually a fault of the original
4553             // calling activity (such as a fairly granting permissions), so propagate it
4554             // back to them.
4555             /*
4556             StringBuilder msg = new StringBuilder();
4557             msg.append("While launching");
4558             msg.append(intent.toString());
4559             msg.append(": ");
4560             msg.append(e.getMessage());
4561             */
4562             throw e;
4563         }
4564     }
4565
4566     @Override
4567     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4568             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4569             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4570         enforceNotIsolatedCaller("startActivityAndWait");
4571         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4572                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4573         WaitResult res = new WaitResult();
4574         // TODO: Switch to user app stacks here.
4575         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4576                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4577                 bOptions, false, userId, null, null, "startActivityAndWait");
4578         return res;
4579     }
4580
4581     @Override
4582     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4583             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4584             int startFlags, Configuration config, Bundle bOptions, int userId) {
4585         enforceNotIsolatedCaller("startActivityWithConfig");
4586         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4587                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4588         // TODO: Switch to user app stacks here.
4589         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4590                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4591                 null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig");
4592         return ret;
4593     }
4594
4595     @Override
4596     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4597             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4598             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4599             throws TransactionTooLargeException {
4600         enforceNotIsolatedCaller("startActivityIntentSender");
4601         // Refuse possible leaked file descriptors
4602         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4603             throw new IllegalArgumentException("File descriptors passed in Intent");
4604         }
4605
4606         if (!(target instanceof PendingIntentRecord)) {
4607             throw new IllegalArgumentException("Bad PendingIntent object");
4608         }
4609
4610         PendingIntentRecord pir = (PendingIntentRecord)target;
4611
4612         synchronized (this) {
4613             // If this is coming from the currently resumed activity, it is
4614             // effectively saying that app switches are allowed at this point.
4615             final ActivityStack stack = getFocusedStack();
4616             if (stack.mResumedActivity != null &&
4617                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4618                 mAppSwitchesAllowedTime = 0;
4619             }
4620         }
4621         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4622                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4623         return ret;
4624     }
4625
4626     @Override
4627     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4628             Intent intent, String resolvedType, IVoiceInteractionSession session,
4629             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4630             Bundle bOptions, int userId) {
4631         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4632                 != PackageManager.PERMISSION_GRANTED) {
4633             String msg = "Permission Denial: startVoiceActivity() from pid="
4634                     + Binder.getCallingPid()
4635                     + ", uid=" + Binder.getCallingUid()
4636                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4637             Slog.w(TAG, msg);
4638             throw new SecurityException(msg);
4639         }
4640         if (session == null || interactor == null) {
4641             throw new NullPointerException("null session or interactor");
4642         }
4643         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4644                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4645         // TODO: Switch to user app stacks here.
4646         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4647                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4648                 null, bOptions, false, userId, null, null, "startVoiceActivity");
4649     }
4650
4651     @Override
4652     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4653             Intent intent, String resolvedType, Bundle bOptions, int userId) {
4654         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4655                 != PackageManager.PERMISSION_GRANTED) {
4656             final String msg = "Permission Denial: startAssistantActivity() from pid="
4657                     + Binder.getCallingPid()
4658                     + ", uid=" + Binder.getCallingUid()
4659                     + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4660             Slog.w(TAG, msg);
4661             throw new SecurityException(msg);
4662         }
4663         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4664                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4665         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4666                 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4667                 userId, null, null, "startAssistantActivity");
4668     }
4669
4670     @Override
4671     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4672             throws RemoteException {
4673         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4674         synchronized (this) {
4675             ActivityRecord activity = getFocusedStack().topActivity();
4676             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4677                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4678             }
4679             if (mRunningVoice != null || activity.getTask().voiceSession != null
4680                     || activity.voiceSession != null) {
4681                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4682                 return;
4683             }
4684             if (activity.pendingVoiceInteractionStart) {
4685                 Slog.w(TAG, "Pending start of voice interaction already.");
4686                 return;
4687             }
4688             activity.pendingVoiceInteractionStart = true;
4689         }
4690         LocalServices.getService(VoiceInteractionManagerInternal.class)
4691                 .startLocalVoiceInteraction(callingActivity, options);
4692     }
4693
4694     @Override
4695     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4696         LocalServices.getService(VoiceInteractionManagerInternal.class)
4697                 .stopLocalVoiceInteraction(callingActivity);
4698     }
4699
4700     @Override
4701     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4702         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4703                 .supportsLocalVoiceInteraction();
4704     }
4705
4706     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4707             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4708         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4709         if (activityToCallback == null) return;
4710         activityToCallback.setVoiceSessionLocked(voiceSession);
4711
4712         // Inform the activity
4713         try {
4714             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4715                     voiceInteractor);
4716             long token = Binder.clearCallingIdentity();
4717             try {
4718                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4719             } finally {
4720                 Binder.restoreCallingIdentity(token);
4721             }
4722             // TODO: VI Should we cache the activity so that it's easier to find later
4723             // rather than scan through all the stacks and activities?
4724         } catch (RemoteException re) {
4725             activityToCallback.clearVoiceSessionLocked();
4726             // TODO: VI Should this terminate the voice session?
4727         }
4728     }
4729
4730     @Override
4731     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4732         synchronized (this) {
4733             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4734                 if (keepAwake) {
4735                     mVoiceWakeLock.acquire();
4736                 } else {
4737                     mVoiceWakeLock.release();
4738                 }
4739             }
4740         }
4741     }
4742
4743     @Override
4744     public boolean startNextMatchingActivity(IBinder callingActivity,
4745             Intent intent, Bundle bOptions) {
4746         // Refuse possible leaked file descriptors
4747         if (intent != null && intent.hasFileDescriptors() == true) {
4748             throw new IllegalArgumentException("File descriptors passed in Intent");
4749         }
4750         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4751
4752         synchronized (this) {
4753             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4754             if (r == null) {
4755                 ActivityOptions.abort(options);
4756                 return false;
4757             }
4758             if (r.app == null || r.app.thread == null) {
4759                 // The caller is not running...  d'oh!
4760                 ActivityOptions.abort(options);
4761                 return false;
4762             }
4763             intent = new Intent(intent);
4764             // The caller is not allowed to change the data.
4765             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4766             // And we are resetting to find the next component...
4767             intent.setComponent(null);
4768
4769             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4770
4771             ActivityInfo aInfo = null;
4772             try {
4773                 List<ResolveInfo> resolves =
4774                     AppGlobals.getPackageManager().queryIntentActivities(
4775                             intent, r.resolvedType,
4776                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4777                             UserHandle.getCallingUserId()).getList();
4778
4779                 // Look for the original activity in the list...
4780                 final int N = resolves != null ? resolves.size() : 0;
4781                 for (int i=0; i<N; i++) {
4782                     ResolveInfo rInfo = resolves.get(i);
4783                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4784                             && rInfo.activityInfo.name.equals(r.info.name)) {
4785                         // We found the current one...  the next matching is
4786                         // after it.
4787                         i++;
4788                         if (i<N) {
4789                             aInfo = resolves.get(i).activityInfo;
4790                         }
4791                         if (debug) {
4792                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4793                                     + "/" + r.info.name);
4794                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4795                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4796                         }
4797                         break;
4798                     }
4799                 }
4800             } catch (RemoteException e) {
4801             }
4802
4803             if (aInfo == null) {
4804                 // Nobody who is next!
4805                 ActivityOptions.abort(options);
4806                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4807                 return false;
4808             }
4809
4810             intent.setComponent(new ComponentName(
4811                     aInfo.applicationInfo.packageName, aInfo.name));
4812             intent.setFlags(intent.getFlags()&~(
4813                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4814                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4815                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4816                     Intent.FLAG_ACTIVITY_NEW_TASK));
4817
4818             // Okay now we need to start the new activity, replacing the
4819             // currently running activity.  This is a little tricky because
4820             // we want to start the new one as if the current one is finished,
4821             // but not finish the current one first so that there is no flicker.
4822             // And thus...
4823             final boolean wasFinishing = r.finishing;
4824             r.finishing = true;
4825
4826             // Propagate reply information over to the new activity.
4827             final ActivityRecord resultTo = r.resultTo;
4828             final String resultWho = r.resultWho;
4829             final int requestCode = r.requestCode;
4830             r.resultTo = null;
4831             if (resultTo != null) {
4832                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4833             }
4834
4835             final long origId = Binder.clearCallingIdentity();
4836             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4837                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4838                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4839                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4840                     false, false, null, null, null, "startNextMatchingActivity");
4841             Binder.restoreCallingIdentity(origId);
4842
4843             r.finishing = wasFinishing;
4844             if (res != ActivityManager.START_SUCCESS) {
4845                 return false;
4846             }
4847             return true;
4848         }
4849     }
4850
4851     @Override
4852     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4853         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4854             String msg = "Permission Denial: startActivityFromRecents called without " +
4855                     START_TASKS_FROM_RECENTS;
4856             Slog.w(TAG, msg);
4857             throw new SecurityException(msg);
4858         }
4859         final long origId = Binder.clearCallingIdentity();
4860         try {
4861             synchronized (this) {
4862                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4863             }
4864         } finally {
4865             Binder.restoreCallingIdentity(origId);
4866         }
4867     }
4868
4869     final int startActivityInPackage(int uid, String callingPackage,
4870             Intent intent, String resolvedType, IBinder resultTo,
4871             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4872             IActivityContainer container, TaskRecord inTask, String reason) {
4873
4874         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4875                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4876
4877         // TODO: Switch to user app stacks here.
4878         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4879                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4880                 null, null, null, bOptions, false, userId, container, inTask, reason);
4881         return ret;
4882     }
4883
4884     @Override
4885     public final int startActivities(IApplicationThread caller, String callingPackage,
4886             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4887             int userId) {
4888         final String reason = "startActivities";
4889         enforceNotIsolatedCaller(reason);
4890         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4891                 userId, false, ALLOW_FULL_ONLY, reason, null);
4892         // TODO: Switch to user app stacks here.
4893         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4894                 resolvedTypes, resultTo, bOptions, userId, reason);
4895         return ret;
4896     }
4897
4898     final int startActivitiesInPackage(int uid, String callingPackage,
4899             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4900             Bundle bOptions, int userId) {
4901
4902         final String reason = "startActivityInPackage";
4903         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4904                 userId, false, ALLOW_FULL_ONLY, reason, null);
4905         // TODO: Switch to user app stacks here.
4906         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4907                 resultTo, bOptions, userId, reason);
4908         return ret;
4909     }
4910
4911     @Override
4912     public void reportActivityFullyDrawn(IBinder token) {
4913         synchronized (this) {
4914             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4915             if (r == null) {
4916                 return;
4917             }
4918             r.reportFullyDrawnLocked();
4919         }
4920     }
4921
4922     @Override
4923     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4924         synchronized (this) {
4925             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4926             if (r == null) {
4927                 return;
4928             }
4929             final long origId = Binder.clearCallingIdentity();
4930             try {
4931                 r.setRequestedOrientation(requestedOrientation);
4932             } finally {
4933                 Binder.restoreCallingIdentity(origId);
4934             }
4935         }
4936     }
4937
4938     @Override
4939     public int getRequestedOrientation(IBinder token) {
4940         synchronized (this) {
4941             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4942             if (r == null) {
4943                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4944             }
4945             return r.getRequestedOrientation();
4946         }
4947     }
4948
4949     @Override
4950     public final void requestActivityRelaunch(IBinder token) {
4951         synchronized(this) {
4952             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4953             if (r == null) {
4954                 return;
4955             }
4956             final long origId = Binder.clearCallingIdentity();
4957             try {
4958                 r.forceNewConfig = true;
4959                 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4960                         true /* preserveWindow */);
4961             } finally {
4962                 Binder.restoreCallingIdentity(origId);
4963             }
4964         }
4965     }
4966
4967     /**
4968      * This is the internal entry point for handling Activity.finish().
4969      *
4970      * @param token The Binder token referencing the Activity we want to finish.
4971      * @param resultCode Result code, if any, from this Activity.
4972      * @param resultData Result data (Intent), if any, from this Activity.
4973      * @param finishTask Whether to finish the task associated with this Activity.
4974      *
4975      * @return Returns true if the activity successfully finished, or false if it is still running.
4976      */
4977     @Override
4978     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4979             int finishTask) {
4980         // Refuse possible leaked file descriptors
4981         if (resultData != null && resultData.hasFileDescriptors() == true) {
4982             throw new IllegalArgumentException("File descriptors passed in Intent");
4983         }
4984
4985         synchronized(this) {
4986             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4987             if (r == null) {
4988                 return true;
4989             }
4990             // Keep track of the root activity of the task before we finish it
4991             TaskRecord tr = r.getTask();
4992             ActivityRecord rootR = tr.getRootActivity();
4993             if (rootR == null) {
4994                 Slog.w(TAG, "Finishing task with all activities already finished");
4995             }
4996             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4997             // finish.
4998             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4999                     mStackSupervisor.isLastLockedTask(tr)) {
5000                 Slog.i(TAG, "Not finishing task in lock task mode");
5001                 mStackSupervisor.showLockTaskToast();
5002                 return false;
5003             }
5004             if (mController != null) {
5005                 // Find the first activity that is not finishing.
5006                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5007                 if (next != null) {
5008                     // ask watcher if this is allowed
5009                     boolean resumeOK = true;
5010                     try {
5011                         resumeOK = mController.activityResuming(next.packageName);
5012                     } catch (RemoteException e) {
5013                         mController = null;
5014                         Watchdog.getInstance().setActivityController(null);
5015                     }
5016
5017                     if (!resumeOK) {
5018                         Slog.i(TAG, "Not finishing activity because controller resumed");
5019                         return false;
5020                     }
5021                 }
5022             }
5023             final long origId = Binder.clearCallingIdentity();
5024             try {
5025                 boolean res;
5026                 final boolean finishWithRootActivity =
5027                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5028                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5029                         || (finishWithRootActivity && r == rootR)) {
5030                     // If requested, remove the task that is associated to this activity only if it
5031                     // was the root activity in the task. The result code and data is ignored
5032                     // because we don't support returning them across task boundaries. Also, to
5033                     // keep backwards compatibility we remove the task from recents when finishing
5034                     // task with root activity.
5035                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5036                     if (!res) {
5037                         Slog.i(TAG, "Removing task failed to finish activity");
5038                     }
5039                 } else {
5040                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5041                             resultData, "app-request", true);
5042                     if (!res) {
5043                         Slog.i(TAG, "Failed to finish by app-request");
5044                     }
5045                 }
5046                 return res;
5047             } finally {
5048                 Binder.restoreCallingIdentity(origId);
5049             }
5050         }
5051     }
5052
5053     @Override
5054     public final void finishHeavyWeightApp() {
5055         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5056                 != PackageManager.PERMISSION_GRANTED) {
5057             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5058                     + Binder.getCallingPid()
5059                     + ", uid=" + Binder.getCallingUid()
5060                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5061             Slog.w(TAG, msg);
5062             throw new SecurityException(msg);
5063         }
5064
5065         synchronized(this) {
5066             if (mHeavyWeightProcess == null) {
5067                 return;
5068             }
5069
5070             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5071             for (int i = 0; i < activities.size(); i++) {
5072                 ActivityRecord r = activities.get(i);
5073                 if (!r.finishing && r.isInStackLocked()) {
5074                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5075                             null, "finish-heavy", true);
5076                 }
5077             }
5078
5079             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5080                     mHeavyWeightProcess.userId, 0));
5081             mHeavyWeightProcess = null;
5082         }
5083     }
5084
5085     @Override
5086     public void crashApplication(int uid, int initialPid, String packageName, int userId,
5087             String message) {
5088         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5089                 != PackageManager.PERMISSION_GRANTED) {
5090             String msg = "Permission Denial: crashApplication() from pid="
5091                     + Binder.getCallingPid()
5092                     + ", uid=" + Binder.getCallingUid()
5093                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5094             Slog.w(TAG, msg);
5095             throw new SecurityException(msg);
5096         }
5097
5098         synchronized(this) {
5099             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5100         }
5101     }
5102
5103     @Override
5104     public final void finishSubActivity(IBinder token, String resultWho,
5105             int requestCode) {
5106         synchronized(this) {
5107             final long origId = Binder.clearCallingIdentity();
5108             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5109             if (r != null) {
5110                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5111             }
5112             Binder.restoreCallingIdentity(origId);
5113         }
5114     }
5115
5116     @Override
5117     public boolean finishActivityAffinity(IBinder token) {
5118         synchronized(this) {
5119             final long origId = Binder.clearCallingIdentity();
5120             try {
5121                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5122                 if (r == null) {
5123                     return false;
5124                 }
5125
5126                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5127                 // can finish.
5128                 final TaskRecord task = r.getTask();
5129                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5130                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5131                     mStackSupervisor.showLockTaskToast();
5132                     return false;
5133                 }
5134                 return task.getStack().finishActivityAffinityLocked(r);
5135             } finally {
5136                 Binder.restoreCallingIdentity(origId);
5137             }
5138         }
5139     }
5140
5141     @Override
5142     public void finishVoiceTask(IVoiceInteractionSession session) {
5143         synchronized (this) {
5144             final long origId = Binder.clearCallingIdentity();
5145             try {
5146                 // TODO: VI Consider treating local voice interactions and voice tasks
5147                 // differently here
5148                 mStackSupervisor.finishVoiceTask(session);
5149             } finally {
5150                 Binder.restoreCallingIdentity(origId);
5151             }
5152         }
5153
5154     }
5155
5156     @Override
5157     public boolean releaseActivityInstance(IBinder token) {
5158         synchronized(this) {
5159             final long origId = Binder.clearCallingIdentity();
5160             try {
5161                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5162                 if (r == null) {
5163                     return false;
5164                 }
5165                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5166             } finally {
5167                 Binder.restoreCallingIdentity(origId);
5168             }
5169         }
5170     }
5171
5172     @Override
5173     public void releaseSomeActivities(IApplicationThread appInt) {
5174         synchronized(this) {
5175             final long origId = Binder.clearCallingIdentity();
5176             try {
5177                 ProcessRecord app = getRecordForAppLocked(appInt);
5178                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5179             } finally {
5180                 Binder.restoreCallingIdentity(origId);
5181             }
5182         }
5183     }
5184
5185     @Override
5186     public boolean willActivityBeVisible(IBinder token) {
5187         synchronized(this) {
5188             ActivityStack stack = ActivityRecord.getStackLocked(token);
5189             if (stack != null) {
5190                 return stack.willActivityBeVisibleLocked(token);
5191             }
5192             return false;
5193         }
5194     }
5195
5196     @Override
5197     public void overridePendingTransition(IBinder token, String packageName,
5198             int enterAnim, int exitAnim) {
5199         synchronized(this) {
5200             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5201             if (self == null) {
5202                 return;
5203             }
5204
5205             final long origId = Binder.clearCallingIdentity();
5206
5207             if (self.state == ActivityState.RESUMED
5208                     || self.state == ActivityState.PAUSING) {
5209                 mWindowManager.overridePendingAppTransition(packageName,
5210                         enterAnim, exitAnim, null);
5211             }
5212
5213             Binder.restoreCallingIdentity(origId);
5214         }
5215     }
5216
5217     /**
5218      * Main function for removing an existing process from the activity manager
5219      * as a result of that process going away.  Clears out all connections
5220      * to the process.
5221      */
5222     private final void handleAppDiedLocked(ProcessRecord app,
5223             boolean restarting, boolean allowRestart) {
5224         int pid = app.pid;
5225         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5226                 false /*replacingPid*/);
5227         if (!kept && !restarting) {
5228             removeLruProcessLocked(app);
5229             if (pid > 0) {
5230                 ProcessList.remove(pid);
5231             }
5232         }
5233
5234         if (mProfileProc == app) {
5235             clearProfilerLocked();
5236         }
5237
5238         // Remove this application's activities from active lists.
5239         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5240
5241         app.activities.clear();
5242
5243         if (app.instr != null) {
5244             Slog.w(TAG, "Crash of app " + app.processName
5245                   + " running instrumentation " + app.instr.mClass);
5246             Bundle info = new Bundle();
5247             info.putString("shortMsg", "Process crashed.");
5248             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5249         }
5250
5251         mWindowManager.deferSurfaceLayout();
5252         try {
5253             if (!restarting && hasVisibleActivities
5254                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5255                 // If there was nothing to resume, and we are not already restarting this process, but
5256                 // there is a visible activity that is hosted by the process...  then make sure all
5257                 // visible activities are running, taking care of restarting this process.
5258                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5259             }
5260         } finally {
5261             mWindowManager.continueSurfaceLayout();
5262         }
5263     }
5264
5265     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5266         final IBinder threadBinder = thread.asBinder();
5267         // Find the application record.
5268         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5269             final ProcessRecord rec = mLruProcesses.get(i);
5270             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5271                 return i;
5272             }
5273         }
5274         return -1;
5275     }
5276
5277     final ProcessRecord getRecordForAppLocked(
5278             IApplicationThread thread) {
5279         if (thread == null) {
5280             return null;
5281         }
5282
5283         int appIndex = getLRURecordIndexForAppLocked(thread);
5284         if (appIndex >= 0) {
5285             return mLruProcesses.get(appIndex);
5286         }
5287
5288         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5289         // double-check that.
5290         final IBinder threadBinder = thread.asBinder();
5291         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5292         for (int i = pmap.size()-1; i >= 0; i--) {
5293             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5294             for (int j = procs.size()-1; j >= 0; j--) {
5295                 final ProcessRecord proc = procs.valueAt(j);
5296                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5297                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5298                             + proc);
5299                     return proc;
5300                 }
5301             }
5302         }
5303
5304         return null;
5305     }
5306
5307     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5308         // If there are no longer any background processes running,
5309         // and the app that died was not running instrumentation,
5310         // then tell everyone we are now low on memory.
5311         boolean haveBg = false;
5312         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5313             ProcessRecord rec = mLruProcesses.get(i);
5314             if (rec.thread != null
5315                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5316                 haveBg = true;
5317                 break;
5318             }
5319         }
5320
5321         if (!haveBg) {
5322             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5323             if (doReport) {
5324                 long now = SystemClock.uptimeMillis();
5325                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5326                     doReport = false;
5327                 } else {
5328                     mLastMemUsageReportTime = now;
5329                 }
5330             }
5331             final ArrayList<ProcessMemInfo> memInfos
5332                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5333             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5334             long now = SystemClock.uptimeMillis();
5335             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5336                 ProcessRecord rec = mLruProcesses.get(i);
5337                 if (rec == dyingProc || rec.thread == null) {
5338                     continue;
5339                 }
5340                 if (doReport) {
5341                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5342                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5343                 }
5344                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5345                     // The low memory report is overriding any current
5346                     // state for a GC request.  Make sure to do
5347                     // heavy/important/visible/foreground processes first.
5348                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5349                         rec.lastRequestedGc = 0;
5350                     } else {
5351                         rec.lastRequestedGc = rec.lastLowMemory;
5352                     }
5353                     rec.reportLowMemory = true;
5354                     rec.lastLowMemory = now;
5355                     mProcessesToGc.remove(rec);
5356                     addProcessToGcListLocked(rec);
5357                 }
5358             }
5359             if (doReport) {
5360                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5361                 mHandler.sendMessage(msg);
5362             }
5363             scheduleAppGcsLocked();
5364         }
5365     }
5366
5367     final void appDiedLocked(ProcessRecord app) {
5368        appDiedLocked(app, app.pid, app.thread, false);
5369     }
5370
5371     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5372             boolean fromBinderDied) {
5373         // First check if this ProcessRecord is actually active for the pid.
5374         synchronized (mPidsSelfLocked) {
5375             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5376             if (curProc != app) {
5377                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5378                 return;
5379             }
5380         }
5381
5382         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5383         synchronized (stats) {
5384             stats.noteProcessDiedLocked(app.info.uid, pid);
5385         }
5386
5387         if (!app.killed) {
5388             if (!fromBinderDied) {
5389                 killProcessQuiet(pid);
5390             }
5391             killProcessGroup(app.uid, pid);
5392             app.killed = true;
5393         }
5394
5395         // Clean up already done if the process has been re-started.
5396         if (app.pid == pid && app.thread != null &&
5397                 app.thread.asBinder() == thread.asBinder()) {
5398             boolean doLowMem = app.instr == null;
5399             boolean doOomAdj = doLowMem;
5400             if (!app.killedByAm) {
5401                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5402                         + ProcessList.makeOomAdjString(app.setAdj)
5403                         + ProcessList.makeProcStateString(app.setProcState));
5404                 mAllowLowerMemLevel = true;
5405             } else {
5406                 // Note that we always want to do oom adj to update our state with the
5407                 // new number of procs.
5408                 mAllowLowerMemLevel = false;
5409                 doLowMem = false;
5410             }
5411             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5412                     app.setAdj, app.setProcState);
5413             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5414                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5415             handleAppDiedLocked(app, false, true);
5416
5417             if (doOomAdj) {
5418                 updateOomAdjLocked();
5419             }
5420             if (doLowMem) {
5421                 doLowMemReportIfNeededLocked(app);
5422             }
5423         } else if (app.pid != pid) {
5424             // A new process has already been started.
5425             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5426                     + ") has died and restarted (pid " + app.pid + ").");
5427             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5428         } else if (DEBUG_PROCESSES) {
5429             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5430                     + thread.asBinder());
5431         }
5432     }
5433
5434     /**
5435      * If a stack trace dump file is configured, dump process stack traces.
5436      * @param clearTraces causes the dump file to be erased prior to the new
5437      *    traces being written, if true; when false, the new traces will be
5438      *    appended to any existing file content.
5439      * @param firstPids of dalvik VM processes to dump stack traces for first
5440      * @param lastPids of dalvik VM processes to dump stack traces for last
5441      * @param nativePids optional list of native pids to dump stack crawls
5442      */
5443     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5444             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5445             ArrayList<Integer> nativePids) {
5446         ArrayList<Integer> extraPids = null;
5447
5448         // Measure CPU usage as soon as we're called in order to get a realistic sampling
5449         // of the top users at the time of the request.
5450         if (processCpuTracker != null) {
5451             processCpuTracker.init();
5452             try {
5453                 Thread.sleep(200);
5454             } catch (InterruptedException ignored) {
5455             }
5456
5457             processCpuTracker.update();
5458
5459             // We'll take the stack crawls of just the top apps using CPU.
5460             final int N = processCpuTracker.countWorkingStats();
5461             extraPids = new ArrayList<>();
5462             for (int i = 0; i < N && extraPids.size() < 5; i++) {
5463                 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5464                 if (lastPids.indexOfKey(stats.pid) >= 0) {
5465                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5466
5467                     extraPids.add(stats.pid);
5468                 } else if (DEBUG_ANR) {
5469                     Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5470                             + stats.pid);
5471                 }
5472             }
5473         }
5474
5475         boolean useTombstonedForJavaTraces = false;
5476         File tracesFile;
5477
5478         final String tracesDir = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5479         if (tracesDir.isEmpty()) {
5480             // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5481             // dumping scheme. All traces are written to a global trace file (usually
5482             // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5483             // the file if requested.
5484             //
5485             // This mode of operation will be removed in the near future.
5486
5487
5488             String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5489             if (globalTracesPath.isEmpty()) {
5490                 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5491                 return null;
5492             }
5493
5494             tracesFile = new File(globalTracesPath);
5495             try {
5496                 if (clearTraces && tracesFile.exists()) {
5497                     tracesFile.delete();
5498                 }
5499
5500                 tracesFile.createNewFile();
5501                 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5502             } catch (IOException e) {
5503                 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5504                 return null;
5505             }
5506         } else {
5507             // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5508             // Each set of ANR traces is written to a separate file and dumpstate will process
5509             // all such files and add them to a captured bug report if they're recent enough.
5510             //
5511             // NOTE: We should consider creating the file in native code atomically once we've
5512             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5513             // can be removed.
5514             try {
5515                 tracesFile = File.createTempFile("anr_", "", new File(tracesDir));
5516                 FileUtils.setPermissions(tracesFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5517             } catch (IOException ioe) {
5518                 Slog.w(TAG, "Unable to create ANR traces file: ", ioe);
5519                 return null;
5520             }
5521
5522             useTombstonedForJavaTraces = true;
5523         }
5524
5525         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5526                 useTombstonedForJavaTraces);
5527         return tracesFile;
5528     }
5529
5530     /**
5531      * Legacy code, do not use. Existing users will be deleted.
5532      *
5533      * @deprecated
5534      */
5535     @Deprecated
5536     public static class DumpStackFileObserver extends FileObserver {
5537         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5538         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5539
5540         private final String mTracesPath;
5541         private boolean mClosed;
5542
5543         public DumpStackFileObserver(String tracesPath) {
5544             super(tracesPath, FileObserver.CLOSE_WRITE);
5545             mTracesPath = tracesPath;
5546         }
5547
5548         @Override
5549         public synchronized void onEvent(int event, String path) {
5550             mClosed = true;
5551             notify();
5552         }
5553
5554         public long dumpWithTimeout(int pid, long timeout) {
5555             sendSignal(pid, SIGNAL_QUIT);
5556             final long start = SystemClock.elapsedRealtime();
5557
5558             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5559             synchronized (this) {
5560                 try {
5561                     wait(waitTime); // Wait for traces file to be closed.
5562                 } catch (InterruptedException e) {
5563                     Slog.wtf(TAG, e);
5564                 }
5565             }
5566
5567             // This avoids a corner case of passing a negative time to the native
5568             // trace in case we've already hit the overall timeout.
5569             final long timeWaited = SystemClock.elapsedRealtime() - start;
5570             if (timeWaited >= timeout) {
5571                 return timeWaited;
5572             }
5573
5574             if (!mClosed) {
5575                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5576                        ". Attempting native stack collection.");
5577
5578                 final long nativeDumpTimeoutMs = Math.min(
5579                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5580
5581                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5582                         (int) (nativeDumpTimeoutMs / 1000));
5583             }
5584
5585             final long end = SystemClock.elapsedRealtime();
5586             mClosed = false;
5587
5588             return (end - start);
5589         }
5590     }
5591
5592     /**
5593      * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5594      * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5595      * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5596      * attempting to obtain native traces in the case of a failure. Returns the total time spent
5597      * capturing traces.
5598      */
5599     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5600         final long timeStart = SystemClock.elapsedRealtime();
5601         if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5602             Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5603                     (NATIVE_DUMP_TIMEOUT_MS / 1000));
5604         }
5605
5606         return SystemClock.elapsedRealtime() - timeStart;
5607     }
5608
5609     private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5610             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5611             boolean useTombstonedForJavaTraces) {
5612
5613         // We don't need any sort of inotify based monitoring when we're dumping traces via
5614         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5615         // control of all writes to the file in question.
5616         final DumpStackFileObserver observer;
5617         if (useTombstonedForJavaTraces) {
5618             observer = null;
5619         } else {
5620             // Use a FileObserver to detect when traces finish writing.
5621             // The order of traces is considered important to maintain for legibility.
5622             observer = new DumpStackFileObserver(tracesFile);
5623         }
5624
5625         // We must complete all stack dumps within 20 seconds.
5626         long remainingTime = 20 * 1000;
5627         try {
5628             if (observer != null) {
5629                 observer.startWatching();
5630             }
5631
5632             // First collect all of the stacks of the most important pids.
5633             if (firstPids != null) {
5634                 int num = firstPids.size();
5635                 for (int i = 0; i < num; i++) {
5636                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5637                             + firstPids.get(i));
5638                     final long timeTaken;
5639                     if (useTombstonedForJavaTraces) {
5640                         timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5641                     } else {
5642                         timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5643                     }
5644
5645                     remainingTime -= timeTaken;
5646                     if (remainingTime <= 0) {
5647                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5648                             "); deadline exceeded.");
5649                         return;
5650                     }
5651
5652                     if (DEBUG_ANR) {
5653                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5654                     }
5655                 }
5656             }
5657
5658             // Next collect the stacks of the native pids
5659             if (nativePids != null) {
5660                 for (int pid : nativePids) {
5661                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5662                     final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5663
5664                     final long start = SystemClock.elapsedRealtime();
5665                     Debug.dumpNativeBacktraceToFileTimeout(
5666                             pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5667                     final long timeTaken = SystemClock.elapsedRealtime() - start;
5668
5669                     remainingTime -= timeTaken;
5670                     if (remainingTime <= 0) {
5671                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5672                             "); deadline exceeded.");
5673                         return;
5674                     }
5675
5676                     if (DEBUG_ANR) {
5677                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5678                     }
5679                 }
5680             }
5681
5682             // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5683             if (extraPids != null) {
5684                 for (int pid : extraPids) {
5685                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5686
5687                     final long timeTaken;
5688                     if (useTombstonedForJavaTraces) {
5689                         timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5690                     } else {
5691                         timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5692                     }
5693
5694                     remainingTime -= timeTaken;
5695                     if (remainingTime <= 0) {
5696                         Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5697                                 "); deadline exceeded.");
5698                         return;
5699                     }
5700
5701                     if (DEBUG_ANR) {
5702                         Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5703                     }
5704                 }
5705             }
5706         } finally {
5707             if (observer != null) {
5708                 observer.stopWatching();
5709             }
5710         }
5711     }
5712
5713     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5714         if (true || IS_USER_BUILD) {
5715             return;
5716         }
5717         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5718         if (tracesPath == null || tracesPath.length() == 0) {
5719             return;
5720         }
5721
5722         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5723         StrictMode.allowThreadDiskWrites();
5724         try {
5725             final File tracesFile = new File(tracesPath);
5726             final File tracesDir = tracesFile.getParentFile();
5727             final File tracesTmp = new File(tracesDir, "__tmp__");
5728             try {
5729                 if (tracesFile.exists()) {
5730                     tracesTmp.delete();
5731                     tracesFile.renameTo(tracesTmp);
5732                 }
5733                 StringBuilder sb = new StringBuilder();
5734                 Time tobj = new Time();
5735                 tobj.set(System.currentTimeMillis());
5736                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5737                 sb.append(": ");
5738                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5739                 sb.append(" since ");
5740                 sb.append(msg);
5741                 FileOutputStream fos = new FileOutputStream(tracesFile);
5742                 fos.write(sb.toString().getBytes());
5743                 if (app == null) {
5744                     fos.write("\n*** No application process!".getBytes());
5745                 }
5746                 fos.close();
5747                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5748             } catch (IOException e) {
5749                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5750                 return;
5751             }
5752
5753             if (app != null) {
5754                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5755                 firstPids.add(app.pid);
5756                 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5757             }
5758
5759             File lastTracesFile = null;
5760             File curTracesFile = null;
5761             for (int i=9; i>=0; i--) {
5762                 String name = String.format(Locale.US, "slow%02d.txt", i);
5763                 curTracesFile = new File(tracesDir, name);
5764                 if (curTracesFile.exists()) {
5765                     if (lastTracesFile != null) {
5766                         curTracesFile.renameTo(lastTracesFile);
5767                     } else {
5768                         curTracesFile.delete();
5769                     }
5770                 }
5771                 lastTracesFile = curTracesFile;
5772             }
5773             tracesFile.renameTo(curTracesFile);
5774             if (tracesTmp.exists()) {
5775                 tracesTmp.renameTo(tracesFile);
5776             }
5777         } finally {
5778             StrictMode.setThreadPolicy(oldPolicy);
5779         }
5780     }
5781
5782     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5783         if (!mLaunchWarningShown) {
5784             mLaunchWarningShown = true;
5785             mUiHandler.post(new Runnable() {
5786                 @Override
5787                 public void run() {
5788                     synchronized (ActivityManagerService.this) {
5789                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5790                         d.show();
5791                         mUiHandler.postDelayed(new Runnable() {
5792                             @Override
5793                             public void run() {
5794                                 synchronized (ActivityManagerService.this) {
5795                                     d.dismiss();
5796                                     mLaunchWarningShown = false;
5797                                 }
5798                             }
5799                         }, 4000);
5800                     }
5801                 }
5802             });
5803         }
5804     }
5805
5806     @Override
5807     public boolean clearApplicationUserData(final String packageName,
5808             final IPackageDataObserver observer, int userId) {
5809         enforceNotIsolatedCaller("clearApplicationUserData");
5810         int uid = Binder.getCallingUid();
5811         int pid = Binder.getCallingPid();
5812         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5813                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5814
5815
5816         long callingId = Binder.clearCallingIdentity();
5817         try {
5818             IPackageManager pm = AppGlobals.getPackageManager();
5819             int pkgUid = -1;
5820             synchronized(this) {
5821                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5822                         userId, packageName)) {
5823                     throw new SecurityException(
5824                             "Cannot clear data for a protected package: " + packageName);
5825                 }
5826
5827                 try {
5828                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5829                 } catch (RemoteException e) {
5830                 }
5831                 if (pkgUid == -1) {
5832                     Slog.w(TAG, "Invalid packageName: " + packageName);
5833                     if (observer != null) {
5834                         try {
5835                             observer.onRemoveCompleted(packageName, false);
5836                         } catch (RemoteException e) {
5837                             Slog.i(TAG, "Observer no longer exists.");
5838                         }
5839                     }
5840                     return false;
5841                 }
5842                 if (uid == pkgUid || checkComponentPermission(
5843                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5844                         pid, uid, -1, true)
5845                         == PackageManager.PERMISSION_GRANTED) {
5846                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5847                 } else {
5848                     throw new SecurityException("PID " + pid + " does not have permission "
5849                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5850                                     + " of package " + packageName);
5851                 }
5852
5853                 // Remove all tasks match the cleared application package and user
5854                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5855                     final TaskRecord tr = mRecentTasks.get(i);
5856                     final String taskPackageName =
5857                             tr.getBaseIntent().getComponent().getPackageName();
5858                     if (tr.userId != userId) continue;
5859                     if (!taskPackageName.equals(packageName)) continue;
5860                     mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5861                 }
5862             }
5863
5864             final int pkgUidF = pkgUid;
5865             final int userIdF = userId;
5866             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5867                 @Override
5868                 public void onRemoveCompleted(String packageName, boolean succeeded)
5869                         throws RemoteException {
5870                     synchronized (ActivityManagerService.this) {
5871                         finishForceStopPackageLocked(packageName, pkgUidF);
5872                     }
5873
5874                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5875                             Uri.fromParts("package", packageName, null));
5876                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5877                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5878                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5879                     broadcastIntentInPackage("android", SYSTEM_UID, intent,
5880                             null, null, 0, null, null, null, null, false, false, userIdF);
5881
5882                     if (observer != null) {
5883                         observer.onRemoveCompleted(packageName, succeeded);
5884                     }
5885                 }
5886             };
5887
5888             try {
5889                 // Clear application user data
5890                 pm.clearApplicationUserData(packageName, localObserver, userId);
5891
5892                 synchronized(this) {
5893                     // Remove all permissions granted from/to this package
5894                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5895                 }
5896
5897                 // Reset notification settings.
5898                 INotificationManager inm = NotificationManager.getService();
5899                 inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5900             } catch (RemoteException e) {
5901             }
5902         } finally {
5903             Binder.restoreCallingIdentity(callingId);
5904         }
5905         return true;
5906     }
5907
5908     @Override
5909     public void killBackgroundProcesses(final String packageName, int userId) {
5910         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5911                 != PackageManager.PERMISSION_GRANTED &&
5912                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5913                         != PackageManager.PERMISSION_GRANTED) {
5914             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5915                     + Binder.getCallingPid()
5916                     + ", uid=" + Binder.getCallingUid()
5917                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5918             Slog.w(TAG, msg);
5919             throw new SecurityException(msg);
5920         }
5921
5922         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5923                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5924         long callingId = Binder.clearCallingIdentity();
5925         try {
5926             IPackageManager pm = AppGlobals.getPackageManager();
5927             synchronized(this) {
5928                 int appId = -1;
5929                 try {
5930                     appId = UserHandle.getAppId(
5931                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5932                 } catch (RemoteException e) {
5933                 }
5934                 if (appId == -1) {
5935                     Slog.w(TAG, "Invalid packageName: " + packageName);
5936                     return;
5937                 }
5938                 killPackageProcessesLocked(packageName, appId, userId,
5939                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5940             }
5941         } finally {
5942             Binder.restoreCallingIdentity(callingId);
5943         }
5944     }
5945
5946     @Override
5947     public void killAllBackgroundProcesses() {
5948         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5949                 != PackageManager.PERMISSION_GRANTED) {
5950             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5951                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5952                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5953             Slog.w(TAG, msg);
5954             throw new SecurityException(msg);
5955         }
5956
5957         final long callingId = Binder.clearCallingIdentity();
5958         try {
5959             synchronized (this) {
5960                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5961                 final int NP = mProcessNames.getMap().size();
5962                 for (int ip = 0; ip < NP; ip++) {
5963                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5964                     final int NA = apps.size();
5965                     for (int ia = 0; ia < NA; ia++) {
5966                         final ProcessRecord app = apps.valueAt(ia);
5967                         if (app.persistent) {
5968                             // We don't kill persistent processes.
5969                             continue;
5970                         }
5971                         if (app.removed) {
5972                             procs.add(app);
5973                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5974                             app.removed = true;
5975                             procs.add(app);
5976                         }
5977                     }
5978                 }
5979
5980                 final int N = procs.size();
5981                 for (int i = 0; i < N; i++) {
5982                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5983                 }
5984
5985                 mAllowLowerMemLevel = true;
5986
5987                 updateOomAdjLocked();
5988                 doLowMemReportIfNeededLocked(null);
5989             }
5990         } finally {
5991             Binder.restoreCallingIdentity(callingId);
5992         }
5993     }
5994
5995     /**
5996      * Kills all background processes, except those matching any of the
5997      * specified properties.
5998      *
5999      * @param minTargetSdk the target SDK version at or above which to preserve
6000      *                     processes, or {@code -1} to ignore the target SDK
6001      * @param maxProcState the process state at or below which to preserve
6002      *                     processes, or {@code -1} to ignore the process state
6003      */
6004     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6005         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6006                 != PackageManager.PERMISSION_GRANTED) {
6007             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6008                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6009                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6010             Slog.w(TAG, msg);
6011             throw new SecurityException(msg);
6012         }
6013
6014         final long callingId = Binder.clearCallingIdentity();
6015         try {
6016             synchronized (this) {
6017                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6018                 final int NP = mProcessNames.getMap().size();
6019                 for (int ip = 0; ip < NP; ip++) {
6020                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6021                     final int NA = apps.size();
6022                     for (int ia = 0; ia < NA; ia++) {
6023                         final ProcessRecord app = apps.valueAt(ia);
6024                         if (app.removed) {
6025                             procs.add(app);
6026                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6027                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6028                             app.removed = true;
6029                             procs.add(app);
6030                         }
6031                     }
6032                 }
6033
6034                 final int N = procs.size();
6035                 for (int i = 0; i < N; i++) {
6036                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
6037                 }
6038             }
6039         } finally {
6040             Binder.restoreCallingIdentity(callingId);
6041         }
6042     }
6043
6044     @Override
6045     public void forceStopPackage(final String packageName, int userId) {
6046         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6047                 != PackageManager.PERMISSION_GRANTED) {
6048             String msg = "Permission Denial: forceStopPackage() from pid="
6049                     + Binder.getCallingPid()
6050                     + ", uid=" + Binder.getCallingUid()
6051                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6052             Slog.w(TAG, msg);
6053             throw new SecurityException(msg);
6054         }
6055         final int callingPid = Binder.getCallingPid();
6056         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6057                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6058         long callingId = Binder.clearCallingIdentity();
6059         try {
6060             IPackageManager pm = AppGlobals.getPackageManager();
6061             synchronized(this) {
6062                 int[] users = userId == UserHandle.USER_ALL
6063                         ? mUserController.getUsers() : new int[] { userId };
6064                 for (int user : users) {
6065                     int pkgUid = -1;
6066                     try {
6067                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6068                                 user);
6069                     } catch (RemoteException e) {
6070                     }
6071                     if (pkgUid == -1) {
6072                         Slog.w(TAG, "Invalid packageName: " + packageName);
6073                         continue;
6074                     }
6075                     try {
6076                         pm.setPackageStoppedState(packageName, true, user);
6077                     } catch (RemoteException e) {
6078                     } catch (IllegalArgumentException e) {
6079                         Slog.w(TAG, "Failed trying to unstop package "
6080                                 + packageName + ": " + e);
6081                     }
6082                     if (mUserController.isUserRunningLocked(user, 0)) {
6083                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6084                         finishForceStopPackageLocked(packageName, pkgUid);
6085                     }
6086                 }
6087             }
6088         } finally {
6089             Binder.restoreCallingIdentity(callingId);
6090         }
6091     }
6092
6093     @Override
6094     public void addPackageDependency(String packageName) {
6095         synchronized (this) {
6096             int callingPid = Binder.getCallingPid();
6097             if (callingPid == myPid()) {
6098                 //  Yeah, um, no.
6099                 return;
6100             }
6101             ProcessRecord proc;
6102             synchronized (mPidsSelfLocked) {
6103                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6104             }
6105             if (proc != null) {
6106                 if (proc.pkgDeps == null) {
6107                     proc.pkgDeps = new ArraySet<String>(1);
6108                 }
6109                 proc.pkgDeps.add(packageName);
6110             }
6111         }
6112     }
6113
6114     /*
6115      * The pkg name and app id have to be specified.
6116      */
6117     @Override
6118     public void killApplication(String pkg, int appId, int userId, String reason) {
6119         if (pkg == null) {
6120             return;
6121         }
6122         // Make sure the uid is valid.
6123         if (appId < 0) {
6124             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6125             return;
6126         }
6127         int callerUid = Binder.getCallingUid();
6128         // Only the system server can kill an application
6129         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6130             // Post an aysnc message to kill the application
6131             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6132             msg.arg1 = appId;
6133             msg.arg2 = userId;
6134             Bundle bundle = new Bundle();
6135             bundle.putString("pkg", pkg);
6136             bundle.putString("reason", reason);
6137             msg.obj = bundle;
6138             mHandler.sendMessage(msg);
6139         } else {
6140             throw new SecurityException(callerUid + " cannot kill pkg: " +
6141                     pkg);
6142         }
6143     }
6144
6145     @Override
6146     public void closeSystemDialogs(String reason) {
6147         enforceNotIsolatedCaller("closeSystemDialogs");
6148
6149         final int pid = Binder.getCallingPid();
6150         final int uid = Binder.getCallingUid();
6151         final long origId = Binder.clearCallingIdentity();
6152         try {
6153             synchronized (this) {
6154                 // Only allow this from foreground processes, so that background
6155                 // applications can't abuse it to prevent system UI from being shown.
6156                 if (uid >= FIRST_APPLICATION_UID) {
6157                     ProcessRecord proc;
6158                     synchronized (mPidsSelfLocked) {
6159                         proc = mPidsSelfLocked.get(pid);
6160                     }
6161                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6162                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6163                                 + " from background process " + proc);
6164                         return;
6165                     }
6166                 }
6167                 closeSystemDialogsLocked(reason);
6168             }
6169         } finally {
6170             Binder.restoreCallingIdentity(origId);
6171         }
6172     }
6173
6174     void closeSystemDialogsLocked(String reason) {
6175         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6176         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6177                 | Intent.FLAG_RECEIVER_FOREGROUND);
6178         if (reason != null) {
6179             intent.putExtra("reason", reason);
6180         }
6181         mWindowManager.closeSystemDialogs(reason);
6182
6183         mStackSupervisor.closeSystemDialogsLocked();
6184
6185         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6186                 AppOpsManager.OP_NONE, null, false, false,
6187                 -1, SYSTEM_UID, UserHandle.USER_ALL);
6188     }
6189
6190     @Override
6191     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6192         enforceNotIsolatedCaller("getProcessMemoryInfo");
6193         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6194         for (int i=pids.length-1; i>=0; i--) {
6195             ProcessRecord proc;
6196             int oomAdj;
6197             synchronized (this) {
6198                 synchronized (mPidsSelfLocked) {
6199                     proc = mPidsSelfLocked.get(pids[i]);
6200                     oomAdj = proc != null ? proc.setAdj : 0;
6201                 }
6202             }
6203             infos[i] = new Debug.MemoryInfo();
6204             Debug.getMemoryInfo(pids[i], infos[i]);
6205             if (proc != null) {
6206                 synchronized (this) {
6207                     if (proc.thread != null && proc.setAdj == oomAdj) {
6208                         // Record this for posterity if the process has been stable.
6209                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6210                                 infos[i].getTotalUss(), false, proc.pkgList);
6211                     }
6212                 }
6213             }
6214         }
6215         return infos;
6216     }
6217
6218     @Override
6219     public long[] getProcessPss(int[] pids) {
6220         enforceNotIsolatedCaller("getProcessPss");
6221         long[] pss = new long[pids.length];
6222         for (int i=pids.length-1; i>=0; i--) {
6223             ProcessRecord proc;
6224             int oomAdj;
6225             synchronized (this) {
6226                 synchronized (mPidsSelfLocked) {
6227                     proc = mPidsSelfLocked.get(pids[i]);
6228                     oomAdj = proc != null ? proc.setAdj : 0;
6229                 }
6230             }
6231             long[] tmpUss = new long[1];
6232             pss[i] = Debug.getPss(pids[i], tmpUss, null);
6233             if (proc != null) {
6234                 synchronized (this) {
6235                     if (proc.thread != null && proc.setAdj == oomAdj) {
6236                         // Record this for posterity if the process has been stable.
6237                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6238                     }
6239                 }
6240             }
6241         }
6242         return pss;
6243     }
6244
6245     @Override
6246     public void killApplicationProcess(String processName, int uid) {
6247         if (processName == null) {
6248             return;
6249         }
6250
6251         int callerUid = Binder.getCallingUid();
6252         // Only the system server can kill an application
6253         if (callerUid == SYSTEM_UID) {
6254             synchronized (this) {
6255                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6256                 if (app != null && app.thread != null) {
6257                     try {
6258                         app.thread.scheduleSuicide();
6259                     } catch (RemoteException e) {
6260                         // If the other end already died, then our work here is done.
6261                     }
6262                 } else {
6263                     Slog.w(TAG, "Process/uid not found attempting kill of "
6264                             + processName + " / " + uid);
6265                 }
6266             }
6267         } else {
6268             throw new SecurityException(callerUid + " cannot kill app process: " +
6269                     processName);
6270         }
6271     }
6272
6273     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6274         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6275                 false, true, false, false, UserHandle.getUserId(uid), reason);
6276     }
6277
6278     private void finishForceStopPackageLocked(final String packageName, int uid) {
6279         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6280                 Uri.fromParts("package", packageName, null));
6281         if (!mProcessesReady) {
6282             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6283                     | Intent.FLAG_RECEIVER_FOREGROUND);
6284         }
6285         intent.putExtra(Intent.EXTRA_UID, uid);
6286         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6287         broadcastIntentLocked(null, null, intent,
6288                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6289                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6290     }
6291
6292
6293     private final boolean killPackageProcessesLocked(String packageName, int appId,
6294             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6295             boolean doit, boolean evenPersistent, String reason) {
6296         ArrayList<ProcessRecord> procs = new ArrayList<>();
6297
6298         // Remove all processes this package may have touched: all with the
6299         // same UID (except for the system or root user), and all whose name
6300         // matches the package name.
6301         final int NP = mProcessNames.getMap().size();
6302         for (int ip=0; ip<NP; ip++) {
6303             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6304             final int NA = apps.size();
6305             for (int ia=0; ia<NA; ia++) {
6306                 ProcessRecord app = apps.valueAt(ia);
6307                 if (app.persistent && !evenPersistent) {
6308                     // we don't kill persistent processes
6309                     continue;
6310                 }
6311                 if (app.removed) {
6312                     if (doit) {
6313                         procs.add(app);
6314                     }
6315                     continue;
6316                 }
6317
6318                 // Skip process if it doesn't meet our oom adj requirement.
6319                 if (app.setAdj < minOomAdj) {
6320                     continue;
6321                 }
6322
6323                 // If no package is specified, we call all processes under the
6324                 // give user id.
6325                 if (packageName == null) {
6326                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6327                         continue;
6328                     }
6329                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6330                         continue;
6331                     }
6332                 // Package has been specified, we want to hit all processes
6333                 // that match it.  We need to qualify this by the processes
6334                 // that are running under the specified app and user ID.
6335                 } else {
6336                     final boolean isDep = app.pkgDeps != null
6337                             && app.pkgDeps.contains(packageName);
6338                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6339                         continue;
6340                     }
6341                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6342                         continue;
6343                     }
6344                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6345                         continue;
6346                     }
6347                 }
6348
6349                 // Process has passed all conditions, kill it!
6350                 if (!doit) {
6351                     return true;
6352                 }
6353                 app.removed = true;
6354                 procs.add(app);
6355             }
6356         }
6357
6358         int N = procs.size();
6359         for (int i=0; i<N; i++) {
6360             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6361         }
6362         updateOomAdjLocked();
6363         return N > 0;
6364     }
6365
6366     private void cleanupDisabledPackageComponentsLocked(
6367             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6368
6369         Set<String> disabledClasses = null;
6370         boolean packageDisabled = false;
6371         IPackageManager pm = AppGlobals.getPackageManager();
6372
6373         if (changedClasses == null) {
6374             // Nothing changed...
6375             return;
6376         }
6377
6378         // Determine enable/disable state of the package and its components.
6379         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6380         for (int i = changedClasses.length - 1; i >= 0; i--) {
6381             final String changedClass = changedClasses[i];
6382
6383             if (changedClass.equals(packageName)) {
6384                 try {
6385                     // Entire package setting changed
6386                     enabled = pm.getApplicationEnabledSetting(packageName,
6387                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6388                 } catch (Exception e) {
6389                     // No such package/component; probably racing with uninstall.  In any
6390                     // event it means we have nothing further to do here.
6391                     return;
6392                 }
6393                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6394                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6395                 if (packageDisabled) {
6396                     // Entire package is disabled.
6397                     // No need to continue to check component states.
6398                     disabledClasses = null;
6399                     break;
6400                 }
6401             } else {
6402                 try {
6403                     enabled = pm.getComponentEnabledSetting(
6404                             new ComponentName(packageName, changedClass),
6405                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6406                 } catch (Exception e) {
6407                     // As above, probably racing with uninstall.
6408                     return;
6409                 }
6410                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6411                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6412                     if (disabledClasses == null) {
6413                         disabledClasses = new ArraySet<>(changedClasses.length);
6414                     }
6415                     disabledClasses.add(changedClass);
6416                 }
6417             }
6418         }
6419
6420         if (!packageDisabled && disabledClasses == null) {
6421             // Nothing to do here...
6422             return;
6423         }
6424
6425         // Clean-up disabled activities.
6426         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6427                 packageName, disabledClasses, true, false, userId) && mBooted) {
6428             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6429             mStackSupervisor.scheduleIdleLocked();
6430         }
6431
6432         // Clean-up disabled tasks
6433         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6434
6435         // Clean-up disabled services.
6436         mServices.bringDownDisabledPackageServicesLocked(
6437                 packageName, disabledClasses, userId, false, killProcess, true);
6438
6439         // Clean-up disabled providers.
6440         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6441         mProviderMap.collectPackageProvidersLocked(
6442                 packageName, disabledClasses, true, false, userId, providers);
6443         for (int i = providers.size() - 1; i >= 0; i--) {
6444             removeDyingProviderLocked(null, providers.get(i), true);
6445         }
6446
6447         // Clean-up disabled broadcast receivers.
6448         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6449             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6450                     packageName, disabledClasses, userId, true);
6451         }
6452
6453     }
6454
6455     final boolean clearBroadcastQueueForUserLocked(int userId) {
6456         boolean didSomething = false;
6457         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6458             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6459                     null, null, userId, true);
6460         }
6461         return didSomething;
6462     }
6463
6464     final boolean forceStopPackageLocked(String packageName, int appId,
6465             boolean callerWillRestart, boolean purgeCache, boolean doit,
6466             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6467         int i;
6468
6469         if (userId == UserHandle.USER_ALL && packageName == null) {
6470             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6471         }
6472
6473         if (appId < 0 && packageName != null) {
6474             try {
6475                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6476                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6477             } catch (RemoteException e) {
6478             }
6479         }
6480
6481         if (doit) {
6482             if (packageName != null) {
6483                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6484                         + " user=" + userId + ": " + reason);
6485             } else {
6486                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6487             }
6488
6489             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6490         }
6491
6492         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6493                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6494                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6495
6496         didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6497
6498         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6499                 packageName, null, doit, evenPersistent, userId)) {
6500             if (!doit) {
6501                 return true;
6502             }
6503             didSomething = true;
6504         }
6505
6506         if (mServices.bringDownDisabledPackageServicesLocked(
6507                 packageName, null, userId, evenPersistent, true, doit)) {
6508             if (!doit) {
6509                 return true;
6510             }
6511             didSomething = true;
6512         }
6513
6514         if (packageName == null) {
6515             // Remove all sticky broadcasts from this user.
6516             mStickyBroadcasts.remove(userId);
6517         }
6518
6519         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6520         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6521                 userId, providers)) {
6522             if (!doit) {
6523                 return true;
6524             }
6525             didSomething = true;
6526         }
6527         for (i = providers.size() - 1; i >= 0; i--) {
6528             removeDyingProviderLocked(null, providers.get(i), true);
6529         }
6530
6531         // Remove transient permissions granted from/to this package/user
6532         removeUriPermissionsForPackageLocked(packageName, userId, false);
6533
6534         if (doit) {
6535             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6536                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6537                         packageName, null, userId, doit);
6538             }
6539         }
6540
6541         if (packageName == null || uninstalling) {
6542             // Remove pending intents.  For now we only do this when force
6543             // stopping users, because we have some problems when doing this
6544             // for packages -- app widgets are not currently cleaned up for
6545             // such packages, so they can be left with bad pending intents.
6546             if (mIntentSenderRecords.size() > 0) {
6547                 Iterator<WeakReference<PendingIntentRecord>> it
6548                         = mIntentSenderRecords.values().iterator();
6549                 while (it.hasNext()) {
6550                     WeakReference<PendingIntentRecord> wpir = it.next();
6551                     if (wpir == null) {
6552                         it.remove();
6553                         continue;
6554                     }
6555                     PendingIntentRecord pir = wpir.get();
6556                     if (pir == null) {
6557                         it.remove();
6558                         continue;
6559                     }
6560                     if (packageName == null) {
6561                         // Stopping user, remove all objects for the user.
6562                         if (pir.key.userId != userId) {
6563                             // Not the same user, skip it.
6564                             continue;
6565                         }
6566                     } else {
6567                         if (UserHandle.getAppId(pir.uid) != appId) {
6568                             // Different app id, skip it.
6569                             continue;
6570                         }
6571                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6572                             // Different user, skip it.
6573                             continue;
6574                         }
6575                         if (!pir.key.packageName.equals(packageName)) {
6576                             // Different package, skip it.
6577                             continue;
6578                         }
6579                     }
6580                     if (!doit) {
6581                         return true;
6582                     }
6583                     didSomething = true;
6584                     it.remove();
6585                     makeIntentSenderCanceledLocked(pir);
6586                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6587                         pir.key.activity.pendingResults.remove(pir.ref);
6588                     }
6589                 }
6590             }
6591         }
6592
6593         if (doit) {
6594             if (purgeCache && packageName != null) {
6595                 AttributeCache ac = AttributeCache.instance();
6596                 if (ac != null) {
6597                     ac.removePackage(packageName);
6598                 }
6599             }
6600             if (mBooted) {
6601                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6602                 mStackSupervisor.scheduleIdleLocked();
6603             }
6604         }
6605
6606         return didSomething;
6607     }
6608
6609     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6610         return removeProcessNameLocked(name, uid, null);
6611     }
6612
6613     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6614             final ProcessRecord expecting) {
6615         ProcessRecord old = mProcessNames.get(name, uid);
6616         // Only actually remove when the currently recorded value matches the
6617         // record that we expected; if it doesn't match then we raced with a
6618         // newly created process and we don't want to destroy the new one.
6619         if ((expecting == null) || (old == expecting)) {
6620             mProcessNames.remove(name, uid);
6621         }
6622         if (old != null && old.uidRecord != null) {
6623             old.uidRecord.numProcs--;
6624             if (old.uidRecord.numProcs == 0) {
6625                 // No more processes using this uid, tell clients it is gone.
6626                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6627                         "No more processes in " + old.uidRecord);
6628                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6629                 EventLogTags.writeAmUidStopped(uid);
6630                 mActiveUids.remove(uid);
6631                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6632             }
6633             old.uidRecord = null;
6634         }
6635         mIsolatedProcesses.remove(uid);
6636         return old;
6637     }
6638
6639     private final void addProcessNameLocked(ProcessRecord proc) {
6640         // We shouldn't already have a process under this name, but just in case we
6641         // need to clean up whatever may be there now.
6642         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6643         if (old == proc && proc.persistent) {
6644             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6645             Slog.w(TAG, "Re-adding persistent process " + proc);
6646         } else if (old != null) {
6647             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6648         }
6649         UidRecord uidRec = mActiveUids.get(proc.uid);
6650         if (uidRec == null) {
6651             uidRec = new UidRecord(proc.uid);
6652             // This is the first appearance of the uid, report it now!
6653             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6654                     "Creating new process uid: " + uidRec);
6655             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6656                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6657                 uidRec.setWhitelist = uidRec.curWhitelist = true;
6658             }
6659             uidRec.updateHasInternetPermission();
6660             mActiveUids.put(proc.uid, uidRec);
6661             EventLogTags.writeAmUidRunning(uidRec.uid);
6662             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6663             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6664         }
6665         proc.uidRecord = uidRec;
6666
6667         // Reset render thread tid if it was already set, so new process can set it again.
6668         proc.renderThreadTid = 0;
6669         uidRec.numProcs++;
6670         mProcessNames.put(proc.processName, proc.uid, proc);
6671         if (proc.isolated) {
6672             mIsolatedProcesses.put(proc.uid, proc);
6673         }
6674     }
6675
6676     boolean removeProcessLocked(ProcessRecord app,
6677             boolean callerWillRestart, boolean allowRestart, String reason) {
6678         final String name = app.processName;
6679         final int uid = app.uid;
6680         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6681             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6682
6683         ProcessRecord old = mProcessNames.get(name, uid);
6684         if (old != app) {
6685             // This process is no longer active, so nothing to do.
6686             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6687             return false;
6688         }
6689         removeProcessNameLocked(name, uid);
6690         if (mHeavyWeightProcess == app) {
6691             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6692                     mHeavyWeightProcess.userId, 0));
6693             mHeavyWeightProcess = null;
6694         }
6695         boolean needRestart = false;
6696         if (app.pid > 0 && app.pid != MY_PID) {
6697             int pid = app.pid;
6698             synchronized (mPidsSelfLocked) {
6699                 mPidsSelfLocked.remove(pid);
6700                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6701             }
6702             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6703             if (app.isolated) {
6704                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6705                 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6706             }
6707             boolean willRestart = false;
6708             if (app.persistent && !app.isolated) {
6709                 if (!callerWillRestart) {
6710                     willRestart = true;
6711                 } else {
6712                     needRestart = true;
6713                 }
6714             }
6715             app.kill(reason, true);
6716             handleAppDiedLocked(app, willRestart, allowRestart);
6717             if (willRestart) {
6718                 removeLruProcessLocked(app);
6719                 addAppLocked(app.info, null, false, null /* ABI override */);
6720             }
6721         } else {
6722             mRemovedProcesses.add(app);
6723         }
6724
6725         return needRestart;
6726     }
6727
6728     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6729         cleanupAppInLaunchingProvidersLocked(app, true);
6730         removeProcessLocked(app, false, true, "timeout publishing content providers");
6731     }
6732
6733     private final void processStartTimedOutLocked(ProcessRecord app) {
6734         final int pid = app.pid;
6735         boolean gone = false;
6736         synchronized (mPidsSelfLocked) {
6737             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6738             if (knownApp != null && knownApp.thread == null) {
6739                 mPidsSelfLocked.remove(pid);
6740                 gone = true;
6741             }
6742         }
6743
6744         if (gone) {
6745             Slog.w(TAG, "Process " + app + " failed to attach");
6746             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6747                     pid, app.uid, app.processName);
6748             removeProcessNameLocked(app.processName, app.uid);
6749             if (mHeavyWeightProcess == app) {
6750                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6751                         mHeavyWeightProcess.userId, 0));
6752                 mHeavyWeightProcess = null;
6753             }
6754             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6755             if (app.isolated) {
6756                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6757             }
6758             // Take care of any launching providers waiting for this process.
6759             cleanupAppInLaunchingProvidersLocked(app, true);
6760             // Take care of any services that are waiting for the process.
6761             mServices.processStartTimedOutLocked(app);
6762             app.kill("start timeout", true);
6763             removeLruProcessLocked(app);
6764             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6765                 Slog.w(TAG, "Unattached app died before backup, skipping");
6766                 mHandler.post(new Runnable() {
6767                 @Override
6768                     public void run(){
6769                         try {
6770                             IBackupManager bm = IBackupManager.Stub.asInterface(
6771                                     ServiceManager.getService(Context.BACKUP_SERVICE));
6772                             bm.agentDisconnected(app.info.packageName);
6773                         } catch (RemoteException e) {
6774                             // Can't happen; the backup manager is local
6775                         }
6776                     }
6777                 });
6778             }
6779             if (isPendingBroadcastProcessLocked(pid)) {
6780                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6781                 skipPendingBroadcastLocked(pid);
6782             }
6783         } else {
6784             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6785         }
6786     }
6787
6788     private final boolean attachApplicationLocked(IApplicationThread thread,
6789             int pid) {
6790
6791         // Find the application record that is being attached...  either via
6792         // the pid if we are running in multiple processes, or just pull the
6793         // next app record if we are emulating process with anonymous threads.
6794         ProcessRecord app;
6795         long startTime = SystemClock.uptimeMillis();
6796         if (pid != MY_PID && pid >= 0) {
6797             synchronized (mPidsSelfLocked) {
6798                 app = mPidsSelfLocked.get(pid);
6799             }
6800         } else {
6801             app = null;
6802         }
6803
6804         if (app == null) {
6805             Slog.w(TAG, "No pending application record for pid " + pid
6806                     + " (IApplicationThread " + thread + "); dropping process");
6807             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6808             if (pid > 0 && pid != MY_PID) {
6809                 killProcessQuiet(pid);
6810                 //TODO: killProcessGroup(app.info.uid, pid);
6811             } else {
6812                 try {
6813                     thread.scheduleExit();
6814                 } catch (Exception e) {
6815                     // Ignore exceptions.
6816                 }
6817             }
6818             return false;
6819         }
6820
6821         // If this application record is still attached to a previous
6822         // process, clean it up now.
6823         if (app.thread != null) {
6824             handleAppDiedLocked(app, true, true);
6825         }
6826
6827         // Tell the process all about itself.
6828
6829         if (DEBUG_ALL) Slog.v(
6830                 TAG, "Binding process pid " + pid + " to record " + app);
6831
6832         final String processName = app.processName;
6833         try {
6834             AppDeathRecipient adr = new AppDeathRecipient(
6835                     app, pid, thread);
6836             thread.asBinder().linkToDeath(adr, 0);
6837             app.deathRecipient = adr;
6838         } catch (RemoteException e) {
6839             app.resetPackageList(mProcessStats);
6840             startProcessLocked(app, "link fail", processName);
6841             return false;
6842         }
6843
6844         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6845
6846         app.makeActive(thread, mProcessStats);
6847         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6848         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6849         app.forcingToImportant = null;
6850         updateProcessForegroundLocked(app, false, false);
6851         app.hasShownUi = false;
6852         app.debugging = false;
6853         app.cached = false;
6854         app.killedByAm = false;
6855         app.killed = false;
6856
6857
6858         // We carefully use the same state that PackageManager uses for
6859         // filtering, since we use this flag to decide if we need to install
6860         // providers when user is unlocked later
6861         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6862
6863         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6864
6865         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6866         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6867
6868         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6869             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6870             msg.obj = app;
6871             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6872         }
6873
6874         checkTime(startTime, "attachApplicationLocked: before bindApplication");
6875
6876         if (!normalMode) {
6877             Slog.i(TAG, "Launching preboot mode app: " + app);
6878         }
6879
6880         if (DEBUG_ALL) Slog.v(
6881             TAG, "New app record " + app
6882             + " thread=" + thread.asBinder() + " pid=" + pid);
6883         try {
6884             int testMode = ApplicationThreadConstants.DEBUG_OFF;
6885             if (mDebugApp != null && mDebugApp.equals(processName)) {
6886                 testMode = mWaitForDebugger
6887                     ? ApplicationThreadConstants.DEBUG_WAIT
6888                     : ApplicationThreadConstants.DEBUG_ON;
6889                 app.debugging = true;
6890                 if (mDebugTransient) {
6891                     mDebugApp = mOrigDebugApp;
6892                     mWaitForDebugger = mOrigWaitForDebugger;
6893                 }
6894             }
6895             String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6896             ParcelFileDescriptor profileFd = null;
6897             int samplingInterval = 0;
6898             boolean profileAutoStop = false;
6899             boolean profileStreamingOutput = false;
6900             if (mProfileApp != null && mProfileApp.equals(processName)) {
6901                 mProfileProc = app;
6902                 profileFile = mProfileFile;
6903                 profileFd = mProfileFd;
6904                 samplingInterval = mSamplingInterval;
6905                 profileAutoStop = mAutoStopProfiler;
6906                 profileStreamingOutput = mStreamingOutput;
6907             }
6908             boolean enableTrackAllocation = false;
6909             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6910                 enableTrackAllocation = true;
6911                 mTrackAllocationApp = null;
6912             }
6913
6914             // If the app is being launched for restore or full backup, set it up specially
6915             boolean isRestrictedBackupMode = false;
6916             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6917                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6918                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6919                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6920                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6921             }
6922
6923             if (app.instr != null) {
6924                 notifyPackageUse(app.instr.mClass.getPackageName(),
6925                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6926             }
6927             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6928                     + processName + " with config " + getGlobalConfiguration());
6929             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6930             app.compat = compatibilityInfoForPackageLocked(appInfo);
6931             if (profileFd != null) {
6932                 profileFd = profileFd.dup();
6933             }
6934             ProfilerInfo profilerInfo = profileFile == null ? null
6935                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6936                                        profileStreamingOutput);
6937
6938             // We deprecated Build.SERIAL and it is not accessible to
6939             // apps that target the v2 security sandbox. Since access to
6940             // the serial is now behind a permission we push down the value.
6941             String buildSerial = Build.UNKNOWN;
6942             if (appInfo.targetSandboxVersion != 2) {
6943                 buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6944                         ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6945                         .getSerial();
6946             }
6947
6948             // Check if this is a secondary process that should be incorporated into some
6949             // currently active instrumentation.  (Note we do this AFTER all of the profiling
6950             // stuff above because profiling can currently happen only in the primary
6951             // instrumentation process.)
6952             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6953                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6954                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6955                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6956                         if (aInstr.mTargetProcesses.length == 0) {
6957                             // This is the wildcard mode, where every process brought up for
6958                             // the target instrumentation should be included.
6959                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6960                                 app.instr = aInstr;
6961                                 aInstr.mRunningProcesses.add(app);
6962                             }
6963                         } else {
6964                             for (String proc : aInstr.mTargetProcesses) {
6965                                 if (proc.equals(app.processName)) {
6966                                     app.instr = aInstr;
6967                                     aInstr.mRunningProcesses.add(app);
6968                                     break;
6969                                 }
6970                             }
6971                         }
6972                     }
6973                 }
6974             }
6975
6976             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6977             mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
6978             if (app.instr != null) {
6979                 thread.bindApplication(processName, appInfo, providers,
6980                         app.instr.mClass,
6981                         profilerInfo, app.instr.mArguments,
6982                         app.instr.mWatcher,
6983                         app.instr.mUiAutomationConnection, testMode,
6984                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
6985                         isRestrictedBackupMode || !normalMode, app.persistent,
6986                         new Configuration(getGlobalConfiguration()), app.compat,
6987                         getCommonServicesLocked(app.isolated),
6988                         mCoreSettingsObserver.getCoreSettingsLocked(),
6989                         buildSerial);
6990             } else {
6991                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6992                         null, null, null, testMode,
6993                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
6994                         isRestrictedBackupMode || !normalMode, app.persistent,
6995                         new Configuration(getGlobalConfiguration()), app.compat,
6996                         getCommonServicesLocked(app.isolated),
6997                         mCoreSettingsObserver.getCoreSettingsLocked(),
6998                         buildSerial);
6999             }
7000
7001             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7002             updateLruProcessLocked(app, false, null);
7003             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7004             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7005         } catch (Exception e) {
7006             // todo: Yikes!  What should we do?  For now we will try to
7007             // start another process, but that could easily get us in
7008             // an infinite loop of restarting processes...
7009             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7010
7011             app.resetPackageList(mProcessStats);
7012             app.unlinkDeathRecipient();
7013             startProcessLocked(app, "bind fail", processName);
7014             return false;
7015         }
7016
7017         // Remove this record from the list of starting applications.
7018         mPersistentStartingProcesses.remove(app);
7019         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7020                 "Attach application locked removing on hold: " + app);
7021         mProcessesOnHold.remove(app);
7022
7023         boolean badApp = false;
7024         boolean didSomething = false;
7025
7026         // See if the top visible activity is waiting to run in this process...
7027         if (normalMode) {
7028             try {
7029                 if (mStackSupervisor.attachApplicationLocked(app)) {
7030                     didSomething = true;
7031                 }
7032             } catch (Exception e) {
7033                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7034                 badApp = true;
7035             }
7036         }
7037
7038         // Find any services that should be running in this process...
7039         if (!badApp) {
7040             try {
7041                 didSomething |= mServices.attachApplicationLocked(app, processName);
7042                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7043             } catch (Exception e) {
7044                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7045                 badApp = true;
7046             }
7047         }
7048
7049         // Check if a next-broadcast receiver is in this process...
7050         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7051             try {
7052                 didSomething |= sendPendingBroadcastsLocked(app);
7053                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7054             } catch (Exception e) {
7055                 // If the app died trying to launch the receiver we declare it 'bad'
7056                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7057                 badApp = true;
7058             }
7059         }
7060
7061         // Check whether the next backup agent is in this process...
7062         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7063             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7064                     "New app is backup target, launching agent for " + app);
7065             notifyPackageUse(mBackupTarget.appInfo.packageName,
7066                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7067             try {
7068                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7069                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7070                         mBackupTarget.backupMode);
7071             } catch (Exception e) {
7072                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7073                 badApp = true;
7074             }
7075         }
7076
7077         if (badApp) {
7078             app.kill("error during init", true);
7079             handleAppDiedLocked(app, false, true);
7080             return false;
7081         }
7082
7083         if (!didSomething) {
7084             updateOomAdjLocked();
7085             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7086         }
7087
7088         return true;
7089     }
7090
7091     @Override
7092     public final void attachApplication(IApplicationThread thread) {
7093         synchronized (this) {
7094             int callingPid = Binder.getCallingPid();
7095             final long origId = Binder.clearCallingIdentity();
7096             attachApplicationLocked(thread, callingPid);
7097             Binder.restoreCallingIdentity(origId);
7098         }
7099     }
7100
7101     @Override
7102     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7103         final long origId = Binder.clearCallingIdentity();
7104         synchronized (this) {
7105             ActivityStack stack = ActivityRecord.getStackLocked(token);
7106             if (stack != null) {
7107                 ActivityRecord r =
7108                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7109                                 false /* processPausingActivities */, config);
7110                 if (stopProfiling) {
7111                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
7112                         try {
7113                             mProfileFd.close();
7114                         } catch (IOException e) {
7115                         }
7116                         clearProfilerLocked();
7117                     }
7118                 }
7119             }
7120         }
7121         Binder.restoreCallingIdentity(origId);
7122     }
7123
7124     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7125         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7126                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7127     }
7128
7129     void enableScreenAfterBoot() {
7130         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7131                 SystemClock.uptimeMillis());
7132         mWindowManager.enableScreenAfterBoot();
7133
7134         synchronized (this) {
7135             updateEventDispatchingLocked();
7136         }
7137     }
7138
7139     @Override
7140     public void showBootMessage(final CharSequence msg, final boolean always) {
7141         if (Binder.getCallingUid() != myUid()) {
7142             throw new SecurityException();
7143         }
7144         mWindowManager.showBootMessage(msg, always);
7145     }
7146
7147     @Override
7148     public void keyguardGoingAway(int flags) {
7149         enforceNotIsolatedCaller("keyguardGoingAway");
7150         final long token = Binder.clearCallingIdentity();
7151         try {
7152             synchronized (this) {
7153                 mKeyguardController.keyguardGoingAway(flags);
7154             }
7155         } finally {
7156             Binder.restoreCallingIdentity(token);
7157         }
7158     }
7159
7160     /**
7161      * @return whther the keyguard is currently locked.
7162      */
7163     boolean isKeyguardLocked() {
7164         return mKeyguardController.isKeyguardLocked();
7165     }
7166
7167     final void finishBooting() {
7168         synchronized (this) {
7169             if (!mBootAnimationComplete) {
7170                 mCallFinishBooting = true;
7171                 return;
7172             }
7173             mCallFinishBooting = false;
7174         }
7175
7176         ArraySet<String> completedIsas = new ArraySet<String>();
7177         for (String abi : Build.SUPPORTED_ABIS) {
7178             zygoteProcess.establishZygoteConnectionForAbi(abi);
7179             final String instructionSet = VMRuntime.getInstructionSet(abi);
7180             if (!completedIsas.contains(instructionSet)) {
7181                 try {
7182                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7183                 } catch (InstallerException e) {
7184                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7185                             e.getMessage() +")");
7186                 }
7187                 completedIsas.add(instructionSet);
7188             }
7189         }
7190
7191         IntentFilter pkgFilter = new IntentFilter();
7192         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7193         pkgFilter.addDataScheme("package");
7194         mContext.registerReceiver(new BroadcastReceiver() {
7195             @Override
7196             public void onReceive(Context context, Intent intent) {
7197                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7198                 if (pkgs != null) {
7199                     for (String pkg : pkgs) {
7200                         synchronized (ActivityManagerService.this) {
7201                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7202                                     0, "query restart")) {
7203                                 setResultCode(Activity.RESULT_OK);
7204                                 return;
7205                             }
7206                         }
7207                     }
7208                 }
7209             }
7210         }, pkgFilter);
7211
7212         IntentFilter dumpheapFilter = new IntentFilter();
7213         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7214         mContext.registerReceiver(new BroadcastReceiver() {
7215             @Override
7216             public void onReceive(Context context, Intent intent) {
7217                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7218                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7219                 } else {
7220                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7221                 }
7222             }
7223         }, dumpheapFilter);
7224
7225         // Let system services know.
7226         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7227
7228         synchronized (this) {
7229             // Ensure that any processes we had put on hold are now started
7230             // up.
7231             final int NP = mProcessesOnHold.size();
7232             if (NP > 0) {
7233                 ArrayList<ProcessRecord> procs =
7234                     new ArrayList<ProcessRecord>(mProcessesOnHold);
7235                 for (int ip=0; ip<NP; ip++) {
7236                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7237                             + procs.get(ip));
7238                     startProcessLocked(procs.get(ip), "on-hold", null);
7239                 }
7240             }
7241
7242             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7243                 // Start looking for apps that are abusing wake locks.
7244                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7245                 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
7246                 // Tell anyone interested that we are done booting!
7247                 SystemProperties.set("sys.boot_completed", "1");
7248
7249                 // And trigger dev.bootcomplete if we are not showing encryption progress
7250                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7251                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7252                     SystemProperties.set("dev.bootcomplete", "1");
7253                 }
7254                 mUserController.sendBootCompletedLocked(
7255                         new IIntentReceiver.Stub() {
7256                             @Override
7257                             public void performReceive(Intent intent, int resultCode,
7258                                     String data, Bundle extras, boolean ordered,
7259                                     boolean sticky, int sendingUser) {
7260                                 synchronized (ActivityManagerService.this) {
7261                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7262                                             true, false);
7263                                 }
7264                             }
7265                         });
7266                 scheduleStartProfilesLocked();
7267             }
7268         }
7269     }
7270
7271     @Override
7272     public void bootAnimationComplete() {
7273         final boolean callFinishBooting;
7274         synchronized (this) {
7275             callFinishBooting = mCallFinishBooting;
7276             mBootAnimationComplete = true;
7277         }
7278         if (callFinishBooting) {
7279             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7280             finishBooting();
7281             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7282         }
7283     }
7284
7285     final void ensureBootCompleted() {
7286         boolean booting;
7287         boolean enableScreen;
7288         synchronized (this) {
7289             booting = mBooting;
7290             mBooting = false;
7291             enableScreen = !mBooted;
7292             mBooted = true;
7293         }
7294
7295         if (booting) {
7296             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7297             finishBooting();
7298             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7299         }
7300
7301         if (enableScreen) {
7302             enableScreenAfterBoot();
7303         }
7304     }
7305
7306     @Override
7307     public final void activityResumed(IBinder token) {
7308         final long origId = Binder.clearCallingIdentity();
7309         synchronized(this) {
7310             ActivityRecord.activityResumedLocked(token);
7311             mWindowManager.notifyAppResumedFinished(token);
7312         }
7313         Binder.restoreCallingIdentity(origId);
7314     }
7315
7316     @Override
7317     public final void activityPaused(IBinder token) {
7318         final long origId = Binder.clearCallingIdentity();
7319         synchronized(this) {
7320             ActivityStack stack = ActivityRecord.getStackLocked(token);
7321             if (stack != null) {
7322                 stack.activityPausedLocked(token, false);
7323             }
7324         }
7325         Binder.restoreCallingIdentity(origId);
7326     }
7327
7328     @Override
7329     public final void activityStopped(IBinder token, Bundle icicle,
7330             PersistableBundle persistentState, CharSequence description) {
7331         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7332
7333         // Refuse possible leaked file descriptors
7334         if (icicle != null && icicle.hasFileDescriptors()) {
7335             throw new IllegalArgumentException("File descriptors passed in Bundle");
7336         }
7337
7338         final long origId = Binder.clearCallingIdentity();
7339
7340         synchronized (this) {
7341             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7342             if (r != null) {
7343                 r.activityStoppedLocked(icicle, persistentState, description);
7344             }
7345         }
7346
7347         trimApplications();
7348
7349         Binder.restoreCallingIdentity(origId);
7350     }
7351
7352     @Override
7353     public final void activityDestroyed(IBinder token) {
7354         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7355         synchronized (this) {
7356             ActivityStack stack = ActivityRecord.getStackLocked(token);
7357             if (stack != null) {
7358                 stack.activityDestroyedLocked(token, "activityDestroyed");
7359             }
7360         }
7361     }
7362
7363     @Override
7364     public final void activityRelaunched(IBinder token) {
7365         final long origId = Binder.clearCallingIdentity();
7366         synchronized (this) {
7367             mStackSupervisor.activityRelaunchedLocked(token);
7368         }
7369         Binder.restoreCallingIdentity(origId);
7370     }
7371
7372     @Override
7373     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7374             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7375         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7376                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7377         synchronized (this) {
7378             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7379             if (record == null) {
7380                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7381                         + "found for: " + token);
7382             }
7383             record.setSizeConfigurations(horizontalSizeConfiguration,
7384                     verticalSizeConfigurations, smallestSizeConfigurations);
7385         }
7386     }
7387
7388     @Override
7389     public final void backgroundResourcesReleased(IBinder token) {
7390         final long origId = Binder.clearCallingIdentity();
7391         try {
7392             synchronized (this) {
7393                 ActivityStack stack = ActivityRecord.getStackLocked(token);
7394                 if (stack != null) {
7395                     stack.backgroundResourcesReleased();
7396                 }
7397             }
7398         } finally {
7399             Binder.restoreCallingIdentity(origId);
7400         }
7401     }
7402
7403     @Override
7404     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7405         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7406     }
7407
7408     @Override
7409     public final void notifyEnterAnimationComplete(IBinder token) {
7410         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7411     }
7412
7413     @Override
7414     public String getCallingPackage(IBinder token) {
7415         synchronized (this) {
7416             ActivityRecord r = getCallingRecordLocked(token);
7417             return r != null ? r.info.packageName : null;
7418         }
7419     }
7420
7421     @Override
7422     public ComponentName getCallingActivity(IBinder token) {
7423         synchronized (this) {
7424             ActivityRecord r = getCallingRecordLocked(token);
7425             return r != null ? r.intent.getComponent() : null;
7426         }
7427     }
7428
7429     private ActivityRecord getCallingRecordLocked(IBinder token) {
7430         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7431         if (r == null) {
7432             return null;
7433         }
7434         return r.resultTo;
7435     }
7436
7437     @Override
7438     public ComponentName getActivityClassForToken(IBinder token) {
7439         synchronized(this) {
7440             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7441             if (r == null) {
7442                 return null;
7443             }
7444             return r.intent.getComponent();
7445         }
7446     }
7447
7448     @Override
7449     public String getPackageForToken(IBinder token) {
7450         synchronized(this) {
7451             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7452             if (r == null) {
7453                 return null;
7454             }
7455             return r.packageName;
7456         }
7457     }
7458
7459     @Override
7460     public boolean isRootVoiceInteraction(IBinder token) {
7461         synchronized(this) {
7462             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7463             if (r == null) {
7464                 return false;
7465             }
7466             return r.rootVoiceInteraction;
7467         }
7468     }
7469
7470     @Override
7471     public IIntentSender getIntentSender(int type,
7472             String packageName, IBinder token, String resultWho,
7473             int requestCode, Intent[] intents, String[] resolvedTypes,
7474             int flags, Bundle bOptions, int userId) {
7475         enforceNotIsolatedCaller("getIntentSender");
7476         // Refuse possible leaked file descriptors
7477         if (intents != null) {
7478             if (intents.length < 1) {
7479                 throw new IllegalArgumentException("Intents array length must be >= 1");
7480             }
7481             for (int i=0; i<intents.length; i++) {
7482                 Intent intent = intents[i];
7483                 if (intent != null) {
7484                     if (intent.hasFileDescriptors()) {
7485                         throw new IllegalArgumentException("File descriptors passed in Intent");
7486                     }
7487                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7488                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7489                         throw new IllegalArgumentException(
7490                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7491                     }
7492                     intents[i] = new Intent(intent);
7493                 }
7494             }
7495             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7496                 throw new IllegalArgumentException(
7497                         "Intent array length does not match resolvedTypes length");
7498             }
7499         }
7500         if (bOptions != null) {
7501             if (bOptions.hasFileDescriptors()) {
7502                 throw new IllegalArgumentException("File descriptors passed in options");
7503             }
7504         }
7505
7506         synchronized(this) {
7507             int callingUid = Binder.getCallingUid();
7508             int origUserId = userId;
7509             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7510                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7511                     ALLOW_NON_FULL, "getIntentSender", null);
7512             if (origUserId == UserHandle.USER_CURRENT) {
7513                 // We don't want to evaluate this until the pending intent is
7514                 // actually executed.  However, we do want to always do the
7515                 // security checking for it above.
7516                 userId = UserHandle.USER_CURRENT;
7517             }
7518             try {
7519                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7520                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7521                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7522                     if (!UserHandle.isSameApp(callingUid, uid)) {
7523                         String msg = "Permission Denial: getIntentSender() from pid="
7524                             + Binder.getCallingPid()
7525                             + ", uid=" + Binder.getCallingUid()
7526                             + ", (need uid=" + uid + ")"
7527                             + " is not allowed to send as package " + packageName;
7528                         Slog.w(TAG, msg);
7529                         throw new SecurityException(msg);
7530                     }
7531                 }
7532
7533                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7534                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7535
7536             } catch (RemoteException e) {
7537                 throw new SecurityException(e);
7538             }
7539         }
7540     }
7541
7542     IIntentSender getIntentSenderLocked(int type, String packageName,
7543             int callingUid, int userId, IBinder token, String resultWho,
7544             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7545             Bundle bOptions) {
7546         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7547         ActivityRecord activity = null;
7548         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7549             activity = ActivityRecord.isInStackLocked(token);
7550             if (activity == null) {
7551                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7552                 return null;
7553             }
7554             if (activity.finishing) {
7555                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7556                 return null;
7557             }
7558         }
7559
7560         // We're going to be splicing together extras before sending, so we're
7561         // okay poking into any contained extras.
7562         if (intents != null) {
7563             for (int i = 0; i < intents.length; i++) {
7564                 intents[i].setDefusable(true);
7565             }
7566         }
7567         Bundle.setDefusable(bOptions, true);
7568
7569         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7570         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7571         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7572         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7573                 |PendingIntent.FLAG_UPDATE_CURRENT);
7574
7575         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7576                 type, packageName, activity, resultWho,
7577                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7578         WeakReference<PendingIntentRecord> ref;
7579         ref = mIntentSenderRecords.get(key);
7580         PendingIntentRecord rec = ref != null ? ref.get() : null;
7581         if (rec != null) {
7582             if (!cancelCurrent) {
7583                 if (updateCurrent) {
7584                     if (rec.key.requestIntent != null) {
7585                         rec.key.requestIntent.replaceExtras(intents != null ?
7586                                 intents[intents.length - 1] : null);
7587                     }
7588                     if (intents != null) {
7589                         intents[intents.length-1] = rec.key.requestIntent;
7590                         rec.key.allIntents = intents;
7591                         rec.key.allResolvedTypes = resolvedTypes;
7592                     } else {
7593                         rec.key.allIntents = null;
7594                         rec.key.allResolvedTypes = null;
7595                     }
7596                 }
7597                 return rec;
7598             }
7599             makeIntentSenderCanceledLocked(rec);
7600             mIntentSenderRecords.remove(key);
7601         }
7602         if (noCreate) {
7603             return rec;
7604         }
7605         rec = new PendingIntentRecord(this, key, callingUid);
7606         mIntentSenderRecords.put(key, rec.ref);
7607         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7608             if (activity.pendingResults == null) {
7609                 activity.pendingResults
7610                         = new HashSet<WeakReference<PendingIntentRecord>>();
7611             }
7612             activity.pendingResults.add(rec.ref);
7613         }
7614         return rec;
7615     }
7616
7617     @Override
7618     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7619             Intent intent, String resolvedType,
7620             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7621         if (target instanceof PendingIntentRecord) {
7622             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7623                     whitelistToken, finishedReceiver, requiredPermission, options);
7624         } else {
7625             if (intent == null) {
7626                 // Weird case: someone has given us their own custom IIntentSender, and now
7627                 // they have someone else trying to send to it but of course this isn't
7628                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7629                 // supplying an Intent... but we never want to dispatch a null Intent to
7630                 // a receiver, so um...  let's make something up.
7631                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7632                 intent = new Intent(Intent.ACTION_MAIN);
7633             }
7634             try {
7635                 target.send(code, intent, resolvedType, whitelistToken, null,
7636                         requiredPermission, options);
7637             } catch (RemoteException e) {
7638             }
7639             // Platform code can rely on getting a result back when the send is done, but if
7640             // this intent sender is from outside of the system we can't rely on it doing that.
7641             // So instead we don't give it the result receiver, and instead just directly
7642             // report the finish immediately.
7643             if (finishedReceiver != null) {
7644                 try {
7645                     finishedReceiver.performReceive(intent, 0,
7646                             null, null, false, false, UserHandle.getCallingUserId());
7647                 } catch (RemoteException e) {
7648                 }
7649             }
7650             return 0;
7651         }
7652     }
7653
7654     @Override
7655     public void cancelIntentSender(IIntentSender sender) {
7656         if (!(sender instanceof PendingIntentRecord)) {
7657             return;
7658         }
7659         synchronized(this) {
7660             PendingIntentRecord rec = (PendingIntentRecord)sender;
7661             try {
7662                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7663                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7664                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7665                     String msg = "Permission Denial: cancelIntentSender() from pid="
7666                         + Binder.getCallingPid()
7667                         + ", uid=" + Binder.getCallingUid()
7668                         + " is not allowed to cancel package "
7669                         + rec.key.packageName;
7670                     Slog.w(TAG, msg);
7671                     throw new SecurityException(msg);
7672                 }
7673             } catch (RemoteException e) {
7674                 throw new SecurityException(e);
7675             }
7676             cancelIntentSenderLocked(rec, true);
7677         }
7678     }
7679
7680     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7681         makeIntentSenderCanceledLocked(rec);
7682         mIntentSenderRecords.remove(rec.key);
7683         if (cleanActivity && rec.key.activity != null) {
7684             rec.key.activity.pendingResults.remove(rec.ref);
7685         }
7686     }
7687
7688     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7689         rec.canceled = true;
7690         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7691         if (callbacks != null) {
7692             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7693         }
7694     }
7695
7696     @Override
7697     public String getPackageForIntentSender(IIntentSender pendingResult) {
7698         if (!(pendingResult instanceof PendingIntentRecord)) {
7699             return null;
7700         }
7701         try {
7702             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7703             return res.key.packageName;
7704         } catch (ClassCastException e) {
7705         }
7706         return null;
7707     }
7708
7709     @Override
7710     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7711         if (!(sender instanceof PendingIntentRecord)) {
7712             return;
7713         }
7714         synchronized(this) {
7715             ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7716         }
7717     }
7718
7719     @Override
7720     public void unregisterIntentSenderCancelListener(IIntentSender sender,
7721             IResultReceiver receiver) {
7722         if (!(sender instanceof PendingIntentRecord)) {
7723             return;
7724         }
7725         synchronized(this) {
7726             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7727         }
7728     }
7729
7730     @Override
7731     public int getUidForIntentSender(IIntentSender sender) {
7732         if (sender instanceof PendingIntentRecord) {
7733             try {
7734                 PendingIntentRecord res = (PendingIntentRecord)sender;
7735                 return res.uid;
7736             } catch (ClassCastException e) {
7737             }
7738         }
7739         return -1;
7740     }
7741
7742     @Override
7743     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7744         if (!(pendingResult instanceof PendingIntentRecord)) {
7745             return false;
7746         }
7747         try {
7748             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7749             if (res.key.allIntents == null) {
7750                 return false;
7751             }
7752             for (int i=0; i<res.key.allIntents.length; i++) {
7753                 Intent intent = res.key.allIntents[i];
7754                 if (intent.getPackage() != null && intent.getComponent() != null) {
7755                     return false;
7756                 }
7757             }
7758             return true;
7759         } catch (ClassCastException e) {
7760         }
7761         return false;
7762     }
7763
7764     @Override
7765     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7766         if (!(pendingResult instanceof PendingIntentRecord)) {
7767             return false;
7768         }
7769         try {
7770             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7771             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7772                 return true;
7773             }
7774             return false;
7775         } catch (ClassCastException e) {
7776         }
7777         return false;
7778     }
7779
7780     @Override
7781     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7782         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7783                 "getIntentForIntentSender()");
7784         if (!(pendingResult instanceof PendingIntentRecord)) {
7785             return null;
7786         }
7787         try {
7788             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7789             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7790         } catch (ClassCastException e) {
7791         }
7792         return null;
7793     }
7794
7795     @Override
7796     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7797         if (!(pendingResult instanceof PendingIntentRecord)) {
7798             return null;
7799         }
7800         try {
7801             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7802             synchronized (this) {
7803                 return getTagForIntentSenderLocked(res, prefix);
7804             }
7805         } catch (ClassCastException e) {
7806         }
7807         return null;
7808     }
7809
7810     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7811         final Intent intent = res.key.requestIntent;
7812         if (intent != null) {
7813             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7814                     || res.lastTagPrefix.equals(prefix))) {
7815                 return res.lastTag;
7816             }
7817             res.lastTagPrefix = prefix;
7818             final StringBuilder sb = new StringBuilder(128);
7819             if (prefix != null) {
7820                 sb.append(prefix);
7821             }
7822             if (intent.getAction() != null) {
7823                 sb.append(intent.getAction());
7824             } else if (intent.getComponent() != null) {
7825                 intent.getComponent().appendShortString(sb);
7826             } else {
7827                 sb.append("?");
7828             }
7829             return res.lastTag = sb.toString();
7830         }
7831         return null;
7832     }
7833
7834     @Override
7835     public void setProcessLimit(int max) {
7836         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7837                 "setProcessLimit()");
7838         synchronized (this) {
7839             mConstants.setOverrideMaxCachedProcesses(max);
7840         }
7841         trimApplications();
7842     }
7843
7844     @Override
7845     public int getProcessLimit() {
7846         synchronized (this) {
7847             return mConstants.getOverrideMaxCachedProcesses();
7848         }
7849     }
7850
7851     void importanceTokenDied(ImportanceToken token) {
7852         synchronized (ActivityManagerService.this) {
7853             synchronized (mPidsSelfLocked) {
7854                 ImportanceToken cur
7855                     = mImportantProcesses.get(token.pid);
7856                 if (cur != token) {
7857                     return;
7858                 }
7859                 mImportantProcesses.remove(token.pid);
7860                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7861                 if (pr == null) {
7862                     return;
7863                 }
7864                 pr.forcingToImportant = null;
7865                 updateProcessForegroundLocked(pr, false, false);
7866             }
7867             updateOomAdjLocked();
7868         }
7869     }
7870
7871     @Override
7872     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7873         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7874                 "setProcessImportant()");
7875         synchronized(this) {
7876             boolean changed = false;
7877
7878             synchronized (mPidsSelfLocked) {
7879                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7880                 if (pr == null && isForeground) {
7881                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7882                     return;
7883                 }
7884                 ImportanceToken oldToken = mImportantProcesses.get(pid);
7885                 if (oldToken != null) {
7886                     oldToken.token.unlinkToDeath(oldToken, 0);
7887                     mImportantProcesses.remove(pid);
7888                     if (pr != null) {
7889                         pr.forcingToImportant = null;
7890                     }
7891                     changed = true;
7892                 }
7893                 if (isForeground && token != null) {
7894                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7895                         @Override
7896                         public void binderDied() {
7897                             importanceTokenDied(this);
7898                         }
7899                     };
7900                     try {
7901                         token.linkToDeath(newToken, 0);
7902                         mImportantProcesses.put(pid, newToken);
7903                         pr.forcingToImportant = newToken;
7904                         changed = true;
7905                     } catch (RemoteException e) {
7906                         // If the process died while doing this, we will later
7907                         // do the cleanup with the process death link.
7908                     }
7909                 }
7910             }
7911
7912             if (changed) {
7913                 updateOomAdjLocked();
7914             }
7915         }
7916     }
7917
7918     @Override
7919     public boolean isAppForeground(int uid) throws RemoteException {
7920         synchronized (this) {
7921             UidRecord uidRec = mActiveUids.get(uid);
7922             if (uidRec == null || uidRec.idle) {
7923                 return false;
7924             }
7925             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7926         }
7927     }
7928
7929     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7930     // be guarded by permission checking.
7931     int getUidState(int uid) {
7932         synchronized (this) {
7933             return getUidStateLocked(uid);
7934         }
7935     }
7936
7937     int getUidStateLocked(int uid) {
7938         UidRecord uidRec = mActiveUids.get(uid);
7939         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7940     }
7941
7942     @Override
7943     public boolean isInMultiWindowMode(IBinder token) {
7944         final long origId = Binder.clearCallingIdentity();
7945         try {
7946             synchronized(this) {
7947                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7948                 if (r == null) {
7949                     return false;
7950                 }
7951                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7952                 return !r.getTask().mFullscreen;
7953             }
7954         } finally {
7955             Binder.restoreCallingIdentity(origId);
7956         }
7957     }
7958
7959     @Override
7960     public boolean isInPictureInPictureMode(IBinder token) {
7961         final long origId = Binder.clearCallingIdentity();
7962         try {
7963             synchronized(this) {
7964                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
7965             }
7966         } finally {
7967             Binder.restoreCallingIdentity(origId);
7968         }
7969     }
7970
7971     private boolean isInPictureInPictureMode(ActivityRecord r) {
7972         if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
7973                 r.getStack().isInStackLocked(r) == null) {
7974             return false;
7975         }
7976
7977         // If we are animating to fullscreen then we have already dispatched the PIP mode
7978         // changed, so we should reflect that check here as well.
7979         final PinnedActivityStack stack = r.getStack();
7980         final PinnedStackWindowController windowController = stack.getWindowContainerController();
7981         return !windowController.isAnimatingBoundsToFullscreen();
7982     }
7983
7984     @Override
7985     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
7986         final long origId = Binder.clearCallingIdentity();
7987         try {
7988             synchronized(this) {
7989                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7990                         "enterPictureInPictureMode", token, params);
7991
7992                 // If the activity is already in picture in picture mode, then just return early
7993                 if (isInPictureInPictureMode(r)) {
7994                     return true;
7995                 }
7996
7997                 // Activity supports picture-in-picture, now check that we can enter PiP at this
7998                 // point, if it is
7999                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8000                         false /* noThrow */, false /* beforeStopping */)) {
8001                     return false;
8002                 }
8003
8004                 final Runnable enterPipRunnable = () -> {
8005                     // Only update the saved args from the args that are set
8006                     r.pictureInPictureArgs.copyOnlySet(params);
8007                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8008                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8009                     // Adjust the source bounds by the insets for the transition down
8010                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8011                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8012                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8013                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8014                     stack.setPictureInPictureAspectRatio(aspectRatio);
8015                     stack.setPictureInPictureActions(actions);
8016
8017                     MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8018                             r.supportsPictureInPictureWhilePausing);
8019                     logPictureInPictureArgs(params);
8020                 };
8021
8022                 if (isKeyguardLocked()) {
8023                     // If the keyguard is showing or occluded, then try and dismiss it before
8024                     // entering picture-in-picture (this will prompt the user to authenticate if the
8025                     // device is currently locked).
8026                     try {
8027                         dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8028                             @Override
8029                             public void onDismissError() throws RemoteException {
8030                                 // Do nothing
8031                             }
8032
8033                             @Override
8034                             public void onDismissSucceeded() throws RemoteException {
8035                                 mHandler.post(enterPipRunnable);
8036                             }
8037
8038                             @Override
8039                             public void onDismissCancelled() throws RemoteException {
8040                                 // Do nothing
8041                             }
8042                         });
8043                     } catch (RemoteException e) {
8044                         // Local call
8045                     }
8046                 } else {
8047                     // Enter picture in picture immediately otherwise
8048                     enterPipRunnable.run();
8049                 }
8050                 return true;
8051             }
8052         } finally {
8053             Binder.restoreCallingIdentity(origId);
8054         }
8055     }
8056
8057     @Override
8058     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8059         final long origId = Binder.clearCallingIdentity();
8060         try {
8061             synchronized(this) {
8062                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8063                         "setPictureInPictureParams", token, params);
8064
8065                 // Only update the saved args from the args that are set
8066                 r.pictureInPictureArgs.copyOnlySet(params);
8067                 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8068                     // If the activity is already in picture-in-picture, update the pinned stack now
8069                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
8070                     // be used the next time the activity enters PiP
8071                     final PinnedActivityStack stack = r.getStack();
8072                     if (!stack.isAnimatingBoundsToFullscreen()) {
8073                         stack.setPictureInPictureAspectRatio(
8074                                 r.pictureInPictureArgs.getAspectRatio());
8075                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8076                     }
8077                 }
8078                 logPictureInPictureArgs(params);
8079             }
8080         } finally {
8081             Binder.restoreCallingIdentity(origId);
8082         }
8083     }
8084
8085     @Override
8086     public int getMaxNumPictureInPictureActions(IBinder token) {
8087         // Currently, this is a static constant, but later, we may change this to be dependent on
8088         // the context of the activity
8089         return 3;
8090     }
8091
8092     private void logPictureInPictureArgs(PictureInPictureParams params) {
8093         if (params.hasSetActions()) {
8094             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8095                     params.getActions().size());
8096         }
8097         if (params.hasSetAspectRatio()) {
8098             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8099             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8100             MetricsLogger.action(lm);
8101         }
8102     }
8103
8104     /**
8105      * Checks the state of the system and the activity associated with the given {@param token} to
8106      * verify that picture-in-picture is supported for that activity.
8107      *
8108      * @return the activity record for the given {@param token} if all the checks pass.
8109      */
8110     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8111             IBinder token, PictureInPictureParams params) {
8112         if (!mSupportsPictureInPicture) {
8113             throw new IllegalStateException(caller
8114                     + ": Device doesn't support picture-in-picture mode.");
8115         }
8116
8117         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8118         if (r == null) {
8119             throw new IllegalStateException(caller
8120                     + ": Can't find activity for token=" + token);
8121         }
8122
8123         if (!r.supportsPictureInPicture()) {
8124             throw new IllegalStateException(caller
8125                     + ": Current activity does not support picture-in-picture.");
8126         }
8127
8128         if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8129             throw new IllegalStateException(caller
8130                     + ": Activities on the home, assistant, or recents stack not supported");
8131         }
8132
8133         if (params.hasSetAspectRatio()
8134                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8135                         params.getAspectRatio())) {
8136             final float minAspectRatio = mContext.getResources().getFloat(
8137                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8138             final float maxAspectRatio = mContext.getResources().getFloat(
8139                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8140             throw new IllegalArgumentException(String.format(caller
8141                     + ": Aspect ratio is too extreme (must be between %f and %f).",
8142                             minAspectRatio, maxAspectRatio));
8143         }
8144
8145         // Truncate the number of actions if necessary
8146         params.truncateActions(getMaxNumPictureInPictureActions(token));
8147
8148         return r;
8149     }
8150
8151     // =========================================================
8152     // PROCESS INFO
8153     // =========================================================
8154
8155     static class ProcessInfoService extends IProcessInfoService.Stub {
8156         final ActivityManagerService mActivityManagerService;
8157         ProcessInfoService(ActivityManagerService activityManagerService) {
8158             mActivityManagerService = activityManagerService;
8159         }
8160
8161         @Override
8162         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8163             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8164                     /*in*/ pids, /*out*/ states, null);
8165         }
8166
8167         @Override
8168         public void getProcessStatesAndOomScoresFromPids(
8169                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8170             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8171                     /*in*/ pids, /*out*/ states, /*out*/ scores);
8172         }
8173     }
8174
8175     /**
8176      * For each PID in the given input array, write the current process state
8177      * for that process into the states array, or -1 to indicate that no
8178      * process with the given PID exists. If scores array is provided, write
8179      * the oom score for the process into the scores array, with INVALID_ADJ
8180      * indicating the PID doesn't exist.
8181      */
8182     public void getProcessStatesAndOomScoresForPIDs(
8183             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8184         if (scores != null) {
8185             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8186                     "getProcessStatesAndOomScoresForPIDs()");
8187         }
8188
8189         if (pids == null) {
8190             throw new NullPointerException("pids");
8191         } else if (states == null) {
8192             throw new NullPointerException("states");
8193         } else if (pids.length != states.length) {
8194             throw new IllegalArgumentException("pids and states arrays have different lengths!");
8195         } else if (scores != null && pids.length != scores.length) {
8196             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8197         }
8198
8199         synchronized (mPidsSelfLocked) {
8200             for (int i = 0; i < pids.length; i++) {
8201                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8202                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8203                         pr.curProcState;
8204                 if (scores != null) {
8205                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8206                 }
8207             }
8208         }
8209     }
8210
8211     // =========================================================
8212     // PERMISSIONS
8213     // =========================================================
8214
8215     static class PermissionController extends IPermissionController.Stub {
8216         ActivityManagerService mActivityManagerService;
8217         PermissionController(ActivityManagerService activityManagerService) {
8218             mActivityManagerService = activityManagerService;
8219         }
8220
8221         @Override
8222         public boolean checkPermission(String permission, int pid, int uid) {
8223             return mActivityManagerService.checkPermission(permission, pid,
8224                     uid) == PackageManager.PERMISSION_GRANTED;
8225         }
8226
8227         @Override
8228         public String[] getPackagesForUid(int uid) {
8229             return mActivityManagerService.mContext.getPackageManager()
8230                     .getPackagesForUid(uid);
8231         }
8232
8233         @Override
8234         public boolean isRuntimePermission(String permission) {
8235             try {
8236                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8237                         .getPermissionInfo(permission, 0);
8238                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8239                         == PermissionInfo.PROTECTION_DANGEROUS;
8240             } catch (NameNotFoundException nnfe) {
8241                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8242             }
8243             return false;
8244         }
8245     }
8246
8247     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8248         @Override
8249         public int checkComponentPermission(String permission, int pid, int uid,
8250                 int owningUid, boolean exported) {
8251             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8252                     owningUid, exported);
8253         }
8254
8255         @Override
8256         public Object getAMSLock() {
8257             return ActivityManagerService.this;
8258         }
8259     }
8260
8261     /**
8262      * This can be called with or without the global lock held.
8263      */
8264     int checkComponentPermission(String permission, int pid, int uid,
8265             int owningUid, boolean exported) {
8266         if (pid == MY_PID) {
8267             return PackageManager.PERMISSION_GRANTED;
8268         }
8269         return ActivityManager.checkComponentPermission(permission, uid,
8270                 owningUid, exported);
8271     }
8272
8273     /**
8274      * As the only public entry point for permissions checking, this method
8275      * can enforce the semantic that requesting a check on a null global
8276      * permission is automatically denied.  (Internally a null permission
8277      * string is used when calling {@link #checkComponentPermission} in cases
8278      * when only uid-based security is needed.)
8279      *
8280      * This can be called with or without the global lock held.
8281      */
8282     @Override
8283     public int checkPermission(String permission, int pid, int uid) {
8284         if (permission == null) {
8285             return PackageManager.PERMISSION_DENIED;
8286         }
8287         return checkComponentPermission(permission, pid, uid, -1, true);
8288     }
8289
8290     @Override
8291     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8292         if (permission == null) {
8293             return PackageManager.PERMISSION_DENIED;
8294         }
8295
8296         // We might be performing an operation on behalf of an indirect binder
8297         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8298         // client identity accordingly before proceeding.
8299         Identity tlsIdentity = sCallerIdentity.get();
8300         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8301             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8302                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8303             uid = tlsIdentity.uid;
8304             pid = tlsIdentity.pid;
8305         }
8306
8307         return checkComponentPermission(permission, pid, uid, -1, true);
8308     }
8309
8310     /**
8311      * Binder IPC calls go through the public entry point.
8312      * This can be called with or without the global lock held.
8313      */
8314     int checkCallingPermission(String permission) {
8315         return checkPermission(permission,
8316                 Binder.getCallingPid(),
8317                 UserHandle.getAppId(Binder.getCallingUid()));
8318     }
8319
8320     /**
8321      * This can be called with or without the global lock held.
8322      */
8323     void enforceCallingPermission(String permission, String func) {
8324         if (checkCallingPermission(permission)
8325                 == PackageManager.PERMISSION_GRANTED) {
8326             return;
8327         }
8328
8329         String msg = "Permission Denial: " + func + " from pid="
8330                 + Binder.getCallingPid()
8331                 + ", uid=" + Binder.getCallingUid()
8332                 + " requires " + permission;
8333         Slog.w(TAG, msg);
8334         throw new SecurityException(msg);
8335     }
8336
8337     /**
8338      * Determine if UID is holding permissions required to access {@link Uri} in
8339      * the given {@link ProviderInfo}. Final permission checking is always done
8340      * in {@link ContentProvider}.
8341      */
8342     private final boolean checkHoldingPermissionsLocked(
8343             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8344         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8345                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8346         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8347             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8348                     != PERMISSION_GRANTED) {
8349                 return false;
8350             }
8351         }
8352         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8353     }
8354
8355     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8356             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8357         if (pi.applicationInfo.uid == uid) {
8358             return true;
8359         } else if (!pi.exported) {
8360             return false;
8361         }
8362
8363         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8364         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8365         try {
8366             // check if target holds top-level <provider> permissions
8367             if (!readMet && pi.readPermission != null && considerUidPermissions
8368                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8369                 readMet = true;
8370             }
8371             if (!writeMet && pi.writePermission != null && considerUidPermissions
8372                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8373                 writeMet = true;
8374             }
8375
8376             // track if unprotected read/write is allowed; any denied
8377             // <path-permission> below removes this ability
8378             boolean allowDefaultRead = pi.readPermission == null;
8379             boolean allowDefaultWrite = pi.writePermission == null;
8380
8381             // check if target holds any <path-permission> that match uri
8382             final PathPermission[] pps = pi.pathPermissions;
8383             if (pps != null) {
8384                 final String path = grantUri.uri.getPath();
8385                 int i = pps.length;
8386                 while (i > 0 && (!readMet || !writeMet)) {
8387                     i--;
8388                     PathPermission pp = pps[i];
8389                     if (pp.match(path)) {
8390                         if (!readMet) {
8391                             final String pprperm = pp.getReadPermission();
8392                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8393                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
8394                                     + ": match=" + pp.match(path)
8395                                     + " check=" + pm.checkUidPermission(pprperm, uid));
8396                             if (pprperm != null) {
8397                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8398                                         == PERMISSION_GRANTED) {
8399                                     readMet = true;
8400                                 } else {
8401                                     allowDefaultRead = false;
8402                                 }
8403                             }
8404                         }
8405                         if (!writeMet) {
8406                             final String ppwperm = pp.getWritePermission();
8407                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8408                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
8409                                     + ": match=" + pp.match(path)
8410                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
8411                             if (ppwperm != null) {
8412                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8413                                         == PERMISSION_GRANTED) {
8414                                     writeMet = true;
8415                                 } else {
8416                                     allowDefaultWrite = false;
8417                                 }
8418                             }
8419                         }
8420                     }
8421                 }
8422             }
8423
8424             // grant unprotected <provider> read/write, if not blocked by
8425             // <path-permission> above
8426             if (allowDefaultRead) readMet = true;
8427             if (allowDefaultWrite) writeMet = true;
8428
8429         } catch (RemoteException e) {
8430             return false;
8431         }
8432
8433         return readMet && writeMet;
8434     }
8435
8436     public boolean isAppStartModeDisabled(int uid, String packageName) {
8437         synchronized (this) {
8438             return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8439                     == ActivityManager.APP_START_MODE_DISABLED;
8440         }
8441     }
8442
8443     // Unified app-op and target sdk check
8444     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8445         // Apps that target O+ are always subject to background check
8446         if (packageTargetSdk >= Build.VERSION_CODES.O) {
8447             if (DEBUG_BACKGROUND_CHECK) {
8448                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8449             }
8450             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8451         }
8452         // ...and legacy apps get an AppOp check
8453         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8454                 uid, packageName);
8455         if (DEBUG_BACKGROUND_CHECK) {
8456             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8457         }
8458         switch (appop) {
8459             case AppOpsManager.MODE_ALLOWED:
8460                 return ActivityManager.APP_START_MODE_NORMAL;
8461             case AppOpsManager.MODE_IGNORED:
8462                 return ActivityManager.APP_START_MODE_DELAYED;
8463             default:
8464                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8465         }
8466     }
8467
8468     // Service launch is available to apps with run-in-background exemptions but
8469     // some other background operations are not.  If we're doing a check
8470     // of service-launch policy, allow those callers to proceed unrestricted.
8471     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8472         // Persistent app?
8473         if (mPackageManagerInt.isPackagePersistent(packageName)) {
8474             if (DEBUG_BACKGROUND_CHECK) {
8475                 Slog.i(TAG, "App " + uid + "/" + packageName
8476                         + " is persistent; not restricted in background");
8477             }
8478             return ActivityManager.APP_START_MODE_NORMAL;
8479         }
8480
8481         // Non-persistent but background whitelisted?
8482         if (uidOnBackgroundWhitelist(uid)) {
8483             if (DEBUG_BACKGROUND_CHECK) {
8484                 Slog.i(TAG, "App " + uid + "/" + packageName
8485                         + " on background whitelist; not restricted in background");
8486             }
8487             return ActivityManager.APP_START_MODE_NORMAL;
8488         }
8489
8490         // Is this app on the battery whitelist?
8491         if (isOnDeviceIdleWhitelistLocked(uid)) {
8492             if (DEBUG_BACKGROUND_CHECK) {
8493                 Slog.i(TAG, "App " + uid + "/" + packageName
8494                         + " on idle whitelist; not restricted in background");
8495             }
8496             return ActivityManager.APP_START_MODE_NORMAL;
8497         }
8498
8499         // None of the service-policy criteria apply, so we apply the common criteria
8500         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8501     }
8502
8503     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8504             int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8505         UidRecord uidRec = mActiveUids.get(uid);
8506         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8507                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8508                 + (uidRec != null ? uidRec.idle : false));
8509         if (uidRec == null || alwaysRestrict || uidRec.idle) {
8510             boolean ephemeral;
8511             if (uidRec == null) {
8512                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8513                         UserHandle.getUserId(uid), packageName);
8514             } else {
8515                 ephemeral = uidRec.ephemeral;
8516             }
8517
8518             if (ephemeral) {
8519                 // We are hard-core about ephemeral apps not running in the background.
8520                 return ActivityManager.APP_START_MODE_DISABLED;
8521             } else {
8522                 if (disabledOnly) {
8523                     // The caller is only interested in whether app starts are completely
8524                     // disabled for the given package (that is, it is an instant app).  So
8525                     // we don't need to go further, which is all just seeing if we should
8526                     // apply a "delayed" mode for a regular app.
8527                     return ActivityManager.APP_START_MODE_NORMAL;
8528                 }
8529                 final int startMode = (alwaysRestrict)
8530                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8531                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
8532                                 packageTargetSdk);
8533                 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8534                         + " pkg=" + packageName + " startMode=" + startMode
8535                         + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8536                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8537                     // This is an old app that has been forced into a "compatible as possible"
8538                     // mode of background check.  To increase compatibility, we will allow other
8539                     // foreground apps to cause its services to start.
8540                     if (callingPid >= 0) {
8541                         ProcessRecord proc;
8542                         synchronized (mPidsSelfLocked) {
8543                             proc = mPidsSelfLocked.get(callingPid);
8544                         }
8545                         if (proc != null &&
8546                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8547                             // Whoever is instigating this is in the foreground, so we will allow it
8548                             // to go through.
8549                             return ActivityManager.APP_START_MODE_NORMAL;
8550                         }
8551                     }
8552                 }
8553                 return startMode;
8554             }
8555         }
8556         return ActivityManager.APP_START_MODE_NORMAL;
8557     }
8558
8559     boolean isOnDeviceIdleWhitelistLocked(int uid) {
8560         final int appId = UserHandle.getAppId(uid);
8561         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8562                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8563                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8564     }
8565
8566     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8567         ProviderInfo pi = null;
8568         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8569         if (cpr != null) {
8570             pi = cpr.info;
8571         } else {
8572             try {
8573                 pi = AppGlobals.getPackageManager().resolveContentProvider(
8574                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8575                         userHandle);
8576             } catch (RemoteException ex) {
8577             }
8578         }
8579         return pi;
8580     }
8581
8582     void grantEphemeralAccessLocked(int userId, Intent intent,
8583             int targetAppId, int ephemeralAppId) {
8584         getPackageManagerInternalLocked().
8585                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8586     }
8587
8588     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8589         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8590         if (targetUris != null) {
8591             return targetUris.get(grantUri);
8592         }
8593         return null;
8594     }
8595
8596     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8597             String targetPkg, int targetUid, GrantUri grantUri) {
8598         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8599         if (targetUris == null) {
8600             targetUris = Maps.newArrayMap();
8601             mGrantedUriPermissions.put(targetUid, targetUris);
8602         }
8603
8604         UriPermission perm = targetUris.get(grantUri);
8605         if (perm == null) {
8606             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8607             targetUris.put(grantUri, perm);
8608         }
8609
8610         return perm;
8611     }
8612
8613     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8614             final int modeFlags) {
8615         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8616         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8617                 : UriPermission.STRENGTH_OWNED;
8618
8619         // Root gets to do everything.
8620         if (uid == 0) {
8621             return true;
8622         }
8623
8624         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8625         if (perms == null) return false;
8626
8627         // First look for exact match
8628         final UriPermission exactPerm = perms.get(grantUri);
8629         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8630             return true;
8631         }
8632
8633         // No exact match, look for prefixes
8634         final int N = perms.size();
8635         for (int i = 0; i < N; i++) {
8636             final UriPermission perm = perms.valueAt(i);
8637             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8638                     && perm.getStrength(modeFlags) >= minStrength) {
8639                 return true;
8640             }
8641         }
8642
8643         return false;
8644     }
8645
8646     /**
8647      * @param uri This uri must NOT contain an embedded userId.
8648      * @param userId The userId in which the uri is to be resolved.
8649      */
8650     @Override
8651     public int checkUriPermission(Uri uri, int pid, int uid,
8652             final int modeFlags, int userId, IBinder callerToken) {
8653         enforceNotIsolatedCaller("checkUriPermission");
8654
8655         // Another redirected-binder-call permissions check as in
8656         // {@link checkPermissionWithToken}.
8657         Identity tlsIdentity = sCallerIdentity.get();
8658         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8659             uid = tlsIdentity.uid;
8660             pid = tlsIdentity.pid;
8661         }
8662
8663         // Our own process gets to do everything.
8664         if (pid == MY_PID) {
8665             return PackageManager.PERMISSION_GRANTED;
8666         }
8667         synchronized (this) {
8668             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8669                     ? PackageManager.PERMISSION_GRANTED
8670                     : PackageManager.PERMISSION_DENIED;
8671         }
8672     }
8673
8674     /**
8675      * Check if the targetPkg can be granted permission to access uri by
8676      * the callingUid using the given modeFlags.  Throws a security exception
8677      * if callingUid is not allowed to do this.  Returns the uid of the target
8678      * if the URI permission grant should be performed; returns -1 if it is not
8679      * needed (for example targetPkg already has permission to access the URI).
8680      * If you already know the uid of the target, you can supply it in
8681      * lastTargetUid else set that to -1.
8682      */
8683     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8684             final int modeFlags, int lastTargetUid) {
8685         if (!Intent.isAccessUriMode(modeFlags)) {
8686             return -1;
8687         }
8688
8689         if (targetPkg != null) {
8690             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8691                     "Checking grant " + targetPkg + " permission to " + grantUri);
8692         }
8693
8694         final IPackageManager pm = AppGlobals.getPackageManager();
8695
8696         // If this is not a content: uri, we can't do anything with it.
8697         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8698             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8699                     "Can't grant URI permission for non-content URI: " + grantUri);
8700             return -1;
8701         }
8702
8703         // Bail early if system is trying to hand out permissions directly; it
8704         // must always grant permissions on behalf of someone explicit.
8705         final int callingAppId = UserHandle.getAppId(callingUid);
8706         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8707             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8708                 // Exempted authority for cropping user photos in Settings app
8709             } else {
8710                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8711                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8712                 return -1;
8713             }
8714         }
8715
8716         final String authority = grantUri.uri.getAuthority();
8717         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8718                 MATCH_DEBUG_TRIAGED_MISSING);
8719         if (pi == null) {
8720             Slog.w(TAG, "No content provider found for permission check: " +
8721                     grantUri.uri.toSafeString());
8722             return -1;
8723         }
8724
8725         int targetUid = lastTargetUid;
8726         if (targetUid < 0 && targetPkg != null) {
8727             try {
8728                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8729                         UserHandle.getUserId(callingUid));
8730                 if (targetUid < 0) {
8731                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8732                             "Can't grant URI permission no uid for: " + targetPkg);
8733                     return -1;
8734                 }
8735             } catch (RemoteException ex) {
8736                 return -1;
8737             }
8738         }
8739
8740         // If we're extending a persistable grant, then we always need to create
8741         // the grant data structure so that take/release APIs work
8742         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8743             return targetUid;
8744         }
8745
8746         if (targetUid >= 0) {
8747             // First...  does the target actually need this permission?
8748             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8749                 // No need to grant the target this permission.
8750                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8751                         "Target " + targetPkg + " already has full permission to " + grantUri);
8752                 return -1;
8753             }
8754         } else {
8755             // First...  there is no target package, so can anyone access it?
8756             boolean allowed = pi.exported;
8757             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8758                 if (pi.readPermission != null) {
8759                     allowed = false;
8760                 }
8761             }
8762             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8763                 if (pi.writePermission != null) {
8764                     allowed = false;
8765                 }
8766             }
8767             if (allowed) {
8768                 return -1;
8769             }
8770         }
8771
8772         /* There is a special cross user grant if:
8773          * - The target is on another user.
8774          * - Apps on the current user can access the uri without any uid permissions.
8775          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8776          * grant uri permissions.
8777          */
8778         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8779                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8780                 modeFlags, false /*without considering the uid permissions*/);
8781
8782         // Second...  is the provider allowing granting of URI permissions?
8783         if (!specialCrossUserGrant) {
8784             if (!pi.grantUriPermissions) {
8785                 throw new SecurityException("Provider " + pi.packageName
8786                         + "/" + pi.name
8787                         + " does not allow granting of Uri permissions (uri "
8788                         + grantUri + ")");
8789             }
8790             if (pi.uriPermissionPatterns != null) {
8791                 final int N = pi.uriPermissionPatterns.length;
8792                 boolean allowed = false;
8793                 for (int i=0; i<N; i++) {
8794                     if (pi.uriPermissionPatterns[i] != null
8795                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8796                         allowed = true;
8797                         break;
8798                     }
8799                 }
8800                 if (!allowed) {
8801                     throw new SecurityException("Provider " + pi.packageName
8802                             + "/" + pi.name
8803                             + " does not allow granting of permission to path of Uri "
8804                             + grantUri);
8805                 }
8806             }
8807         }
8808
8809         // Third...  does the caller itself have permission to access
8810         // this uri?
8811         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8812             // Require they hold a strong enough Uri permission
8813             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8814                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8815                     throw new SecurityException(
8816                             "UID " + callingUid + " does not have permission to " + grantUri
8817                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8818                                     + "or related APIs");
8819                 } else {
8820                     throw new SecurityException(
8821                             "UID " + callingUid + " does not have permission to " + grantUri);
8822                 }
8823             }
8824         }
8825         return targetUid;
8826     }
8827
8828     /**
8829      * @param uri This uri must NOT contain an embedded userId.
8830      * @param userId The userId in which the uri is to be resolved.
8831      */
8832     @Override
8833     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8834             final int modeFlags, int userId) {
8835         enforceNotIsolatedCaller("checkGrantUriPermission");
8836         synchronized(this) {
8837             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8838                     new GrantUri(userId, uri, false), modeFlags, -1);
8839         }
8840     }
8841
8842     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8843             final int modeFlags, UriPermissionOwner owner) {
8844         if (!Intent.isAccessUriMode(modeFlags)) {
8845             return;
8846         }
8847
8848         // So here we are: the caller has the assumed permission
8849         // to the uri, and the target doesn't.  Let's now give this to
8850         // the target.
8851
8852         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8853                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8854
8855         final String authority = grantUri.uri.getAuthority();
8856         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8857                 MATCH_DEBUG_TRIAGED_MISSING);
8858         if (pi == null) {
8859             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8860             return;
8861         }
8862
8863         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8864             grantUri.prefix = true;
8865         }
8866         final UriPermission perm = findOrCreateUriPermissionLocked(
8867                 pi.packageName, targetPkg, targetUid, grantUri);
8868         perm.grantModes(modeFlags, owner);
8869     }
8870
8871     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8872             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8873         if (targetPkg == null) {
8874             throw new NullPointerException("targetPkg");
8875         }
8876         int targetUid;
8877         final IPackageManager pm = AppGlobals.getPackageManager();
8878         try {
8879             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8880         } catch (RemoteException ex) {
8881             return;
8882         }
8883
8884         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8885                 targetUid);
8886         if (targetUid < 0) {
8887             return;
8888         }
8889
8890         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8891                 owner);
8892     }
8893
8894     static class NeededUriGrants extends ArrayList<GrantUri> {
8895         final String targetPkg;
8896         final int targetUid;
8897         final int flags;
8898
8899         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8900             this.targetPkg = targetPkg;
8901             this.targetUid = targetUid;
8902             this.flags = flags;
8903         }
8904     }
8905
8906     /**
8907      * Like checkGrantUriPermissionLocked, but takes an Intent.
8908      */
8909     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8910             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8911         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8912                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8913                 + " clip=" + (intent != null ? intent.getClipData() : null)
8914                 + " from " + intent + "; flags=0x"
8915                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8916
8917         if (targetPkg == null) {
8918             throw new NullPointerException("targetPkg");
8919         }
8920
8921         if (intent == null) {
8922             return null;
8923         }
8924         Uri data = intent.getData();
8925         ClipData clip = intent.getClipData();
8926         if (data == null && clip == null) {
8927             return null;
8928         }
8929         // Default userId for uris in the intent (if they don't specify it themselves)
8930         int contentUserHint = intent.getContentUserHint();
8931         if (contentUserHint == UserHandle.USER_CURRENT) {
8932             contentUserHint = UserHandle.getUserId(callingUid);
8933         }
8934         final IPackageManager pm = AppGlobals.getPackageManager();
8935         int targetUid;
8936         if (needed != null) {
8937             targetUid = needed.targetUid;
8938         } else {
8939             try {
8940                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8941                         targetUserId);
8942             } catch (RemoteException ex) {
8943                 return null;
8944             }
8945             if (targetUid < 0) {
8946                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8947                         "Can't grant URI permission no uid for: " + targetPkg
8948                         + " on user " + targetUserId);
8949                 return null;
8950             }
8951         }
8952         if (data != null) {
8953             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8954             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8955                     targetUid);
8956             if (targetUid > 0) {
8957                 if (needed == null) {
8958                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8959                 }
8960                 needed.add(grantUri);
8961             }
8962         }
8963         if (clip != null) {
8964             for (int i=0; i<clip.getItemCount(); i++) {
8965                 Uri uri = clip.getItemAt(i).getUri();
8966                 if (uri != null) {
8967                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8968                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8969                             targetUid);
8970                     if (targetUid > 0) {
8971                         if (needed == null) {
8972                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8973                         }
8974                         needed.add(grantUri);
8975                     }
8976                 } else {
8977                     Intent clipIntent = clip.getItemAt(i).getIntent();
8978                     if (clipIntent != null) {
8979                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8980                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8981                         if (newNeeded != null) {
8982                             needed = newNeeded;
8983                         }
8984                     }
8985                 }
8986             }
8987         }
8988
8989         return needed;
8990     }
8991
8992     /**
8993      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8994      */
8995     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8996             UriPermissionOwner owner) {
8997         if (needed != null) {
8998             for (int i=0; i<needed.size(); i++) {
8999                 GrantUri grantUri = needed.get(i);
9000                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9001                         grantUri, needed.flags, owner);
9002             }
9003         }
9004     }
9005
9006     void grantUriPermissionFromIntentLocked(int callingUid,
9007             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9008         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9009                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9010         if (needed == null) {
9011             return;
9012         }
9013
9014         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9015     }
9016
9017     /**
9018      * @param uri This uri must NOT contain an embedded userId.
9019      * @param userId The userId in which the uri is to be resolved.
9020      */
9021     @Override
9022     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9023             final int modeFlags, int userId) {
9024         enforceNotIsolatedCaller("grantUriPermission");
9025         GrantUri grantUri = new GrantUri(userId, uri, false);
9026         synchronized(this) {
9027             final ProcessRecord r = getRecordForAppLocked(caller);
9028             if (r == null) {
9029                 throw new SecurityException("Unable to find app for caller "
9030                         + caller
9031                         + " when granting permission to uri " + grantUri);
9032             }
9033             if (targetPkg == null) {
9034                 throw new IllegalArgumentException("null target");
9035             }
9036             if (grantUri == null) {
9037                 throw new IllegalArgumentException("null uri");
9038             }
9039
9040             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9041                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9042                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9043                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9044
9045             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9046                     UserHandle.getUserId(r.uid));
9047         }
9048     }
9049
9050     void removeUriPermissionIfNeededLocked(UriPermission perm) {
9051         if (perm.modeFlags == 0) {
9052             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9053                     perm.targetUid);
9054             if (perms != null) {
9055                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9056                         "Removing " + perm.targetUid + " permission to " + perm.uri);
9057
9058                 perms.remove(perm.uri);
9059                 if (perms.isEmpty()) {
9060                     mGrantedUriPermissions.remove(perm.targetUid);
9061                 }
9062             }
9063         }
9064     }
9065
9066     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9067             final int modeFlags) {
9068         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9069                 "Revoking all granted permissions to " + grantUri);
9070
9071         final IPackageManager pm = AppGlobals.getPackageManager();
9072         final String authority = grantUri.uri.getAuthority();
9073         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9074                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9075         if (pi == null) {
9076             Slog.w(TAG, "No content provider found for permission revoke: "
9077                     + grantUri.toSafeString());
9078             return;
9079         }
9080
9081         // Does the caller have this permission on the URI?
9082         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9083             // If they don't have direct access to the URI, then revoke any
9084             // ownerless URI permissions that have been granted to them.
9085             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9086             if (perms != null) {
9087                 boolean persistChanged = false;
9088                 for (int i = perms.size()-1; i >= 0; i--) {
9089                     final UriPermission perm = perms.valueAt(i);
9090                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9091                         continue;
9092                     }
9093                     if (perm.uri.sourceUserId == grantUri.sourceUserId
9094                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9095                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9096                                 "Revoking non-owned " + perm.targetUid
9097                                 + " permission to " + perm.uri);
9098                         persistChanged |= perm.revokeModes(
9099                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9100                         if (perm.modeFlags == 0) {
9101                             perms.removeAt(i);
9102                         }
9103                     }
9104                 }
9105                 if (perms.isEmpty()) {
9106                     mGrantedUriPermissions.remove(callingUid);
9107                 }
9108                 if (persistChanged) {
9109                     schedulePersistUriGrants();
9110                 }
9111             }
9112             return;
9113         }
9114
9115         boolean persistChanged = false;
9116
9117         // Go through all of the permissions and remove any that match.
9118         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9119             final int targetUid = mGrantedUriPermissions.keyAt(i);
9120             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9121
9122             for (int j = perms.size()-1; j >= 0; j--) {
9123                 final UriPermission perm = perms.valueAt(j);
9124                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9125                     continue;
9126                 }
9127                 if (perm.uri.sourceUserId == grantUri.sourceUserId
9128                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9129                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9130                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9131                     persistChanged |= perm.revokeModes(
9132                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9133                             targetPackage == null);
9134                     if (perm.modeFlags == 0) {
9135                         perms.removeAt(j);
9136                     }
9137                 }
9138             }
9139
9140             if (perms.isEmpty()) {
9141                 mGrantedUriPermissions.removeAt(i);
9142             }
9143         }
9144
9145         if (persistChanged) {
9146             schedulePersistUriGrants();
9147         }
9148     }
9149
9150     /**
9151      * @param uri This uri must NOT contain an embedded userId.
9152      * @param userId The userId in which the uri is to be resolved.
9153      */
9154     @Override
9155     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9156             final int modeFlags, int userId) {
9157         enforceNotIsolatedCaller("revokeUriPermission");
9158         synchronized(this) {
9159             final ProcessRecord r = getRecordForAppLocked(caller);
9160             if (r == null) {
9161                 throw new SecurityException("Unable to find app for caller "
9162                         + caller
9163                         + " when revoking permission to uri " + uri);
9164             }
9165             if (uri == null) {
9166                 Slog.w(TAG, "revokeUriPermission: null uri");
9167                 return;
9168             }
9169
9170             if (!Intent.isAccessUriMode(modeFlags)) {
9171                 return;
9172             }
9173
9174             final String authority = uri.getAuthority();
9175             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9176                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9177             if (pi == null) {
9178                 Slog.w(TAG, "No content provider found for permission revoke: "
9179                         + uri.toSafeString());
9180                 return;
9181             }
9182
9183             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9184                     modeFlags);
9185         }
9186     }
9187
9188     /**
9189      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9190      * given package.
9191      *
9192      * @param packageName Package name to match, or {@code null} to apply to all
9193      *            packages.
9194      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9195      *            to all users.
9196      * @param persistable If persistable grants should be removed.
9197      */
9198     private void removeUriPermissionsForPackageLocked(
9199             String packageName, int userHandle, boolean persistable) {
9200         if (userHandle == UserHandle.USER_ALL && packageName == null) {
9201             throw new IllegalArgumentException("Must narrow by either package or user");
9202         }
9203
9204         boolean persistChanged = false;
9205
9206         int N = mGrantedUriPermissions.size();
9207         for (int i = 0; i < N; i++) {
9208             final int targetUid = mGrantedUriPermissions.keyAt(i);
9209             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9210
9211             // Only inspect grants matching user
9212             if (userHandle == UserHandle.USER_ALL
9213                     || userHandle == UserHandle.getUserId(targetUid)) {
9214                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9215                     final UriPermission perm = it.next();
9216
9217                     // Only inspect grants matching package
9218                     if (packageName == null || perm.sourcePkg.equals(packageName)
9219                             || perm.targetPkg.equals(packageName)) {
9220                         // Hacky solution as part of fixing a security bug; ignore
9221                         // grants associated with DownloadManager so we don't have
9222                         // to immediately launch it to regrant the permissions
9223                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9224                                 && !persistable) continue;
9225
9226                         persistChanged |= perm.revokeModes(persistable
9227                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9228
9229                         // Only remove when no modes remain; any persisted grants
9230                         // will keep this alive.
9231                         if (perm.modeFlags == 0) {
9232                             it.remove();
9233                         }
9234                     }
9235                 }
9236
9237                 if (perms.isEmpty()) {
9238                     mGrantedUriPermissions.remove(targetUid);
9239                     N--;
9240                     i--;
9241                 }
9242             }
9243         }
9244
9245         if (persistChanged) {
9246             schedulePersistUriGrants();
9247         }
9248     }
9249
9250     @Override
9251     public IBinder newUriPermissionOwner(String name) {
9252         enforceNotIsolatedCaller("newUriPermissionOwner");
9253         synchronized(this) {
9254             UriPermissionOwner owner = new UriPermissionOwner(this, name);
9255             return owner.getExternalTokenLocked();
9256         }
9257     }
9258
9259     @Override
9260     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9261         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9262         synchronized(this) {
9263             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9264             if (r == null) {
9265                 throw new IllegalArgumentException("Activity does not exist; token="
9266                         + activityToken);
9267             }
9268             return r.getUriPermissionsLocked().getExternalTokenLocked();
9269         }
9270     }
9271     /**
9272      * @param uri This uri must NOT contain an embedded userId.
9273      * @param sourceUserId The userId in which the uri is to be resolved.
9274      * @param targetUserId The userId of the app that receives the grant.
9275      */
9276     @Override
9277     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9278             final int modeFlags, int sourceUserId, int targetUserId) {
9279         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9280                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9281                 "grantUriPermissionFromOwner", null);
9282         synchronized(this) {
9283             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9284             if (owner == null) {
9285                 throw new IllegalArgumentException("Unknown owner: " + token);
9286             }
9287             if (fromUid != Binder.getCallingUid()) {
9288                 if (Binder.getCallingUid() != myUid()) {
9289                     // Only system code can grant URI permissions on behalf
9290                     // of other users.
9291                     throw new SecurityException("nice try");
9292                 }
9293             }
9294             if (targetPkg == null) {
9295                 throw new IllegalArgumentException("null target");
9296             }
9297             if (uri == null) {
9298                 throw new IllegalArgumentException("null uri");
9299             }
9300
9301             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9302                     modeFlags, owner, targetUserId);
9303         }
9304     }
9305
9306     /**
9307      * @param uri This uri must NOT contain an embedded userId.
9308      * @param userId The userId in which the uri is to be resolved.
9309      */
9310     @Override
9311     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9312         synchronized(this) {
9313             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9314             if (owner == null) {
9315                 throw new IllegalArgumentException("Unknown owner: " + token);
9316             }
9317
9318             if (uri == null) {
9319                 owner.removeUriPermissionsLocked(mode);
9320             } else {
9321                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9322                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9323             }
9324         }
9325     }
9326
9327     private void schedulePersistUriGrants() {
9328         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9329             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9330                     10 * DateUtils.SECOND_IN_MILLIS);
9331         }
9332     }
9333
9334     private void writeGrantedUriPermissions() {
9335         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9336
9337         // Snapshot permissions so we can persist without lock
9338         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9339         synchronized (this) {
9340             final int size = mGrantedUriPermissions.size();
9341             for (int i = 0; i < size; i++) {
9342                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9343                 for (UriPermission perm : perms.values()) {
9344                     if (perm.persistedModeFlags != 0) {
9345                         persist.add(perm.snapshot());
9346                     }
9347                 }
9348             }
9349         }
9350
9351         FileOutputStream fos = null;
9352         try {
9353             fos = mGrantFile.startWrite();
9354
9355             XmlSerializer out = new FastXmlSerializer();
9356             out.setOutput(fos, StandardCharsets.UTF_8.name());
9357             out.startDocument(null, true);
9358             out.startTag(null, TAG_URI_GRANTS);
9359             for (UriPermission.Snapshot perm : persist) {
9360                 out.startTag(null, TAG_URI_GRANT);
9361                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9362                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9363                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9364                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9365                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9366                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9367                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9368                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9369                 out.endTag(null, TAG_URI_GRANT);
9370             }
9371             out.endTag(null, TAG_URI_GRANTS);
9372             out.endDocument();
9373
9374             mGrantFile.finishWrite(fos);
9375         } catch (IOException e) {
9376             if (fos != null) {
9377                 mGrantFile.failWrite(fos);
9378             }
9379         }
9380     }
9381
9382     private void readGrantedUriPermissionsLocked() {
9383         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9384
9385         final long now = System.currentTimeMillis();
9386
9387         FileInputStream fis = null;
9388         try {
9389             fis = mGrantFile.openRead();
9390             final XmlPullParser in = Xml.newPullParser();
9391             in.setInput(fis, StandardCharsets.UTF_8.name());
9392
9393             int type;
9394             while ((type = in.next()) != END_DOCUMENT) {
9395                 final String tag = in.getName();
9396                 if (type == START_TAG) {
9397                     if (TAG_URI_GRANT.equals(tag)) {
9398                         final int sourceUserId;
9399                         final int targetUserId;
9400                         final int userHandle = readIntAttribute(in,
9401                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9402                         if (userHandle != UserHandle.USER_NULL) {
9403                             // For backwards compatibility.
9404                             sourceUserId = userHandle;
9405                             targetUserId = userHandle;
9406                         } else {
9407                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9408                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9409                         }
9410                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9411                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9412                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9413                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9414                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9415                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9416
9417                         // Sanity check that provider still belongs to source package
9418                         // Both direct boot aware and unaware packages are fine as we
9419                         // will do filtering at query time to avoid multiple parsing.
9420                         final ProviderInfo pi = getProviderInfoLocked(
9421                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9422                                         | MATCH_DIRECT_BOOT_UNAWARE);
9423                         if (pi != null && sourcePkg.equals(pi.packageName)) {
9424                             int targetUid = -1;
9425                             try {
9426                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
9427                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9428                             } catch (RemoteException e) {
9429                             }
9430                             if (targetUid != -1) {
9431                                 final UriPermission perm = findOrCreateUriPermissionLocked(
9432                                         sourcePkg, targetPkg, targetUid,
9433                                         new GrantUri(sourceUserId, uri, prefix));
9434                                 perm.initPersistedModes(modeFlags, createdTime);
9435                             }
9436                         } else {
9437                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9438                                     + " but instead found " + pi);
9439                         }
9440                     }
9441                 }
9442             }
9443         } catch (FileNotFoundException e) {
9444             // Missing grants is okay
9445         } catch (IOException e) {
9446             Slog.wtf(TAG, "Failed reading Uri grants", e);
9447         } catch (XmlPullParserException e) {
9448             Slog.wtf(TAG, "Failed reading Uri grants", e);
9449         } finally {
9450             IoUtils.closeQuietly(fis);
9451         }
9452     }
9453
9454     /**
9455      * @param uri This uri must NOT contain an embedded userId.
9456      * @param userId The userId in which the uri is to be resolved.
9457      */
9458     @Override
9459     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9460         enforceNotIsolatedCaller("takePersistableUriPermission");
9461
9462         Preconditions.checkFlagsArgument(modeFlags,
9463                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9464
9465         synchronized (this) {
9466             final int callingUid = Binder.getCallingUid();
9467             boolean persistChanged = false;
9468             GrantUri grantUri = new GrantUri(userId, uri, false);
9469
9470             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9471                     new GrantUri(userId, uri, false));
9472             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9473                     new GrantUri(userId, uri, true));
9474
9475             final boolean exactValid = (exactPerm != null)
9476                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9477             final boolean prefixValid = (prefixPerm != null)
9478                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9479
9480             if (!(exactValid || prefixValid)) {
9481                 throw new SecurityException("No persistable permission grants found for UID "
9482                         + callingUid + " and Uri " + grantUri.toSafeString());
9483             }
9484
9485             if (exactValid) {
9486                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9487             }
9488             if (prefixValid) {
9489                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9490             }
9491
9492             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9493
9494             if (persistChanged) {
9495                 schedulePersistUriGrants();
9496             }
9497         }
9498     }
9499
9500     /**
9501      * @param uri This uri must NOT contain an embedded userId.
9502      * @param userId The userId in which the uri is to be resolved.
9503      */
9504     @Override
9505     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9506         enforceNotIsolatedCaller("releasePersistableUriPermission");
9507
9508         Preconditions.checkFlagsArgument(modeFlags,
9509                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9510
9511         synchronized (this) {
9512             final int callingUid = Binder.getCallingUid();
9513             boolean persistChanged = false;
9514
9515             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9516                     new GrantUri(userId, uri, false));
9517             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9518                     new GrantUri(userId, uri, true));
9519             if (exactPerm == null && prefixPerm == null) {
9520                 throw new SecurityException("No permission grants found for UID " + callingUid
9521                         + " and Uri " + uri.toSafeString());
9522             }
9523
9524             if (exactPerm != null) {
9525                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9526                 removeUriPermissionIfNeededLocked(exactPerm);
9527             }
9528             if (prefixPerm != null) {
9529                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9530                 removeUriPermissionIfNeededLocked(prefixPerm);
9531             }
9532
9533             if (persistChanged) {
9534                 schedulePersistUriGrants();
9535             }
9536         }
9537     }
9538
9539     /**
9540      * Prune any older {@link UriPermission} for the given UID until outstanding
9541      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9542      *
9543      * @return if any mutations occured that require persisting.
9544      */
9545     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9546         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9547         if (perms == null) return false;
9548         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9549
9550         final ArrayList<UriPermission> persisted = Lists.newArrayList();
9551         for (UriPermission perm : perms.values()) {
9552             if (perm.persistedModeFlags != 0) {
9553                 persisted.add(perm);
9554             }
9555         }
9556
9557         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9558         if (trimCount <= 0) return false;
9559
9560         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9561         for (int i = 0; i < trimCount; i++) {
9562             final UriPermission perm = persisted.get(i);
9563
9564             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9565                     "Trimming grant created at " + perm.persistedCreateTime);
9566
9567             perm.releasePersistableModes(~0);
9568             removeUriPermissionIfNeededLocked(perm);
9569         }
9570
9571         return true;
9572     }
9573
9574     @Override
9575     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9576             String packageName, boolean incoming) {
9577         enforceNotIsolatedCaller("getPersistedUriPermissions");
9578         Preconditions.checkNotNull(packageName, "packageName");
9579
9580         final int callingUid = Binder.getCallingUid();
9581         final int callingUserId = UserHandle.getUserId(callingUid);
9582         final IPackageManager pm = AppGlobals.getPackageManager();
9583         try {
9584             final int packageUid = pm.getPackageUid(packageName,
9585                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9586             if (packageUid != callingUid) {
9587                 throw new SecurityException(
9588                         "Package " + packageName + " does not belong to calling UID " + callingUid);
9589             }
9590         } catch (RemoteException e) {
9591             throw new SecurityException("Failed to verify package name ownership");
9592         }
9593
9594         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9595         synchronized (this) {
9596             if (incoming) {
9597                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9598                         callingUid);
9599                 if (perms == null) {
9600                     Slog.w(TAG, "No permission grants found for " + packageName);
9601                 } else {
9602                     for (UriPermission perm : perms.values()) {
9603                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9604                             result.add(perm.buildPersistedPublicApiObject());
9605                         }
9606                     }
9607                 }
9608             } else {
9609                 final int size = mGrantedUriPermissions.size();
9610                 for (int i = 0; i < size; i++) {
9611                     final ArrayMap<GrantUri, UriPermission> perms =
9612                             mGrantedUriPermissions.valueAt(i);
9613                     for (UriPermission perm : perms.values()) {
9614                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9615                             result.add(perm.buildPersistedPublicApiObject());
9616                         }
9617                     }
9618                 }
9619             }
9620         }
9621         return new ParceledListSlice<android.content.UriPermission>(result);
9622     }
9623
9624     @Override
9625     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9626             String packageName, int userId) {
9627         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9628                 "getGrantedUriPermissions");
9629
9630         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9631         synchronized (this) {
9632             final int size = mGrantedUriPermissions.size();
9633             for (int i = 0; i < size; i++) {
9634                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9635                 for (UriPermission perm : perms.values()) {
9636                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9637                             && perm.persistedModeFlags != 0) {
9638                         result.add(perm.buildPersistedPublicApiObject());
9639                     }
9640                 }
9641             }
9642         }
9643         return new ParceledListSlice<android.content.UriPermission>(result);
9644     }
9645
9646     @Override
9647     public void clearGrantedUriPermissions(String packageName, int userId) {
9648         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9649                 "clearGrantedUriPermissions");
9650         removeUriPermissionsForPackageLocked(packageName, userId, true);
9651     }
9652
9653     @Override
9654     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9655         synchronized (this) {
9656             ProcessRecord app =
9657                 who != null ? getRecordForAppLocked(who) : null;
9658             if (app == null) return;
9659
9660             Message msg = Message.obtain();
9661             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9662             msg.obj = app;
9663             msg.arg1 = waiting ? 1 : 0;
9664             mUiHandler.sendMessage(msg);
9665         }
9666     }
9667
9668     @Override
9669     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9670         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9671         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9672         outInfo.availMem = getFreeMemory();
9673         outInfo.totalMem = getTotalMemory();
9674         outInfo.threshold = homeAppMem;
9675         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9676         outInfo.hiddenAppThreshold = cachedAppMem;
9677         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9678                 ProcessList.SERVICE_ADJ);
9679         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9680                 ProcessList.VISIBLE_APP_ADJ);
9681         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9682                 ProcessList.FOREGROUND_APP_ADJ);
9683     }
9684
9685     // =========================================================
9686     // TASK MANAGEMENT
9687     // =========================================================
9688
9689     @Override
9690     public List<IBinder> getAppTasks(String callingPackage) {
9691         int callingUid = Binder.getCallingUid();
9692         long ident = Binder.clearCallingIdentity();
9693
9694         synchronized(this) {
9695             ArrayList<IBinder> list = new ArrayList<IBinder>();
9696             try {
9697                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9698
9699                 final int N = mRecentTasks.size();
9700                 for (int i = 0; i < N; i++) {
9701                     TaskRecord tr = mRecentTasks.get(i);
9702                     // Skip tasks that do not match the caller.  We don't need to verify
9703                     // callingPackage, because we are also limiting to callingUid and know
9704                     // that will limit to the correct security sandbox.
9705                     if (tr.effectiveUid != callingUid) {
9706                         continue;
9707                     }
9708                     Intent intent = tr.getBaseIntent();
9709                     if (intent == null ||
9710                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9711                         continue;
9712                     }
9713                     ActivityManager.RecentTaskInfo taskInfo =
9714                             createRecentTaskInfoFromTaskRecord(tr);
9715                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9716                     list.add(taskImpl.asBinder());
9717                 }
9718             } finally {
9719                 Binder.restoreCallingIdentity(ident);
9720             }
9721             return list;
9722         }
9723     }
9724
9725     @Override
9726     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9727         final int callingUid = Binder.getCallingUid();
9728         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9729
9730         synchronized(this) {
9731             if (DEBUG_ALL) Slog.v(
9732                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9733
9734             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9735                     callingUid);
9736
9737             // TODO: Improve with MRU list from all ActivityStacks.
9738             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9739         }
9740
9741         return list;
9742     }
9743
9744     /**
9745      * Creates a new RecentTaskInfo from a TaskRecord.
9746      */
9747     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9748         // Update the task description to reflect any changes in the task stack
9749         tr.updateTaskDescription();
9750
9751         // Compose the recent task info
9752         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9753         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9754         rti.persistentId = tr.taskId;
9755         rti.baseIntent = new Intent(tr.getBaseIntent());
9756         rti.origActivity = tr.origActivity;
9757         rti.realActivity = tr.realActivity;
9758         rti.description = tr.lastDescription;
9759         rti.stackId = tr.getStackId();
9760         rti.userId = tr.userId;
9761         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9762         rti.firstActiveTime = tr.firstActiveTime;
9763         rti.lastActiveTime = tr.lastActiveTime;
9764         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9765         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9766         rti.numActivities = 0;
9767         if (tr.mBounds != null) {
9768             rti.bounds = new Rect(tr.mBounds);
9769         }
9770         rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9771         rti.resizeMode = tr.mResizeMode;
9772
9773         ActivityRecord base = null;
9774         ActivityRecord top = null;
9775         ActivityRecord tmp;
9776
9777         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9778             tmp = tr.mActivities.get(i);
9779             if (tmp.finishing) {
9780                 continue;
9781             }
9782             base = tmp;
9783             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9784                 top = base;
9785             }
9786             rti.numActivities++;
9787         }
9788
9789         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9790         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9791
9792         return rti;
9793     }
9794
9795     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9796         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9797                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9798         if (!allowed) {
9799             if (checkPermission(android.Manifest.permission.GET_TASKS,
9800                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9801                 // Temporary compatibility: some existing apps on the system image may
9802                 // still be requesting the old permission and not switched to the new
9803                 // one; if so, we'll still allow them full access.  This means we need
9804                 // to see if they are holding the old permission and are a system app.
9805                 try {
9806                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9807                         allowed = true;
9808                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9809                                 + " is using old GET_TASKS but privileged; allowing");
9810                     }
9811                 } catch (RemoteException e) {
9812                 }
9813             }
9814         }
9815         if (!allowed) {
9816             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9817                     + " does not hold REAL_GET_TASKS; limiting output");
9818         }
9819         return allowed;
9820     }
9821
9822     @Override
9823     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9824             int userId) {
9825         final int callingUid = Binder.getCallingUid();
9826         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9827                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9828
9829         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9830         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9831         synchronized (this) {
9832             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9833                     callingUid);
9834             final boolean detailed = checkCallingPermission(
9835                     android.Manifest.permission.GET_DETAILED_TASKS)
9836                     == PackageManager.PERMISSION_GRANTED;
9837
9838             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9839                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9840                 return ParceledListSlice.emptyList();
9841             }
9842             mRecentTasks.loadUserRecentsLocked(userId);
9843
9844             final int recentsCount = mRecentTasks.size();
9845             ArrayList<ActivityManager.RecentTaskInfo> res =
9846                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9847
9848             final Set<Integer> includedUsers;
9849             if (includeProfiles) {
9850                 includedUsers = mUserController.getProfileIds(userId);
9851             } else {
9852                 includedUsers = new HashSet<>();
9853             }
9854             includedUsers.add(Integer.valueOf(userId));
9855
9856             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9857                 TaskRecord tr = mRecentTasks.get(i);
9858                 // Only add calling user or related users recent tasks
9859                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9860                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9861                     continue;
9862                 }
9863
9864                 if (tr.realActivitySuspended) {
9865                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9866                     continue;
9867                 }
9868
9869                 // Return the entry if desired by the caller.  We always return
9870                 // the first entry, because callers always expect this to be the
9871                 // foreground app.  We may filter others if the caller has
9872                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9873                 // we should exclude the entry.
9874
9875                 if (i == 0
9876                         || withExcluded
9877                         || (tr.intent == null)
9878                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9879                                 == 0)) {
9880                     if (!allowed) {
9881                         // If the caller doesn't have the GET_TASKS permission, then only
9882                         // allow them to see a small subset of tasks -- their own and home.
9883                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9884                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9885                             continue;
9886                         }
9887                     }
9888                     final ActivityStack stack = tr.getStack();
9889                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9890                         if (stack != null && stack.isHomeOrRecentsStack()) {
9891                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9892                                     "Skipping, home or recents stack task: " + tr);
9893                             continue;
9894                         }
9895                     }
9896                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9897                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9898                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9899                                     "Skipping, top task in docked stack: " + tr);
9900                             continue;
9901                         }
9902                     }
9903                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9904                         if (stack != null && stack.isPinnedStack()) {
9905                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9906                                     "Skipping, pinned stack task: " + tr);
9907                             continue;
9908                         }
9909                     }
9910                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9911                         // Don't include auto remove tasks that are finished or finishing.
9912                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9913                                 "Skipping, auto-remove without activity: " + tr);
9914                         continue;
9915                     }
9916                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9917                             && !tr.isAvailable) {
9918                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9919                                 "Skipping, unavail real act: " + tr);
9920                         continue;
9921                     }
9922
9923                     if (!tr.mUserSetupComplete) {
9924                         // Don't include task launched while user is not done setting-up.
9925                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9926                                 "Skipping, user setup not complete: " + tr);
9927                         continue;
9928                     }
9929
9930                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9931                     if (!detailed) {
9932                         rti.baseIntent.replaceExtras((Bundle)null);
9933                     }
9934
9935                     res.add(rti);
9936                     maxNum--;
9937                 }
9938             }
9939             return new ParceledListSlice<>(res);
9940         }
9941     }
9942
9943     @Override
9944     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9945         synchronized (this) {
9946             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9947                     "getTaskThumbnail()");
9948             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9949                     id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9950             if (tr != null) {
9951                 return tr.getTaskThumbnailLocked();
9952             }
9953         }
9954         return null;
9955     }
9956
9957     @Override
9958     public ActivityManager.TaskDescription getTaskDescription(int id) {
9959         synchronized (this) {
9960             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9961                     "getTaskDescription()");
9962             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9963                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9964             if (tr != null) {
9965                 return tr.lastTaskDescription;
9966             }
9967         }
9968         return null;
9969     }
9970
9971     @Override
9972     public int addAppTask(IBinder activityToken, Intent intent,
9973             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9974         final int callingUid = Binder.getCallingUid();
9975         final long callingIdent = Binder.clearCallingIdentity();
9976
9977         try {
9978             synchronized (this) {
9979                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9980                 if (r == null) {
9981                     throw new IllegalArgumentException("Activity does not exist; token="
9982                             + activityToken);
9983                 }
9984                 ComponentName comp = intent.getComponent();
9985                 if (comp == null) {
9986                     throw new IllegalArgumentException("Intent " + intent
9987                             + " must specify explicit component");
9988                 }
9989                 if (thumbnail.getWidth() != mThumbnailWidth
9990                         || thumbnail.getHeight() != mThumbnailHeight) {
9991                     throw new IllegalArgumentException("Bad thumbnail size: got "
9992                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9993                             + mThumbnailWidth + "x" + mThumbnailHeight);
9994                 }
9995                 if (intent.getSelector() != null) {
9996                     intent.setSelector(null);
9997                 }
9998                 if (intent.getSourceBounds() != null) {
9999                     intent.setSourceBounds(null);
10000                 }
10001                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10002                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10003                         // The caller has added this as an auto-remove task...  that makes no
10004                         // sense, so turn off auto-remove.
10005                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10006                     }
10007                 }
10008                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10009                     mLastAddedTaskActivity = null;
10010                 }
10011                 ActivityInfo ainfo = mLastAddedTaskActivity;
10012                 if (ainfo == null) {
10013                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10014                             comp, 0, UserHandle.getUserId(callingUid));
10015                     if (ainfo.applicationInfo.uid != callingUid) {
10016                         throw new SecurityException(
10017                                 "Can't add task for another application: target uid="
10018                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10019                     }
10020                 }
10021
10022                 TaskRecord task = new TaskRecord(this,
10023                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10024                         ainfo, intent, description, new TaskThumbnailInfo());
10025
10026                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10027                 if (trimIdx >= 0) {
10028                     // If this would have caused a trim, then we'll abort because that
10029                     // means it would be added at the end of the list but then just removed.
10030                     return INVALID_TASK_ID;
10031                 }
10032
10033                 final int N = mRecentTasks.size();
10034                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10035                     final TaskRecord tr = mRecentTasks.remove(N - 1);
10036                     tr.removedFromRecents();
10037                 }
10038
10039                 task.inRecents = true;
10040                 mRecentTasks.add(task);
10041                 r.getStack().addTask(task, false, "addAppTask");
10042
10043                 task.setLastThumbnailLocked(thumbnail);
10044                 task.freeLastThumbnail();
10045                 return task.taskId;
10046             }
10047         } finally {
10048             Binder.restoreCallingIdentity(callingIdent);
10049         }
10050     }
10051
10052     @Override
10053     public Point getAppTaskThumbnailSize() {
10054         synchronized (this) {
10055             return new Point(mThumbnailWidth,  mThumbnailHeight);
10056         }
10057     }
10058
10059     @Override
10060     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10061         synchronized (this) {
10062             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10063             if (r != null) {
10064                 r.setTaskDescription(td);
10065                 final TaskRecord task = r.getTask();
10066                 task.updateTaskDescription();
10067                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10068             }
10069         }
10070     }
10071
10072     @Override
10073     public void setTaskResizeable(int taskId, int resizeableMode) {
10074         synchronized (this) {
10075             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10076                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10077             if (task == null) {
10078                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10079                 return;
10080             }
10081             task.setResizeMode(resizeableMode);
10082         }
10083     }
10084
10085     @Override
10086     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10087         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10088         long ident = Binder.clearCallingIdentity();
10089         try {
10090             synchronized (this) {
10091                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10092                 if (task == null) {
10093                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10094                     return;
10095                 }
10096                 // Place the task in the right stack if it isn't there already based on
10097                 // the requested bounds.
10098                 // The stack transition logic is:
10099                 // - a null bounds on a freeform task moves that task to fullscreen
10100                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10101                 //   that task to freeform
10102                 // - otherwise the task is not moved
10103                 int stackId = task.getStackId();
10104                 if (!StackId.isTaskResizeAllowed(stackId)) {
10105                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10106                 }
10107                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10108                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10109                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10110                     stackId = FREEFORM_WORKSPACE_STACK_ID;
10111                 }
10112
10113                 // Reparent the task to the right stack if necessary
10114                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10115                 if (stackId != task.getStackId()) {
10116                     // Defer resume until the task is resized below
10117                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10118                             DEFER_RESUME, "resizeTask");
10119                     preserveWindow = false;
10120                 }
10121
10122                 // After reparenting (which only resizes the task to the stack bounds), resize the
10123                 // task to the actual bounds provided
10124                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10125             }
10126         } finally {
10127             Binder.restoreCallingIdentity(ident);
10128         }
10129     }
10130
10131     @Override
10132     public Rect getTaskBounds(int taskId) {
10133         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10134         long ident = Binder.clearCallingIdentity();
10135         Rect rect = new Rect();
10136         try {
10137             synchronized (this) {
10138                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10139                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10140                 if (task == null) {
10141                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10142                     return rect;
10143                 }
10144                 if (task.getStack() != null) {
10145                     // Return the bounds from window manager since it will be adjusted for various
10146                     // things like the presense of a docked stack for tasks that aren't resizeable.
10147                     task.getWindowContainerBounds(rect);
10148                 } else {
10149                     // Task isn't in window manager yet since it isn't associated with a stack.
10150                     // Return the persist value from activity manager
10151                     if (task.mBounds != null) {
10152                         rect.set(task.mBounds);
10153                     } else if (task.mLastNonFullscreenBounds != null) {
10154                         rect.set(task.mLastNonFullscreenBounds);
10155                     }
10156                 }
10157             }
10158         } finally {
10159             Binder.restoreCallingIdentity(ident);
10160         }
10161         return rect;
10162     }
10163
10164     @Override
10165     public void cancelTaskWindowTransition(int taskId) {
10166         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10167         final long ident = Binder.clearCallingIdentity();
10168         try {
10169             synchronized (this) {
10170                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10171                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10172                 if (task == null) {
10173                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10174                     return;
10175                 }
10176                 task.cancelWindowTransition();
10177             }
10178         } finally {
10179             Binder.restoreCallingIdentity(ident);
10180         }
10181     }
10182
10183     @Override
10184     public void cancelTaskThumbnailTransition(int taskId) {
10185         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10186         final long ident = Binder.clearCallingIdentity();
10187         try {
10188             synchronized (this) {
10189                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10190                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10191                 if (task == null) {
10192                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10193                     return;
10194                 }
10195                 task.cancelThumbnailTransition();
10196             }
10197         } finally {
10198             Binder.restoreCallingIdentity(ident);
10199         }
10200     }
10201
10202     @Override
10203     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10204         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10205         final long ident = Binder.clearCallingIdentity();
10206         try {
10207             final TaskRecord task;
10208             synchronized (this) {
10209                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10210                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10211                 if (task == null) {
10212                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10213                     return null;
10214                 }
10215             }
10216             // Don't call this while holding the lock as this operation might hit the disk.
10217             return task.getSnapshot(reducedResolution);
10218         } finally {
10219             Binder.restoreCallingIdentity(ident);
10220         }
10221     }
10222
10223     @Override
10224     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10225         if (userId != UserHandle.getCallingUserId()) {
10226             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10227                     "getTaskDescriptionIcon");
10228         }
10229         final File passedIconFile = new File(filePath);
10230         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10231                 passedIconFile.getName());
10232         if (!legitIconFile.getPath().equals(filePath)
10233                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10234             throw new IllegalArgumentException("Bad file path: " + filePath
10235                     + " passed for userId " + userId);
10236         }
10237         return mRecentTasks.getTaskDescriptionIcon(filePath);
10238     }
10239
10240     @Override
10241     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10242             throws RemoteException {
10243         final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10244         if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10245                 activityOptions.getCustomInPlaceResId() == 0) {
10246             throw new IllegalArgumentException("Expected in-place ActivityOption " +
10247                     "with valid animation");
10248         }
10249         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10250         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10251                 activityOptions.getCustomInPlaceResId());
10252         mWindowManager.executeAppTransition();
10253     }
10254
10255     private void removeTasksByPackageNameLocked(String packageName, int userId) {
10256         // Remove all tasks with activities in the specified package from the list of recent tasks
10257         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10258             TaskRecord tr = mRecentTasks.get(i);
10259             if (tr.userId != userId) continue;
10260
10261             ComponentName cn = tr.intent.getComponent();
10262             if (cn != null && cn.getPackageName().equals(packageName)) {
10263                 // If the package name matches, remove the task.
10264                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10265             }
10266         }
10267     }
10268
10269     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10270             int userId) {
10271
10272         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10273             TaskRecord tr = mRecentTasks.get(i);
10274             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10275                 continue;
10276             }
10277
10278             ComponentName cn = tr.intent.getComponent();
10279             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10280                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10281             if (sameComponent) {
10282                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10283             }
10284         }
10285     }
10286
10287     @Override
10288     public void removeStack(int stackId) {
10289         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10290         if (StackId.isHomeOrRecentsStack(stackId)) {
10291             throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10292         }
10293
10294         synchronized (this) {
10295             final long ident = Binder.clearCallingIdentity();
10296             try {
10297                 mStackSupervisor.removeStackLocked(stackId);
10298             } finally {
10299                 Binder.restoreCallingIdentity(ident);
10300             }
10301         }
10302     }
10303
10304     @Override
10305     public void moveStackToDisplay(int stackId, int displayId) {
10306         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10307
10308         synchronized (this) {
10309             final long ident = Binder.clearCallingIdentity();
10310             try {
10311                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10312                         + " to displayId=" + displayId);
10313                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10314             } finally {
10315                 Binder.restoreCallingIdentity(ident);
10316             }
10317         }
10318     }
10319
10320     @Override
10321     public boolean removeTask(int taskId) {
10322         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10323         synchronized (this) {
10324             final long ident = Binder.clearCallingIdentity();
10325             try {
10326                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10327             } finally {
10328                 Binder.restoreCallingIdentity(ident);
10329             }
10330         }
10331     }
10332
10333     /**
10334      * TODO: Add mController hook
10335      */
10336     @Override
10337     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10338         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10339
10340         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10341         synchronized(this) {
10342             moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10343         }
10344     }
10345
10346     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10347         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10348
10349         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10350                 Binder.getCallingUid(), -1, -1, "Task to front")) {
10351             ActivityOptions.abort(options);
10352             return;
10353         }
10354         final long origId = Binder.clearCallingIdentity();
10355         try {
10356             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10357             if (task == null) {
10358                 Slog.d(TAG, "Could not find task for id: "+ taskId);
10359                 return;
10360             }
10361             if (mStackSupervisor.isLockTaskModeViolation(task)) {
10362                 mStackSupervisor.showLockTaskToast();
10363                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10364                 return;
10365             }
10366             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10367             if (prev != null) {
10368                 task.setTaskToReturnTo(prev);
10369             }
10370             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10371                     false /* forceNonResizable */);
10372
10373             final ActivityRecord topActivity = task.getTopActivity();
10374             if (topActivity != null) {
10375
10376                 // We are reshowing a task, use a starting window to hide the initial draw delay
10377                 // so the transition can start earlier.
10378                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10379                         true /* taskSwitch */, fromRecents);
10380             }
10381         } finally {
10382             Binder.restoreCallingIdentity(origId);
10383         }
10384         ActivityOptions.abort(options);
10385     }
10386
10387     /**
10388      * Attempts to move a task backwards in z-order (the order of activities within the task is
10389      * unchanged).
10390      *
10391      * There are several possible results of this call:
10392      * - if the task is locked, then we will show the lock toast
10393      * - if there is a task behind the provided task, then that task is made visible and resumed as
10394      *   this task is moved to the back
10395      * - otherwise, if there are no other tasks in the stack:
10396      *     - if this task is in the pinned stack, then we remove the stack completely, which will
10397      *       have the effect of moving the task to the top or bottom of the fullscreen stack
10398      *       (depending on whether it is visible)
10399      *     - otherwise, we simply return home and hide this task
10400      *
10401      * @param token A reference to the activity we wish to move
10402      * @param nonRoot If false then this only works if the activity is the root
10403      *                of a task; if true it will work for any activity in a task.
10404      * @return Returns true if the move completed, false if not.
10405      */
10406     @Override
10407     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10408         enforceNotIsolatedCaller("moveActivityTaskToBack");
10409         synchronized(this) {
10410             final long origId = Binder.clearCallingIdentity();
10411             try {
10412                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10413                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10414                 if (task != null) {
10415                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10416                 }
10417             } finally {
10418                 Binder.restoreCallingIdentity(origId);
10419             }
10420         }
10421         return false;
10422     }
10423
10424     @Override
10425     public void moveTaskBackwards(int task) {
10426         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10427                 "moveTaskBackwards()");
10428
10429         synchronized(this) {
10430             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10431                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
10432                 return;
10433             }
10434             final long origId = Binder.clearCallingIdentity();
10435             moveTaskBackwardsLocked(task);
10436             Binder.restoreCallingIdentity(origId);
10437         }
10438     }
10439
10440     private final void moveTaskBackwardsLocked(int task) {
10441         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10442     }
10443
10444     @Override
10445     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10446             IActivityContainerCallback callback) throws RemoteException {
10447         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10448         synchronized (this) {
10449             if (parentActivityToken == null) {
10450                 throw new IllegalArgumentException("parent token must not be null");
10451             }
10452             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10453             if (r == null) {
10454                 return null;
10455             }
10456             if (callback == null) {
10457                 throw new IllegalArgumentException("callback must not be null");
10458             }
10459             return mStackSupervisor.createVirtualActivityContainer(r, callback);
10460         }
10461     }
10462
10463     @Override
10464     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10465         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10466         synchronized (this) {
10467             final int stackId = mStackSupervisor.getNextStackId();
10468             final ActivityStack stack =
10469                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10470             if (stack == null) {
10471                 return null;
10472             }
10473             return stack.mActivityContainer;
10474         }
10475     }
10476
10477     @Override
10478     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10479         synchronized (this) {
10480             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10481             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10482                 return stack.mActivityContainer.getDisplayId();
10483             }
10484             return DEFAULT_DISPLAY;
10485         }
10486     }
10487
10488     @Override
10489     public int getActivityStackId(IBinder token) throws RemoteException {
10490         synchronized (this) {
10491             ActivityStack stack = ActivityRecord.getStackLocked(token);
10492             if (stack == null) {
10493                 return INVALID_STACK_ID;
10494             }
10495             return stack.mStackId;
10496         }
10497     }
10498
10499     @Override
10500     public void exitFreeformMode(IBinder token) throws RemoteException {
10501         synchronized (this) {
10502             long ident = Binder.clearCallingIdentity();
10503             try {
10504                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10505                 if (r == null) {
10506                     throw new IllegalArgumentException(
10507                             "exitFreeformMode: No activity record matching token=" + token);
10508                 }
10509
10510                 final ActivityStack stack = r.getStack();
10511                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10512                     throw new IllegalStateException(
10513                             "exitFreeformMode: You can only go fullscreen from freeform.");
10514                 }
10515
10516                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10517                 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10518                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10519             } finally {
10520                 Binder.restoreCallingIdentity(ident);
10521             }
10522         }
10523     }
10524
10525     @Override
10526     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10527         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10528         if (StackId.isHomeOrRecentsStack(stackId)) {
10529             throw new IllegalArgumentException(
10530                     "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10531         }
10532         synchronized (this) {
10533             long ident = Binder.clearCallingIdentity();
10534             try {
10535                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10536                 if (task == null) {
10537                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10538                     return;
10539                 }
10540
10541                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10542                         + " to stackId=" + stackId + " toTop=" + toTop);
10543                 if (stackId == DOCKED_STACK_ID) {
10544                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10545                             null /* initialBounds */);
10546                 }
10547                 task.reparent(stackId, toTop,
10548                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10549             } finally {
10550                 Binder.restoreCallingIdentity(ident);
10551             }
10552         }
10553     }
10554
10555     @Override
10556     public void swapDockedAndFullscreenStack() throws RemoteException {
10557         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10558         synchronized (this) {
10559             long ident = Binder.clearCallingIdentity();
10560             try {
10561                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10562                         FULLSCREEN_WORKSPACE_STACK_ID);
10563                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10564                         : null;
10565                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10566                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10567                         : null;
10568                 if (topTask == null || tasks == null || tasks.size() == 0) {
10569                     Slog.w(TAG,
10570                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
10571                     return;
10572                 }
10573
10574                 // TODO: App transition
10575                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10576
10577                 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10578                 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10579                         DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10580                 final int size = tasks.size();
10581                 for (int i = 0; i < size; i++) {
10582                     final int id = tasks.get(i).taskId;
10583                     if (id == topTask.taskId) {
10584                         continue;
10585                     }
10586
10587                     // Defer the resume until after all the tasks have been moved
10588                     tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10589                             REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10590                             "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10591                 }
10592
10593                 // Because we deferred the resume to avoid conflicts with stack switches while
10594                 // resuming, we need to do it after all the tasks are moved.
10595                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10596                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10597
10598                 mWindowManager.executeAppTransition();
10599             } finally {
10600                 Binder.restoreCallingIdentity(ident);
10601             }
10602         }
10603     }
10604
10605     /**
10606      * Moves the input task to the docked stack.
10607      *
10608      * @param taskId Id of task to move.
10609      * @param createMode The mode the docked stack should be created in if it doesn't exist
10610      *                   already. See
10611      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10612      *                   and
10613      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10614      * @param toTop If the task and stack should be moved to the top.
10615      * @param animate Whether we should play an animation for the moving the task
10616      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10617      *                      docked stack. Pass {@code null} to use default bounds.
10618      */
10619     @Override
10620     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10621             Rect initialBounds) {
10622         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10623         synchronized (this) {
10624             long ident = Binder.clearCallingIdentity();
10625             try {
10626                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10627                 if (task == null) {
10628                     Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10629                     return false;
10630                 }
10631
10632                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10633                         + " to createMode=" + createMode + " toTop=" + toTop);
10634                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10635
10636                 // Defer resuming until we move the home stack to the front below
10637                 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10638                         REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10639                         "moveTaskToDockedStack");
10640                 if (moved) {
10641                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10642                 }
10643                 return moved;
10644             } finally {
10645                 Binder.restoreCallingIdentity(ident);
10646             }
10647         }
10648     }
10649
10650     /**
10651      * Moves the top activity in the input stackId to the pinned stack.
10652      *
10653      * @param stackId Id of stack to move the top activity to pinned stack.
10654      * @param bounds Bounds to use for pinned stack.
10655      *
10656      * @return True if the top activity of the input stack was successfully moved to the pinned
10657      *          stack.
10658      */
10659     @Override
10660     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10661         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10662         synchronized (this) {
10663             if (!mSupportsPictureInPicture) {
10664                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10665                         + "Device doesn't support picture-in-picture mode");
10666             }
10667
10668             long ident = Binder.clearCallingIdentity();
10669             try {
10670                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10671             } finally {
10672                 Binder.restoreCallingIdentity(ident);
10673             }
10674         }
10675     }
10676
10677     @Override
10678     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10679             boolean preserveWindows, boolean animate, int animationDuration) {
10680         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10681         long ident = Binder.clearCallingIdentity();
10682         try {
10683             synchronized (this) {
10684                 if (animate) {
10685                     if (stackId == PINNED_STACK_ID) {
10686                         final PinnedActivityStack pinnedStack =
10687                                 mStackSupervisor.getStack(PINNED_STACK_ID);
10688                         if (pinnedStack != null) {
10689                             pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10690                                     destBounds, animationDuration, false /* fromFullscreen */);
10691                         }
10692                     } else {
10693                         throw new IllegalArgumentException("Stack: " + stackId
10694                                 + " doesn't support animated resize.");
10695                     }
10696                 } else {
10697                     mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10698                             null /* tempTaskInsetBounds */, preserveWindows,
10699                             allowResizeInDockedMode, !DEFER_RESUME);
10700                 }
10701             }
10702         } finally {
10703             Binder.restoreCallingIdentity(ident);
10704         }
10705     }
10706
10707     @Override
10708     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10709             Rect tempDockedTaskInsetBounds,
10710             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10711         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10712                 "resizeDockedStack()");
10713         long ident = Binder.clearCallingIdentity();
10714         try {
10715             synchronized (this) {
10716                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10717                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10718                         PRESERVE_WINDOWS);
10719             }
10720         } finally {
10721             Binder.restoreCallingIdentity(ident);
10722         }
10723     }
10724
10725     @Override
10726     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10727         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10728                 "resizePinnedStack()");
10729         final long ident = Binder.clearCallingIdentity();
10730         try {
10731             synchronized (this) {
10732                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10733             }
10734         } finally {
10735             Binder.restoreCallingIdentity(ident);
10736         }
10737     }
10738
10739     /**
10740      * Try to place task to provided position. The final position might be different depending on
10741      * current user and stacks state. The task will be moved to target stack if it's currently in
10742      * different stack.
10743      */
10744     @Override
10745     public void positionTaskInStack(int taskId, int stackId, int position) {
10746         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10747         if (StackId.isHomeOrRecentsStack(stackId)) {
10748             throw new IllegalArgumentException(
10749                     "positionTaskInStack: Attempt to change the position of task "
10750                     + taskId + " in/to home/recents stack");
10751         }
10752         synchronized (this) {
10753             long ident = Binder.clearCallingIdentity();
10754             try {
10755                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10756                         + taskId + " in stackId=" + stackId + " at position=" + position);
10757                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10758                 if (task == null) {
10759                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
10760                             + taskId);
10761                 }
10762
10763                 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10764                         !ON_TOP);
10765
10766                 // TODO: Have the callers of this API call a separate reparent method if that is
10767                 // what they intended to do vs. having this method also do reparenting.
10768                 if (task.getStack() == stack) {
10769                     // Change position in current stack.
10770                     stack.positionChildAt(task, position);
10771                 } else {
10772                     // Reparent to new stack.
10773                     task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10774                             !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10775                 }
10776             } finally {
10777                 Binder.restoreCallingIdentity(ident);
10778             }
10779         }
10780     }
10781
10782     @Override
10783     public List<StackInfo> getAllStackInfos() {
10784         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10785         long ident = Binder.clearCallingIdentity();
10786         try {
10787             synchronized (this) {
10788                 return mStackSupervisor.getAllStackInfosLocked();
10789             }
10790         } finally {
10791             Binder.restoreCallingIdentity(ident);
10792         }
10793     }
10794
10795     @Override
10796     public StackInfo getStackInfo(int stackId) {
10797         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10798         long ident = Binder.clearCallingIdentity();
10799         try {
10800             synchronized (this) {
10801                 return mStackSupervisor.getStackInfoLocked(stackId);
10802             }
10803         } finally {
10804             Binder.restoreCallingIdentity(ident);
10805         }
10806     }
10807
10808     @Override
10809     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10810         synchronized(this) {
10811             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10812         }
10813     }
10814
10815     @Override
10816     public void updateDeviceOwner(String packageName) {
10817         final int callingUid = Binder.getCallingUid();
10818         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10819             throw new SecurityException("updateDeviceOwner called from non-system process");
10820         }
10821         synchronized (this) {
10822             mDeviceOwnerName = packageName;
10823         }
10824     }
10825
10826     @Override
10827     public void updateLockTaskPackages(int userId, String[] packages) {
10828         final int callingUid = Binder.getCallingUid();
10829         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10830             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10831                     "updateLockTaskPackages()");
10832         }
10833         synchronized (this) {
10834             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10835                     Arrays.toString(packages));
10836             mLockTaskPackages.put(userId, packages);
10837             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10838         }
10839     }
10840
10841
10842     void startLockTaskModeLocked(TaskRecord task) {
10843         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10844         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10845             return;
10846         }
10847
10848         // When a task is locked, dismiss the pinned stack if it exists
10849         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10850                 PINNED_STACK_ID);
10851         if (pinnedStack != null) {
10852             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10853         }
10854
10855         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10856         // is initiated by system after the pinning request was shown and locked mode is initiated
10857         // by an authorized app directly
10858         final int callingUid = Binder.getCallingUid();
10859         boolean isSystemInitiated = callingUid == SYSTEM_UID;
10860         long ident = Binder.clearCallingIdentity();
10861         try {
10862             if (!isSystemInitiated) {
10863                 task.mLockTaskUid = callingUid;
10864                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10865                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10866                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10867                     StatusBarManagerInternal statusBarManager =
10868                             LocalServices.getService(StatusBarManagerInternal.class);
10869                     if (statusBarManager != null) {
10870                         statusBarManager.showScreenPinningRequest(task.taskId);
10871                     }
10872                     return;
10873                 }
10874
10875                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10876                 if (stack == null || task != stack.topTask()) {
10877                     throw new IllegalArgumentException("Invalid task, not in foreground");
10878                 }
10879             }
10880             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10881                     "Locking fully");
10882             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10883                     ActivityManager.LOCK_TASK_MODE_PINNED :
10884                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10885                     "startLockTask", true);
10886         } finally {
10887             Binder.restoreCallingIdentity(ident);
10888         }
10889     }
10890
10891     @Override
10892     public void startLockTaskModeById(int taskId) {
10893         synchronized (this) {
10894             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10895             if (task != null) {
10896                 startLockTaskModeLocked(task);
10897             }
10898         }
10899     }
10900
10901     @Override
10902     public void startLockTaskModeByToken(IBinder token) {
10903         synchronized (this) {
10904             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10905             if (r == null) {
10906                 return;
10907             }
10908             final TaskRecord task = r.getTask();
10909             if (task != null) {
10910                 startLockTaskModeLocked(task);
10911             }
10912         }
10913     }
10914
10915     @Override
10916     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10917         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10918         // This makes inner call to look as if it was initiated by system.
10919         long ident = Binder.clearCallingIdentity();
10920         try {
10921             synchronized (this) {
10922                 startLockTaskModeById(taskId);
10923             }
10924         } finally {
10925             Binder.restoreCallingIdentity(ident);
10926         }
10927     }
10928
10929     @Override
10930     public void stopLockTaskMode() {
10931         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10932         if (lockTask == null) {
10933             // Our work here is done.
10934             return;
10935         }
10936
10937         final int callingUid = Binder.getCallingUid();
10938         final int lockTaskUid = lockTask.mLockTaskUid;
10939         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10940         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10941             // Done.
10942             return;
10943         } else {
10944             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10945             // It is possible lockTaskMode was started by the system process because
10946             // android:lockTaskMode is set to a locking value in the application manifest
10947             // instead of the app calling startLockTaskMode. In this case
10948             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10949             // {@link TaskRecord.effectiveUid} instead. Also caller with
10950             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10951             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10952                     && callingUid != lockTaskUid
10953                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10954                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10955                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10956             }
10957         }
10958         long ident = Binder.clearCallingIdentity();
10959         try {
10960             Log.d(TAG, "stopLockTaskMode");
10961             // Stop lock task
10962             synchronized (this) {
10963                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10964                         "stopLockTask", true);
10965             }
10966             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10967             if (tm != null) {
10968                 tm.showInCallScreen(false);
10969             }
10970         } finally {
10971             Binder.restoreCallingIdentity(ident);
10972         }
10973     }
10974
10975     /**
10976      * This API should be called by SystemUI only when user perform certain action to dismiss
10977      * lock task mode. We should only dismiss pinned lock task mode in this case.
10978      */
10979     @Override
10980     public void stopSystemLockTaskMode() throws RemoteException {
10981         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10982             stopLockTaskMode();
10983         } else {
10984             mStackSupervisor.showLockTaskToast();
10985         }
10986     }
10987
10988     @Override
10989     public boolean isInLockTaskMode() {
10990         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10991     }
10992
10993     @Override
10994     public int getLockTaskModeState() {
10995         synchronized (this) {
10996             return mStackSupervisor.getLockTaskModeState();
10997         }
10998     }
10999
11000     @Override
11001     public void showLockTaskEscapeMessage(IBinder token) {
11002         synchronized (this) {
11003             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11004             if (r == null) {
11005                 return;
11006             }
11007             mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11008         }
11009     }
11010
11011     @Override
11012     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11013             throws RemoteException {
11014         synchronized (this) {
11015             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11016             if (r == null) {
11017                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11018                         + token);
11019                 return;
11020             }
11021             final long origId = Binder.clearCallingIdentity();
11022             try {
11023                 r.setDisablePreviewScreenshots(disable);
11024             } finally {
11025                 Binder.restoreCallingIdentity(origId);
11026             }
11027         }
11028     }
11029
11030     // =========================================================
11031     // CONTENT PROVIDERS
11032     // =========================================================
11033
11034     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11035         List<ProviderInfo> providers = null;
11036         try {
11037             providers = AppGlobals.getPackageManager()
11038                     .queryContentProviders(app.processName, app.uid,
11039                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11040                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11041                     .getList();
11042         } catch (RemoteException ex) {
11043         }
11044         if (DEBUG_MU) Slog.v(TAG_MU,
11045                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11046         int userId = app.userId;
11047         if (providers != null) {
11048             int N = providers.size();
11049             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11050             for (int i=0; i<N; i++) {
11051                 // TODO: keep logic in sync with installEncryptionUnawareProviders
11052                 ProviderInfo cpi =
11053                     (ProviderInfo)providers.get(i);
11054                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11055                         cpi.name, cpi.flags);
11056                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11057                     // This is a singleton provider, but a user besides the
11058                     // default user is asking to initialize a process it runs
11059                     // in...  well, no, it doesn't actually run in this process,
11060                     // it runs in the process of the default user.  Get rid of it.
11061                     providers.remove(i);
11062                     N--;
11063                     i--;
11064                     continue;
11065                 }
11066
11067                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11068                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11069                 if (cpr == null) {
11070                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11071                     mProviderMap.putProviderByClass(comp, cpr);
11072                 }
11073                 if (DEBUG_MU) Slog.v(TAG_MU,
11074                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11075                 app.pubProviders.put(cpi.name, cpr);
11076                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11077                     // Don't add this if it is a platform component that is marked
11078                     // to run in multiple processes, because this is actually
11079                     // part of the framework so doesn't make sense to track as a
11080                     // separate apk in the process.
11081                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11082                             mProcessStats);
11083                 }
11084                 notifyPackageUse(cpi.applicationInfo.packageName,
11085                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11086             }
11087         }
11088         return providers;
11089     }
11090
11091     /**
11092      * Check if the calling UID has a possible chance at accessing the provider
11093      * at the given authority and user.
11094      */
11095     public String checkContentProviderAccess(String authority, int userId) {
11096         if (userId == UserHandle.USER_ALL) {
11097             mContext.enforceCallingOrSelfPermission(
11098                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11099             userId = UserHandle.getCallingUserId();
11100         }
11101
11102         ProviderInfo cpi = null;
11103         try {
11104             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11105                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11106                             | PackageManager.MATCH_DISABLED_COMPONENTS
11107                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
11108                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11109                     userId);
11110         } catch (RemoteException ignored) {
11111         }
11112         if (cpi == null) {
11113             return "Failed to find provider " + authority + " for user " + userId
11114                     + "; expected to find a valid ContentProvider for this authority";
11115         }
11116
11117         ProcessRecord r = null;
11118         synchronized (mPidsSelfLocked) {
11119             r = mPidsSelfLocked.get(Binder.getCallingPid());
11120         }
11121         if (r == null) {
11122             return "Failed to find PID " + Binder.getCallingPid();
11123         }
11124
11125         synchronized (this) {
11126             return checkContentProviderPermissionLocked(cpi, r, userId, true);
11127         }
11128     }
11129
11130     /**
11131      * Check if {@link ProcessRecord} has a possible chance at accessing the
11132      * given {@link ProviderInfo}. Final permission checking is always done
11133      * in {@link ContentProvider}.
11134      */
11135     private final String checkContentProviderPermissionLocked(
11136             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11137         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11138         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11139         boolean checkedGrants = false;
11140         if (checkUser) {
11141             // Looking for cross-user grants before enforcing the typical cross-users permissions
11142             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11143             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11144                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11145                     return null;
11146                 }
11147                 checkedGrants = true;
11148             }
11149             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11150                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11151             if (userId != tmpTargetUserId) {
11152                 // When we actually went to determine the final targer user ID, this ended
11153                 // up different than our initial check for the authority.  This is because
11154                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11155                 // SELF.  So we need to re-check the grants again.
11156                 checkedGrants = false;
11157             }
11158         }
11159         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11160                 cpi.applicationInfo.uid, cpi.exported)
11161                 == PackageManager.PERMISSION_GRANTED) {
11162             return null;
11163         }
11164         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11165                 cpi.applicationInfo.uid, cpi.exported)
11166                 == PackageManager.PERMISSION_GRANTED) {
11167             return null;
11168         }
11169
11170         PathPermission[] pps = cpi.pathPermissions;
11171         if (pps != null) {
11172             int i = pps.length;
11173             while (i > 0) {
11174                 i--;
11175                 PathPermission pp = pps[i];
11176                 String pprperm = pp.getReadPermission();
11177                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11178                         cpi.applicationInfo.uid, cpi.exported)
11179                         == PackageManager.PERMISSION_GRANTED) {
11180                     return null;
11181                 }
11182                 String ppwperm = pp.getWritePermission();
11183                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11184                         cpi.applicationInfo.uid, cpi.exported)
11185                         == PackageManager.PERMISSION_GRANTED) {
11186                     return null;
11187                 }
11188             }
11189         }
11190         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11191             return null;
11192         }
11193
11194         final String suffix;
11195         if (!cpi.exported) {
11196             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11197         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11198             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11199         } else {
11200             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11201         }
11202         final String msg = "Permission Denial: opening provider " + cpi.name
11203                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11204                 + ", uid=" + callingUid + ")" + suffix;
11205         Slog.w(TAG, msg);
11206         return msg;
11207     }
11208
11209     /**
11210      * Returns if the ContentProvider has granted a uri to callingUid
11211      */
11212     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11213         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11214         if (perms != null) {
11215             for (int i=perms.size()-1; i>=0; i--) {
11216                 GrantUri grantUri = perms.keyAt(i);
11217                 if (grantUri.sourceUserId == userId || !checkUser) {
11218                     if (matchesProvider(grantUri.uri, cpi)) {
11219                         return true;
11220                     }
11221                 }
11222             }
11223         }
11224         return false;
11225     }
11226
11227     /**
11228      * Returns true if the uri authority is one of the authorities specified in the provider.
11229      */
11230     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11231         String uriAuth = uri.getAuthority();
11232         String cpiAuth = cpi.authority;
11233         if (cpiAuth.indexOf(';') == -1) {
11234             return cpiAuth.equals(uriAuth);
11235         }
11236         String[] cpiAuths = cpiAuth.split(";");
11237         int length = cpiAuths.length;
11238         for (int i = 0; i < length; i++) {
11239             if (cpiAuths[i].equals(uriAuth)) return true;
11240         }
11241         return false;
11242     }
11243
11244     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11245             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11246         if (r != null) {
11247             for (int i=0; i<r.conProviders.size(); i++) {
11248                 ContentProviderConnection conn = r.conProviders.get(i);
11249                 if (conn.provider == cpr) {
11250                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11251                             "Adding provider requested by "
11252                             + r.processName + " from process "
11253                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11254                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11255                     if (stable) {
11256                         conn.stableCount++;
11257                         conn.numStableIncs++;
11258                     } else {
11259                         conn.unstableCount++;
11260                         conn.numUnstableIncs++;
11261                     }
11262                     return conn;
11263                 }
11264             }
11265             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11266             if (stable) {
11267                 conn.stableCount = 1;
11268                 conn.numStableIncs = 1;
11269             } else {
11270                 conn.unstableCount = 1;
11271                 conn.numUnstableIncs = 1;
11272             }
11273             cpr.connections.add(conn);
11274             r.conProviders.add(conn);
11275             startAssociationLocked(r.uid, r.processName, r.curProcState,
11276                     cpr.uid, cpr.name, cpr.info.processName);
11277             return conn;
11278         }
11279         cpr.addExternalProcessHandleLocked(externalProcessToken);
11280         return null;
11281     }
11282
11283     boolean decProviderCountLocked(ContentProviderConnection conn,
11284             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11285         if (conn != null) {
11286             cpr = conn.provider;
11287             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11288                     "Removing provider requested by "
11289                     + conn.client.processName + " from process "
11290                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11291                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11292             if (stable) {
11293                 conn.stableCount--;
11294             } else {
11295                 conn.unstableCount--;
11296             }
11297             if (conn.stableCount == 0 && conn.unstableCount == 0) {
11298                 cpr.connections.remove(conn);
11299                 conn.client.conProviders.remove(conn);
11300                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11301                     // The client is more important than last activity -- note the time this
11302                     // is happening, so we keep the old provider process around a bit as last
11303                     // activity to avoid thrashing it.
11304                     if (cpr.proc != null) {
11305                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11306                     }
11307                 }
11308                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11309                 return true;
11310             }
11311             return false;
11312         }
11313         cpr.removeExternalProcessHandleLocked(externalProcessToken);
11314         return false;
11315     }
11316
11317     private void checkTime(long startTime, String where) {
11318         long now = SystemClock.uptimeMillis();
11319         if ((now-startTime) > 50) {
11320             // If we are taking more than 50ms, log about it.
11321             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11322         }
11323     }
11324
11325     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11326             PROC_SPACE_TERM,
11327             PROC_SPACE_TERM|PROC_PARENS,
11328             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11329     };
11330
11331     private final long[] mProcessStateStatsLongs = new long[1];
11332
11333     boolean isProcessAliveLocked(ProcessRecord proc) {
11334         if (proc.procStatFile == null) {
11335             proc.procStatFile = "/proc/" + proc.pid + "/stat";
11336         }
11337         mProcessStateStatsLongs[0] = 0;
11338         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11339                 mProcessStateStatsLongs, null)) {
11340             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11341             return false;
11342         }
11343         final long state = mProcessStateStatsLongs[0];
11344         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11345                 + (char)state);
11346         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11347     }
11348
11349     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11350             String name, IBinder token, boolean stable, int userId) {
11351         ContentProviderRecord cpr;
11352         ContentProviderConnection conn = null;
11353         ProviderInfo cpi = null;
11354
11355         synchronized(this) {
11356             long startTime = SystemClock.uptimeMillis();
11357
11358             ProcessRecord r = null;
11359             if (caller != null) {
11360                 r = getRecordForAppLocked(caller);
11361                 if (r == null) {
11362                     throw new SecurityException(
11363                             "Unable to find app for caller " + caller
11364                           + " (pid=" + Binder.getCallingPid()
11365                           + ") when getting content provider " + name);
11366                 }
11367             }
11368
11369             boolean checkCrossUser = true;
11370
11371             checkTime(startTime, "getContentProviderImpl: getProviderByName");
11372
11373             // First check if this content provider has been published...
11374             cpr = mProviderMap.getProviderByName(name, userId);
11375             // If that didn't work, check if it exists for user 0 and then
11376             // verify that it's a singleton provider before using it.
11377             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11378                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11379                 if (cpr != null) {
11380                     cpi = cpr.info;
11381                     if (isSingleton(cpi.processName, cpi.applicationInfo,
11382                             cpi.name, cpi.flags)
11383                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11384                         userId = UserHandle.USER_SYSTEM;
11385                         checkCrossUser = false;
11386                     } else {
11387                         cpr = null;
11388                         cpi = null;
11389                     }
11390                 }
11391             }
11392
11393             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11394             if (providerRunning) {
11395                 cpi = cpr.info;
11396                 String msg;
11397                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11398                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11399                         != null) {
11400                     throw new SecurityException(msg);
11401                 }
11402                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11403
11404                 if (r != null && cpr.canRunHere(r)) {
11405                     // This provider has been published or is in the process
11406                     // of being published...  but it is also allowed to run
11407                     // in the caller's process, so don't make a connection
11408                     // and just let the caller instantiate its own instance.
11409                     ContentProviderHolder holder = cpr.newHolder(null);
11410                     // don't give caller the provider object, it needs
11411                     // to make its own.
11412                     holder.provider = null;
11413                     return holder;
11414                 }
11415                 // Don't expose providers between normal apps and instant apps
11416                 try {
11417                     if (AppGlobals.getPackageManager()
11418                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11419                         return null;
11420                     }
11421                 } catch (RemoteException e) {
11422                 }
11423
11424                 final long origId = Binder.clearCallingIdentity();
11425
11426                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11427
11428                 // In this case the provider instance already exists, so we can
11429                 // return it right away.
11430                 conn = incProviderCountLocked(r, cpr, token, stable);
11431                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11432                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11433                         // If this is a perceptible app accessing the provider,
11434                         // make sure to count it as being accessed and thus
11435                         // back up on the LRU list.  This is good because
11436                         // content providers are often expensive to start.
11437                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11438                         updateLruProcessLocked(cpr.proc, false, null);
11439                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11440                     }
11441                 }
11442
11443                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11444                 final int verifiedAdj = cpr.proc.verifiedAdj;
11445                 boolean success = updateOomAdjLocked(cpr.proc, true);
11446                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11447                 // if the process has been successfully adjusted.  So to reduce races with
11448                 // it, we will check whether the process still exists.  Note that this doesn't
11449                 // completely get rid of races with LMK killing the process, but should make
11450                 // them much smaller.
11451                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11452                     success = false;
11453                 }
11454                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11455                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11456                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11457                 // NOTE: there is still a race here where a signal could be
11458                 // pending on the process even though we managed to update its
11459                 // adj level.  Not sure what to do about this, but at least
11460                 // the race is now smaller.
11461                 if (!success) {
11462                     // Uh oh...  it looks like the provider's process
11463                     // has been killed on us.  We need to wait for a new
11464                     // process to be started, and make sure its death
11465                     // doesn't kill our process.
11466                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11467                             + " is crashing; detaching " + r);
11468                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11469                     checkTime(startTime, "getContentProviderImpl: before appDied");
11470                     appDiedLocked(cpr.proc);
11471                     checkTime(startTime, "getContentProviderImpl: after appDied");
11472                     if (!lastRef) {
11473                         // This wasn't the last ref our process had on
11474                         // the provider...  we have now been killed, bail.
11475                         return null;
11476                     }
11477                     providerRunning = false;
11478                     conn = null;
11479                 } else {
11480                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
11481                 }
11482
11483                 Binder.restoreCallingIdentity(origId);
11484             }
11485
11486             if (!providerRunning) {
11487                 try {
11488                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11489                     cpi = AppGlobals.getPackageManager().
11490                         resolveContentProvider(name,
11491                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11492                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11493                 } catch (RemoteException ex) {
11494                 }
11495                 if (cpi == null) {
11496                     return null;
11497                 }
11498                 // If the provider is a singleton AND
11499                 // (it's a call within the same user || the provider is a
11500                 // privileged app)
11501                 // Then allow connecting to the singleton provider
11502                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11503                         cpi.name, cpi.flags)
11504                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11505                 if (singleton) {
11506                     userId = UserHandle.USER_SYSTEM;
11507                 }
11508                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11509                 checkTime(startTime, "getContentProviderImpl: got app info for user");
11510
11511                 String msg;
11512                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11513                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11514                         != null) {
11515                     throw new SecurityException(msg);
11516                 }
11517                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11518
11519                 if (!mProcessesReady
11520                         && !cpi.processName.equals("system")) {
11521                     // If this content provider does not run in the system
11522                     // process, and the system is not yet ready to run other
11523                     // processes, then fail fast instead of hanging.
11524                     throw new IllegalArgumentException(
11525                             "Attempt to launch content provider before system ready");
11526                 }
11527
11528                 // Make sure that the user who owns this provider is running.  If not,
11529                 // we don't want to allow it to run.
11530                 if (!mUserController.isUserRunningLocked(userId, 0)) {
11531                     Slog.w(TAG, "Unable to launch app "
11532                             + cpi.applicationInfo.packageName + "/"
11533                             + cpi.applicationInfo.uid + " for provider "
11534                             + name + ": user " + userId + " is stopped");
11535                     return null;
11536                 }
11537
11538                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11539                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11540                 cpr = mProviderMap.getProviderByClass(comp, userId);
11541                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11542                 final boolean firstClass = cpr == null;
11543                 if (firstClass) {
11544                     final long ident = Binder.clearCallingIdentity();
11545
11546                     // If permissions need a review before any of the app components can run,
11547                     // we return no provider and launch a review activity if the calling app
11548                     // is in the foreground.
11549                     if (mPermissionReviewRequired) {
11550                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11551                             return null;
11552                         }
11553                     }
11554
11555                     try {
11556                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11557                         ApplicationInfo ai =
11558                             AppGlobals.getPackageManager().
11559                                 getApplicationInfo(
11560                                         cpi.applicationInfo.packageName,
11561                                         STOCK_PM_FLAGS, userId);
11562                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11563                         if (ai == null) {
11564                             Slog.w(TAG, "No package info for content provider "
11565                                     + cpi.name);
11566                             return null;
11567                         }
11568                         ai = getAppInfoForUser(ai, userId);
11569                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11570                     } catch (RemoteException ex) {
11571                         // pm is in same process, this will never happen.
11572                     } finally {
11573                         Binder.restoreCallingIdentity(ident);
11574                     }
11575                 }
11576
11577                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11578
11579                 if (r != null && cpr.canRunHere(r)) {
11580                     // If this is a multiprocess provider, then just return its
11581                     // info and allow the caller to instantiate it.  Only do
11582                     // this if the provider is the same user as the caller's
11583                     // process, or can run as root (so can be in any process).
11584                     return cpr.newHolder(null);
11585                 }
11586
11587                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11588                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11589                             + cpr.info.name + " callers=" + Debug.getCallers(6));
11590
11591                 // This is single process, and our app is now connecting to it.
11592                 // See if we are already in the process of launching this
11593                 // provider.
11594                 final int N = mLaunchingProviders.size();
11595                 int i;
11596                 for (i = 0; i < N; i++) {
11597                     if (mLaunchingProviders.get(i) == cpr) {
11598                         break;
11599                     }
11600                 }
11601
11602                 // If the provider is not already being launched, then get it
11603                 // started.
11604                 if (i >= N) {
11605                     final long origId = Binder.clearCallingIdentity();
11606
11607                     try {
11608                         // Content provider is now in use, its package can't be stopped.
11609                         try {
11610                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
11611                             AppGlobals.getPackageManager().setPackageStoppedState(
11612                                     cpr.appInfo.packageName, false, userId);
11613                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
11614                         } catch (RemoteException e) {
11615                         } catch (IllegalArgumentException e) {
11616                             Slog.w(TAG, "Failed trying to unstop package "
11617                                     + cpr.appInfo.packageName + ": " + e);
11618                         }
11619
11620                         // Use existing process if already started
11621                         checkTime(startTime, "getContentProviderImpl: looking for process record");
11622                         ProcessRecord proc = getProcessRecordLocked(
11623                                 cpi.processName, cpr.appInfo.uid, false);
11624                         if (proc != null && proc.thread != null && !proc.killed) {
11625                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11626                                     "Installing in existing process " + proc);
11627                             if (!proc.pubProviders.containsKey(cpi.name)) {
11628                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
11629                                 proc.pubProviders.put(cpi.name, cpr);
11630                                 try {
11631                                     proc.thread.scheduleInstallProvider(cpi);
11632                                 } catch (RemoteException e) {
11633                                 }
11634                             }
11635                         } else {
11636                             checkTime(startTime, "getContentProviderImpl: before start process");
11637                             proc = startProcessLocked(cpi.processName,
11638                                     cpr.appInfo, false, 0, "content provider",
11639                                     new ComponentName(cpi.applicationInfo.packageName,
11640                                             cpi.name), false, false, false);
11641                             checkTime(startTime, "getContentProviderImpl: after start process");
11642                             if (proc == null) {
11643                                 Slog.w(TAG, "Unable to launch app "
11644                                         + cpi.applicationInfo.packageName + "/"
11645                                         + cpi.applicationInfo.uid + " for provider "
11646                                         + name + ": process is bad");
11647                                 return null;
11648                             }
11649                         }
11650                         cpr.launchingApp = proc;
11651                         mLaunchingProviders.add(cpr);
11652                     } finally {
11653                         Binder.restoreCallingIdentity(origId);
11654                     }
11655                 }
11656
11657                 checkTime(startTime, "getContentProviderImpl: updating data structures");
11658
11659                 // Make sure the provider is published (the same provider class
11660                 // may be published under multiple names).
11661                 if (firstClass) {
11662                     mProviderMap.putProviderByClass(comp, cpr);
11663                 }
11664
11665                 mProviderMap.putProviderByName(name, cpr);
11666                 conn = incProviderCountLocked(r, cpr, token, stable);
11667                 if (conn != null) {
11668                     conn.waiting = true;
11669                 }
11670             }
11671             checkTime(startTime, "getContentProviderImpl: done!");
11672
11673             grantEphemeralAccessLocked(userId, null /*intent*/,
11674                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11675         }
11676
11677         // Wait for the provider to be published...
11678         synchronized (cpr) {
11679             while (cpr.provider == null) {
11680                 if (cpr.launchingApp == null) {
11681                     Slog.w(TAG, "Unable to launch app "
11682                             + cpi.applicationInfo.packageName + "/"
11683                             + cpi.applicationInfo.uid + " for provider "
11684                             + name + ": launching app became null");
11685                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11686                             UserHandle.getUserId(cpi.applicationInfo.uid),
11687                             cpi.applicationInfo.packageName,
11688                             cpi.applicationInfo.uid, name);
11689                     return null;
11690                 }
11691                 try {
11692                     if (DEBUG_MU) Slog.v(TAG_MU,
11693                             "Waiting to start provider " + cpr
11694                             + " launchingApp=" + cpr.launchingApp);
11695                     if (conn != null) {
11696                         conn.waiting = true;
11697                     }
11698                     cpr.wait();
11699                 } catch (InterruptedException ex) {
11700                 } finally {
11701                     if (conn != null) {
11702                         conn.waiting = false;
11703                     }
11704                 }
11705             }
11706         }
11707         return cpr != null ? cpr.newHolder(conn) : null;
11708     }
11709
11710     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11711             ProcessRecord r, final int userId) {
11712         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11713                 cpi.packageName, userId)) {
11714
11715             final boolean callerForeground = r == null || r.setSchedGroup
11716                     != ProcessList.SCHED_GROUP_BACKGROUND;
11717
11718             // Show a permission review UI only for starting from a foreground app
11719             if (!callerForeground) {
11720                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11721                         + cpi.packageName + " requires a permissions review");
11722                 return false;
11723             }
11724
11725             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11726             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11727                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11728             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11729
11730             if (DEBUG_PERMISSIONS_REVIEW) {
11731                 Slog.i(TAG, "u" + userId + " Launching permission review "
11732                         + "for package " + cpi.packageName);
11733             }
11734
11735             final UserHandle userHandle = new UserHandle(userId);
11736             mHandler.post(new Runnable() {
11737                 @Override
11738                 public void run() {
11739                     mContext.startActivityAsUser(intent, userHandle);
11740                 }
11741             });
11742
11743             return false;
11744         }
11745
11746         return true;
11747     }
11748
11749     PackageManagerInternal getPackageManagerInternalLocked() {
11750         if (mPackageManagerInt == null) {
11751             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11752         }
11753         return mPackageManagerInt;
11754     }
11755
11756     @Override
11757     public final ContentProviderHolder getContentProvider(
11758             IApplicationThread caller, String name, int userId, boolean stable) {
11759         enforceNotIsolatedCaller("getContentProvider");
11760         if (caller == null) {
11761             String msg = "null IApplicationThread when getting content provider "
11762                     + name;
11763             Slog.w(TAG, msg);
11764             throw new SecurityException(msg);
11765         }
11766         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11767         // with cross-user grant.
11768         return getContentProviderImpl(caller, name, null, stable, userId);
11769     }
11770
11771     public ContentProviderHolder getContentProviderExternal(
11772             String name, int userId, IBinder token) {
11773         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11774             "Do not have permission in call getContentProviderExternal()");
11775         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11776                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11777         return getContentProviderExternalUnchecked(name, token, userId);
11778     }
11779
11780     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11781             IBinder token, int userId) {
11782         return getContentProviderImpl(null, name, token, true, userId);
11783     }
11784
11785     /**
11786      * Drop a content provider from a ProcessRecord's bookkeeping
11787      */
11788     public void removeContentProvider(IBinder connection, boolean stable) {
11789         enforceNotIsolatedCaller("removeContentProvider");
11790         long ident = Binder.clearCallingIdentity();
11791         try {
11792             synchronized (this) {
11793                 ContentProviderConnection conn;
11794                 try {
11795                     conn = (ContentProviderConnection)connection;
11796                 } catch (ClassCastException e) {
11797                     String msg ="removeContentProvider: " + connection
11798                             + " not a ContentProviderConnection";
11799                     Slog.w(TAG, msg);
11800                     throw new IllegalArgumentException(msg);
11801                 }
11802                 if (conn == null) {
11803                     throw new NullPointerException("connection is null");
11804                 }
11805                 if (decProviderCountLocked(conn, null, null, stable)) {
11806                     updateOomAdjLocked();
11807                 }
11808             }
11809         } finally {
11810             Binder.restoreCallingIdentity(ident);
11811         }
11812     }
11813
11814     public void removeContentProviderExternal(String name, IBinder token) {
11815         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11816             "Do not have permission in call removeContentProviderExternal()");
11817         int userId = UserHandle.getCallingUserId();
11818         long ident = Binder.clearCallingIdentity();
11819         try {
11820             removeContentProviderExternalUnchecked(name, token, userId);
11821         } finally {
11822             Binder.restoreCallingIdentity(ident);
11823         }
11824     }
11825
11826     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11827         synchronized (this) {
11828             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11829             if(cpr == null) {
11830                 //remove from mProvidersByClass
11831                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11832                 return;
11833             }
11834
11835             //update content provider record entry info
11836             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11837             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11838             if (localCpr.hasExternalProcessHandles()) {
11839                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11840                     updateOomAdjLocked();
11841                 } else {
11842                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11843                             + " with no external reference for token: "
11844                             + token + ".");
11845                 }
11846             } else {
11847                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11848                         + " with no external references.");
11849             }
11850         }
11851     }
11852
11853     public final void publishContentProviders(IApplicationThread caller,
11854             List<ContentProviderHolder> providers) {
11855         if (providers == null) {
11856             return;
11857         }
11858
11859         enforceNotIsolatedCaller("publishContentProviders");
11860         synchronized (this) {
11861             final ProcessRecord r = getRecordForAppLocked(caller);
11862             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11863             if (r == null) {
11864                 throw new SecurityException(
11865                         "Unable to find app for caller " + caller
11866                       + " (pid=" + Binder.getCallingPid()
11867                       + ") when publishing content providers");
11868             }
11869
11870             final long origId = Binder.clearCallingIdentity();
11871
11872             final int N = providers.size();
11873             for (int i = 0; i < N; i++) {
11874                 ContentProviderHolder src = providers.get(i);
11875                 if (src == null || src.info == null || src.provider == null) {
11876                     continue;
11877                 }
11878                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11879                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11880                 if (dst != null) {
11881                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11882                     mProviderMap.putProviderByClass(comp, dst);
11883                     String names[] = dst.info.authority.split(";");
11884                     for (int j = 0; j < names.length; j++) {
11885                         mProviderMap.putProviderByName(names[j], dst);
11886                     }
11887
11888                     int launchingCount = mLaunchingProviders.size();
11889                     int j;
11890                     boolean wasInLaunchingProviders = false;
11891                     for (j = 0; j < launchingCount; j++) {
11892                         if (mLaunchingProviders.get(j) == dst) {
11893                             mLaunchingProviders.remove(j);
11894                             wasInLaunchingProviders = true;
11895                             j--;
11896                             launchingCount--;
11897                         }
11898                     }
11899                     if (wasInLaunchingProviders) {
11900                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11901                     }
11902                     synchronized (dst) {
11903                         dst.provider = src.provider;
11904                         dst.proc = r;
11905                         dst.notifyAll();
11906                     }
11907                     updateOomAdjLocked(r, true);
11908                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11909                             src.info.authority);
11910                 }
11911             }
11912
11913             Binder.restoreCallingIdentity(origId);
11914         }
11915     }
11916
11917     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11918         ContentProviderConnection conn;
11919         try {
11920             conn = (ContentProviderConnection)connection;
11921         } catch (ClassCastException e) {
11922             String msg ="refContentProvider: " + connection
11923                     + " not a ContentProviderConnection";
11924             Slog.w(TAG, msg);
11925             throw new IllegalArgumentException(msg);
11926         }
11927         if (conn == null) {
11928             throw new NullPointerException("connection is null");
11929         }
11930
11931         synchronized (this) {
11932             if (stable > 0) {
11933                 conn.numStableIncs += stable;
11934             }
11935             stable = conn.stableCount + stable;
11936             if (stable < 0) {
11937                 throw new IllegalStateException("stableCount < 0: " + stable);
11938             }
11939
11940             if (unstable > 0) {
11941                 conn.numUnstableIncs += unstable;
11942             }
11943             unstable = conn.unstableCount + unstable;
11944             if (unstable < 0) {
11945                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11946             }
11947
11948             if ((stable+unstable) <= 0) {
11949                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11950                         + stable + " unstable=" + unstable);
11951             }
11952             conn.stableCount = stable;
11953             conn.unstableCount = unstable;
11954             return !conn.dead;
11955         }
11956     }
11957
11958     public void unstableProviderDied(IBinder connection) {
11959         ContentProviderConnection conn;
11960         try {
11961             conn = (ContentProviderConnection)connection;
11962         } catch (ClassCastException e) {
11963             String msg ="refContentProvider: " + connection
11964                     + " not a ContentProviderConnection";
11965             Slog.w(TAG, msg);
11966             throw new IllegalArgumentException(msg);
11967         }
11968         if (conn == null) {
11969             throw new NullPointerException("connection is null");
11970         }
11971
11972         // Safely retrieve the content provider associated with the connection.
11973         IContentProvider provider;
11974         synchronized (this) {
11975             provider = conn.provider.provider;
11976         }
11977
11978         if (provider == null) {
11979             // Um, yeah, we're way ahead of you.
11980             return;
11981         }
11982
11983         // Make sure the caller is being honest with us.
11984         if (provider.asBinder().pingBinder()) {
11985             // Er, no, still looks good to us.
11986             synchronized (this) {
11987                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11988                         + " says " + conn + " died, but we don't agree");
11989                 return;
11990             }
11991         }
11992
11993         // Well look at that!  It's dead!
11994         synchronized (this) {
11995             if (conn.provider.provider != provider) {
11996                 // But something changed...  good enough.
11997                 return;
11998             }
11999
12000             ProcessRecord proc = conn.provider.proc;
12001             if (proc == null || proc.thread == null) {
12002                 // Seems like the process is already cleaned up.
12003                 return;
12004             }
12005
12006             // As far as we're concerned, this is just like receiving a
12007             // death notification...  just a bit prematurely.
12008             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12009                     + ") early provider death");
12010             final long ident = Binder.clearCallingIdentity();
12011             try {
12012                 appDiedLocked(proc);
12013             } finally {
12014                 Binder.restoreCallingIdentity(ident);
12015             }
12016         }
12017     }
12018
12019     @Override
12020     public void appNotRespondingViaProvider(IBinder connection) {
12021         enforceCallingPermission(
12022                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12023
12024         final ContentProviderConnection conn = (ContentProviderConnection) connection;
12025         if (conn == null) {
12026             Slog.w(TAG, "ContentProviderConnection is null");
12027             return;
12028         }
12029
12030         final ProcessRecord host = conn.provider.proc;
12031         if (host == null) {
12032             Slog.w(TAG, "Failed to find hosting ProcessRecord");
12033             return;
12034         }
12035
12036         mHandler.post(new Runnable() {
12037             @Override
12038             public void run() {
12039                 mAppErrors.appNotResponding(host, null, null, false,
12040                         "ContentProvider not responding");
12041             }
12042         });
12043     }
12044
12045     public final void installSystemProviders() {
12046         List<ProviderInfo> providers;
12047         synchronized (this) {
12048             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12049             providers = generateApplicationProvidersLocked(app);
12050             if (providers != null) {
12051                 for (int i=providers.size()-1; i>=0; i--) {
12052                     ProviderInfo pi = (ProviderInfo)providers.get(i);
12053                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12054                         Slog.w(TAG, "Not installing system proc provider " + pi.name
12055                                 + ": not system .apk");
12056                         providers.remove(i);
12057                     }
12058                 }
12059             }
12060         }
12061         if (providers != null) {
12062             mSystemThread.installSystemProviders(providers);
12063         }
12064
12065         mConstants.start(mContext.getContentResolver());
12066         mCoreSettingsObserver = new CoreSettingsObserver(this);
12067         mFontScaleSettingObserver = new FontScaleSettingObserver();
12068
12069         // Now that the settings provider is published we can consider sending
12070         // in a rescue party.
12071         RescueParty.onSettingsProviderPublished(mContext);
12072
12073         //mUsageStatsService.monitorPackages();
12074     }
12075
12076     private void startPersistentApps(int matchFlags) {
12077         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12078
12079         synchronized (this) {
12080             try {
12081                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12082                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12083                 for (ApplicationInfo app : apps) {
12084                     if (!"android".equals(app.packageName)) {
12085                         addAppLocked(app, null, false, null /* ABI override */);
12086                     }
12087                 }
12088             } catch (RemoteException ex) {
12089             }
12090         }
12091     }
12092
12093     /**
12094      * When a user is unlocked, we need to install encryption-unaware providers
12095      * belonging to any running apps.
12096      */
12097     private void installEncryptionUnawareProviders(int userId) {
12098         // We're only interested in providers that are encryption unaware, and
12099         // we don't care about uninstalled apps, since there's no way they're
12100         // running at this point.
12101         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12102
12103         synchronized (this) {
12104             final int NP = mProcessNames.getMap().size();
12105             for (int ip = 0; ip < NP; ip++) {
12106                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12107                 final int NA = apps.size();
12108                 for (int ia = 0; ia < NA; ia++) {
12109                     final ProcessRecord app = apps.valueAt(ia);
12110                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
12111
12112                     final int NG = app.pkgList.size();
12113                     for (int ig = 0; ig < NG; ig++) {
12114                         try {
12115                             final String pkgName = app.pkgList.keyAt(ig);
12116                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12117                                     .getPackageInfo(pkgName, matchFlags, userId);
12118                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12119                                 for (ProviderInfo pi : pkgInfo.providers) {
12120                                     // TODO: keep in sync with generateApplicationProvidersLocked
12121                                     final boolean processMatch = Objects.equals(pi.processName,
12122                                             app.processName) || pi.multiprocess;
12123                                     final boolean userMatch = isSingleton(pi.processName,
12124                                             pi.applicationInfo, pi.name, pi.flags)
12125                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
12126                                     if (processMatch && userMatch) {
12127                                         Log.v(TAG, "Installing " + pi);
12128                                         app.thread.scheduleInstallProvider(pi);
12129                                     } else {
12130                                         Log.v(TAG, "Skipping " + pi);
12131                                     }
12132                                 }
12133                             }
12134                         } catch (RemoteException ignored) {
12135                         }
12136                     }
12137                 }
12138             }
12139         }
12140     }
12141
12142     /**
12143      * Allows apps to retrieve the MIME type of a URI.
12144      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12145      * users, then it does not need permission to access the ContentProvider.
12146      * Either, it needs cross-user uri grants.
12147      *
12148      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12149      *
12150      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12151      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12152      */
12153     public String getProviderMimeType(Uri uri, int userId) {
12154         enforceNotIsolatedCaller("getProviderMimeType");
12155         final String name = uri.getAuthority();
12156         int callingUid = Binder.getCallingUid();
12157         int callingPid = Binder.getCallingPid();
12158         long ident = 0;
12159         boolean clearedIdentity = false;
12160         synchronized (this) {
12161             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12162         }
12163         if (canClearIdentity(callingPid, callingUid, userId)) {
12164             clearedIdentity = true;
12165             ident = Binder.clearCallingIdentity();
12166         }
12167         ContentProviderHolder holder = null;
12168         try {
12169             holder = getContentProviderExternalUnchecked(name, null, userId);
12170             if (holder != null) {
12171                 return holder.provider.getType(uri);
12172             }
12173         } catch (RemoteException e) {
12174             Log.w(TAG, "Content provider dead retrieving " + uri, e);
12175             return null;
12176         } catch (Exception e) {
12177             Log.w(TAG, "Exception while determining type of " + uri, e);
12178             return null;
12179         } finally {
12180             // We need to clear the identity to call removeContentProviderExternalUnchecked
12181             if (!clearedIdentity) {
12182                 ident = Binder.clearCallingIdentity();
12183             }
12184             try {
12185                 if (holder != null) {
12186                     removeContentProviderExternalUnchecked(name, null, userId);
12187                 }
12188             } finally {
12189                 Binder.restoreCallingIdentity(ident);
12190             }
12191         }
12192
12193         return null;
12194     }
12195
12196     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12197         if (UserHandle.getUserId(callingUid) == userId) {
12198             return true;
12199         }
12200         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12201                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12202                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12203                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12204                 return true;
12205         }
12206         return false;
12207     }
12208
12209     // =========================================================
12210     // GLOBAL MANAGEMENT
12211     // =========================================================
12212
12213     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12214             boolean isolated, int isolatedUid) {
12215         String proc = customProcess != null ? customProcess : info.processName;
12216         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12217         final int userId = UserHandle.getUserId(info.uid);
12218         int uid = info.uid;
12219         if (isolated) {
12220             if (isolatedUid == 0) {
12221                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12222                 while (true) {
12223                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12224                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12225                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12226                     }
12227                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12228                     mNextIsolatedProcessUid++;
12229                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12230                         // No process for this uid, use it.
12231                         break;
12232                     }
12233                     stepsLeft--;
12234                     if (stepsLeft <= 0) {
12235                         return null;
12236                     }
12237                 }
12238             } else {
12239                 // Special case for startIsolatedProcess (internal only), where
12240                 // the uid of the isolated process is specified by the caller.
12241                 uid = isolatedUid;
12242             }
12243             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12244
12245             // Register the isolated UID with this application so BatteryStats knows to
12246             // attribute resource usage to the application.
12247             //
12248             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12249             // about the process state of the isolated UID *before* it is registered with the
12250             // owning application.
12251             mBatteryStatsService.addIsolatedUid(uid, info.uid);
12252         }
12253         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12254         if (!mBooted && !mBooting
12255                 && userId == UserHandle.USER_SYSTEM
12256                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12257             r.persistent = true;
12258             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12259         }
12260         addProcessNameLocked(r);
12261         return r;
12262     }
12263
12264     private boolean uidOnBackgroundWhitelist(final int uid) {
12265         final int appId = UserHandle.getAppId(uid);
12266         final int[] whitelist = mBackgroundAppIdWhitelist;
12267         final int N = whitelist.length;
12268         for (int i = 0; i < N; i++) {
12269             if (appId == whitelist[i]) {
12270                 return true;
12271             }
12272         }
12273         return false;
12274     }
12275
12276     @Override
12277     public void backgroundWhitelistUid(final int uid) {
12278         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12279             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12280         }
12281
12282         if (DEBUG_BACKGROUND_CHECK) {
12283             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12284         }
12285         synchronized (this) {
12286             final int N = mBackgroundAppIdWhitelist.length;
12287             int[] newList = new int[N+1];
12288             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12289             newList[N] = UserHandle.getAppId(uid);
12290             mBackgroundAppIdWhitelist = newList;
12291         }
12292     }
12293
12294     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12295             String abiOverride) {
12296         ProcessRecord app;
12297         if (!isolated) {
12298             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12299                     info.uid, true);
12300         } else {
12301             app = null;
12302         }
12303
12304         if (app == null) {
12305             app = newProcessRecordLocked(info, customProcess, isolated, 0);
12306             updateLruProcessLocked(app, false, null);
12307             updateOomAdjLocked();
12308         }
12309
12310         // This package really, really can not be stopped.
12311         try {
12312             AppGlobals.getPackageManager().setPackageStoppedState(
12313                     info.packageName, false, UserHandle.getUserId(app.uid));
12314         } catch (RemoteException e) {
12315         } catch (IllegalArgumentException e) {
12316             Slog.w(TAG, "Failed trying to unstop package "
12317                     + info.packageName + ": " + e);
12318         }
12319
12320         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12321             app.persistent = true;
12322             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12323         }
12324         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12325             mPersistentStartingProcesses.add(app);
12326             startProcessLocked(app, "added application",
12327                     customProcess != null ? customProcess : app.processName, abiOverride,
12328                     null /* entryPoint */, null /* entryPointArgs */);
12329         }
12330
12331         return app;
12332     }
12333
12334     public void unhandledBack() {
12335         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12336                 "unhandledBack()");
12337
12338         synchronized(this) {
12339             final long origId = Binder.clearCallingIdentity();
12340             try {
12341                 getFocusedStack().unhandledBackLocked();
12342             } finally {
12343                 Binder.restoreCallingIdentity(origId);
12344             }
12345         }
12346     }
12347
12348     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12349         enforceNotIsolatedCaller("openContentUri");
12350         final int userId = UserHandle.getCallingUserId();
12351         final Uri uri = Uri.parse(uriString);
12352         String name = uri.getAuthority();
12353         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12354         ParcelFileDescriptor pfd = null;
12355         if (cph != null) {
12356             // We record the binder invoker's uid in thread-local storage before
12357             // going to the content provider to open the file.  Later, in the code
12358             // that handles all permissions checks, we look for this uid and use
12359             // that rather than the Activity Manager's own uid.  The effect is that
12360             // we do the check against the caller's permissions even though it looks
12361             // to the content provider like the Activity Manager itself is making
12362             // the request.
12363             Binder token = new Binder();
12364             sCallerIdentity.set(new Identity(
12365                     token, Binder.getCallingPid(), Binder.getCallingUid()));
12366             try {
12367                 pfd = cph.provider.openFile(null, uri, "r", null, token);
12368             } catch (FileNotFoundException e) {
12369                 // do nothing; pfd will be returned null
12370             } finally {
12371                 // Ensure that whatever happens, we clean up the identity state
12372                 sCallerIdentity.remove();
12373                 // Ensure we're done with the provider.
12374                 removeContentProviderExternalUnchecked(name, null, userId);
12375             }
12376         } else {
12377             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12378         }
12379         return pfd;
12380     }
12381
12382     // Actually is sleeping or shutting down or whatever else in the future
12383     // is an inactive state.
12384     boolean isSleepingOrShuttingDownLocked() {
12385         return isSleepingLocked() || mShuttingDown;
12386     }
12387
12388     boolean isShuttingDownLocked() {
12389         return mShuttingDown;
12390     }
12391
12392     boolean isSleepingLocked() {
12393         return mSleeping;
12394     }
12395
12396     void onWakefulnessChanged(int wakefulness) {
12397         synchronized(this) {
12398             mWakefulness = wakefulness;
12399             updateSleepIfNeededLocked();
12400         }
12401     }
12402
12403     void finishRunningVoiceLocked() {
12404         if (mRunningVoice != null) {
12405             mRunningVoice = null;
12406             mVoiceWakeLock.release();
12407             updateSleepIfNeededLocked();
12408         }
12409     }
12410
12411     void startTimeTrackingFocusedActivityLocked() {
12412         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12413         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12414             mCurAppTimeTracker.start(resumedActivity.packageName);
12415         }
12416     }
12417
12418     void updateSleepIfNeededLocked() {
12419         final boolean shouldSleep = shouldSleepLocked();
12420         if (mSleeping && !shouldSleep) {
12421             mSleeping = false;
12422             startTimeTrackingFocusedActivityLocked();
12423             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12424             mStackSupervisor.comeOutOfSleepIfNeededLocked();
12425             sendNotifyVrManagerOfSleepState(false);
12426             updateOomAdjLocked();
12427         } else if (!mSleeping && shouldSleep) {
12428             mSleeping = true;
12429             if (mCurAppTimeTracker != null) {
12430                 mCurAppTimeTracker.stop();
12431             }
12432             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12433             mStackSupervisor.goingToSleepLocked();
12434             sendNotifyVrManagerOfSleepState(true);
12435             updateOomAdjLocked();
12436
12437             // Initialize the wake times of all processes.
12438             checkExcessivePowerUsageLocked(false);
12439             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12440             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12441             mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
12442         }
12443
12444         // Also update state in a special way for running foreground services UI.
12445         switch (mWakefulness) {
12446             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12447             case PowerManagerInternal.WAKEFULNESS_DREAMING:
12448             case PowerManagerInternal.WAKEFULNESS_DOZING:
12449                 mServices.updateScreenStateLocked(false);
12450                 break;
12451             case PowerManagerInternal.WAKEFULNESS_AWAKE:
12452             default:
12453                 mServices.updateScreenStateLocked(true);
12454                 break;
12455         }
12456     }
12457
12458     private boolean shouldSleepLocked() {
12459         // Resume applications while running a voice interactor.
12460         if (mRunningVoice != null) {
12461             return false;
12462         }
12463
12464         // TODO: Transform the lock screen state into a sleep token instead.
12465         switch (mWakefulness) {
12466             case PowerManagerInternal.WAKEFULNESS_AWAKE:
12467             case PowerManagerInternal.WAKEFULNESS_DREAMING:
12468                 // Pause applications whenever the lock screen is shown or any sleep
12469                 // tokens have been acquired.
12470                 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12471             case PowerManagerInternal.WAKEFULNESS_DOZING:
12472             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12473             default:
12474                 // If we're asleep then pause applications unconditionally.
12475                 return true;
12476         }
12477     }
12478
12479     /** Pokes the task persister. */
12480     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12481         mRecentTasks.notifyTaskPersisterLocked(task, flush);
12482     }
12483
12484     /**
12485      * Notifies all listeners when the pinned stack animation starts.
12486      */
12487     @Override
12488     public void notifyPinnedStackAnimationStarted() {
12489         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12490     }
12491
12492     /**
12493      * Notifies all listeners when the pinned stack animation ends.
12494      */
12495     @Override
12496     public void notifyPinnedStackAnimationEnded() {
12497         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12498     }
12499
12500     @Override
12501     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12502         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12503     }
12504
12505     @Override
12506     public boolean shutdown(int timeout) {
12507         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12508                 != PackageManager.PERMISSION_GRANTED) {
12509             throw new SecurityException("Requires permission "
12510                     + android.Manifest.permission.SHUTDOWN);
12511         }
12512
12513         boolean timedout = false;
12514
12515         synchronized(this) {
12516             mShuttingDown = true;
12517             updateEventDispatchingLocked();
12518             timedout = mStackSupervisor.shutdownLocked(timeout);
12519         }
12520
12521         mAppOpsService.shutdown();
12522         if (mUsageStatsService != null) {
12523             mUsageStatsService.prepareShutdown();
12524         }
12525         mBatteryStatsService.shutdown();
12526         synchronized (this) {
12527             mProcessStats.shutdownLocked();
12528             notifyTaskPersisterLocked(null, true);
12529         }
12530
12531         return timedout;
12532     }
12533
12534     public final void activitySlept(IBinder token) {
12535         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12536
12537         final long origId = Binder.clearCallingIdentity();
12538
12539         synchronized (this) {
12540             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12541             if (r != null) {
12542                 mStackSupervisor.activitySleptLocked(r);
12543             }
12544         }
12545
12546         Binder.restoreCallingIdentity(origId);
12547     }
12548
12549     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12550         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12551         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12552         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12553             boolean wasRunningVoice = mRunningVoice != null;
12554             mRunningVoice = session;
12555             if (!wasRunningVoice) {
12556                 mVoiceWakeLock.acquire();
12557                 updateSleepIfNeededLocked();
12558             }
12559         }
12560     }
12561
12562     private void updateEventDispatchingLocked() {
12563         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12564     }
12565
12566     @Override
12567     public void setLockScreenShown(boolean showing) {
12568         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12569                 != PackageManager.PERMISSION_GRANTED) {
12570             throw new SecurityException("Requires permission "
12571                     + android.Manifest.permission.DEVICE_POWER);
12572         }
12573
12574         synchronized(this) {
12575             long ident = Binder.clearCallingIdentity();
12576             try {
12577                 mKeyguardController.setKeyguardShown(showing);
12578             } finally {
12579                 Binder.restoreCallingIdentity(ident);
12580             }
12581         }
12582     }
12583
12584     @Override
12585     public void notifyLockedProfile(@UserIdInt int userId) {
12586         try {
12587             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12588                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12589             }
12590         } catch (RemoteException ex) {
12591             throw new SecurityException("Fail to check is caller a privileged app", ex);
12592         }
12593
12594         synchronized (this) {
12595             final long ident = Binder.clearCallingIdentity();
12596             try {
12597                 if (mUserController.shouldConfirmCredentials(userId)) {
12598                     if (mKeyguardController.isKeyguardLocked()) {
12599                         // Showing launcher to avoid user entering credential twice.
12600                         final int currentUserId = mUserController.getCurrentUserIdLocked();
12601                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12602                     }
12603                     mStackSupervisor.lockAllProfileTasks(userId);
12604                 }
12605             } finally {
12606                 Binder.restoreCallingIdentity(ident);
12607             }
12608         }
12609     }
12610
12611     @Override
12612     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12613         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12614         synchronized (this) {
12615             final long ident = Binder.clearCallingIdentity();
12616             try {
12617                 mActivityStarter.startConfirmCredentialIntent(intent, options);
12618             } finally {
12619                 Binder.restoreCallingIdentity(ident);
12620             }
12621         }
12622     }
12623
12624     @Override
12625     public void stopAppSwitches() {
12626         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12627                 != PackageManager.PERMISSION_GRANTED) {
12628             throw new SecurityException("viewquires permission "
12629                     + android.Manifest.permission.STOP_APP_SWITCHES);
12630         }
12631
12632         synchronized(this) {
12633             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12634                     + APP_SWITCH_DELAY_TIME;
12635             mDidAppSwitch = false;
12636             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12637             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12638             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12639         }
12640     }
12641
12642     public void resumeAppSwitches() {
12643         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12644                 != PackageManager.PERMISSION_GRANTED) {
12645             throw new SecurityException("Requires permission "
12646                     + android.Manifest.permission.STOP_APP_SWITCHES);
12647         }
12648
12649         synchronized(this) {
12650             // Note that we don't execute any pending app switches... we will
12651             // let those wait until either the timeout, or the next start
12652             // activity request.
12653             mAppSwitchesAllowedTime = 0;
12654         }
12655     }
12656
12657     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12658             int callingPid, int callingUid, String name) {
12659         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12660             return true;
12661         }
12662
12663         int perm = checkComponentPermission(
12664                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12665                 sourceUid, -1, true);
12666         if (perm == PackageManager.PERMISSION_GRANTED) {
12667             return true;
12668         }
12669
12670         // If the actual IPC caller is different from the logical source, then
12671         // also see if they are allowed to control app switches.
12672         if (callingUid != -1 && callingUid != sourceUid) {
12673             perm = checkComponentPermission(
12674                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12675                     callingUid, -1, true);
12676             if (perm == PackageManager.PERMISSION_GRANTED) {
12677                 return true;
12678             }
12679         }
12680
12681         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12682         return false;
12683     }
12684
12685     public void setDebugApp(String packageName, boolean waitForDebugger,
12686             boolean persistent) {
12687         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12688                 "setDebugApp()");
12689
12690         long ident = Binder.clearCallingIdentity();
12691         try {
12692             // Note that this is not really thread safe if there are multiple
12693             // callers into it at the same time, but that's not a situation we
12694             // care about.
12695             if (persistent) {
12696                 final ContentResolver resolver = mContext.getContentResolver();
12697                 Settings.Global.putString(
12698                     resolver, Settings.Global.DEBUG_APP,
12699                     packageName);
12700                 Settings.Global.putInt(
12701                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12702                     waitForDebugger ? 1 : 0);
12703             }
12704
12705             synchronized (this) {
12706                 if (!persistent) {
12707                     mOrigDebugApp = mDebugApp;
12708                     mOrigWaitForDebugger = mWaitForDebugger;
12709                 }
12710                 mDebugApp = packageName;
12711                 mWaitForDebugger = waitForDebugger;
12712                 mDebugTransient = !persistent;
12713                 if (packageName != null) {
12714                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12715                             false, UserHandle.USER_ALL, "set debug app");
12716                 }
12717             }
12718         } finally {
12719             Binder.restoreCallingIdentity(ident);
12720         }
12721     }
12722
12723     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12724         synchronized (this) {
12725             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12726             if (!isDebuggable) {
12727                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12728                     throw new SecurityException("Process not debuggable: " + app.packageName);
12729                 }
12730             }
12731
12732             mTrackAllocationApp = processName;
12733         }
12734     }
12735
12736     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12737         synchronized (this) {
12738             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12739             if (!isDebuggable) {
12740                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12741                     throw new SecurityException("Process not debuggable: " + app.packageName);
12742                 }
12743             }
12744             mProfileApp = processName;
12745             mProfileFile = profilerInfo.profileFile;
12746             if (mProfileFd != null) {
12747                 try {
12748                     mProfileFd.close();
12749                 } catch (IOException e) {
12750                 }
12751                 mProfileFd = null;
12752             }
12753             mProfileFd = profilerInfo.profileFd;
12754             mSamplingInterval = profilerInfo.samplingInterval;
12755             mAutoStopProfiler = profilerInfo.autoStopProfiler;
12756             mStreamingOutput = profilerInfo.streamingOutput;
12757             mProfileType = 0;
12758         }
12759     }
12760
12761     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12762         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12763         if (!isDebuggable) {
12764             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12765                 throw new SecurityException("Process not debuggable: " + app.packageName);
12766             }
12767         }
12768         mNativeDebuggingApp = processName;
12769     }
12770
12771     @Override
12772     public void setAlwaysFinish(boolean enabled) {
12773         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12774                 "setAlwaysFinish()");
12775
12776         long ident = Binder.clearCallingIdentity();
12777         try {
12778             Settings.Global.putInt(
12779                     mContext.getContentResolver(),
12780                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12781
12782             synchronized (this) {
12783                 mAlwaysFinishActivities = enabled;
12784             }
12785         } finally {
12786             Binder.restoreCallingIdentity(ident);
12787         }
12788     }
12789
12790     @Override
12791     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12792         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12793                 "setActivityController()");
12794         synchronized (this) {
12795             mController = controller;
12796             mControllerIsAMonkey = imAMonkey;
12797             Watchdog.getInstance().setActivityController(controller);
12798         }
12799     }
12800
12801     @Override
12802     public void setUserIsMonkey(boolean userIsMonkey) {
12803         synchronized (this) {
12804             synchronized (mPidsSelfLocked) {
12805                 final int callingPid = Binder.getCallingPid();
12806                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12807                 if (proc == null) {
12808                     throw new SecurityException("Unknown process: " + callingPid);
12809                 }
12810                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12811                     throw new SecurityException("Only an instrumentation process "
12812                             + "with a UiAutomation can call setUserIsMonkey");
12813                 }
12814             }
12815             mUserIsMonkey = userIsMonkey;
12816         }
12817     }
12818
12819     @Override
12820     public boolean isUserAMonkey() {
12821         synchronized (this) {
12822             // If there is a controller also implies the user is a monkey.
12823             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12824         }
12825     }
12826
12827     /**
12828      * @deprecated This method is only used by a few internal components and it will soon be
12829      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12830      * No new code should be calling it.
12831      */
12832     @Deprecated
12833     @Override
12834     public void requestBugReport(int bugreportType) {
12835         String extraOptions = null;
12836         switch (bugreportType) {
12837             case ActivityManager.BUGREPORT_OPTION_FULL:
12838                 // Default options.
12839                 break;
12840             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12841                 extraOptions = "bugreportplus";
12842                 break;
12843             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12844                 extraOptions = "bugreportremote";
12845                 break;
12846             case ActivityManager.BUGREPORT_OPTION_WEAR:
12847                 extraOptions = "bugreportwear";
12848                 break;
12849             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12850                 extraOptions = "bugreporttelephony";
12851                 break;
12852             default:
12853                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12854                         + bugreportType);
12855         }
12856         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12857         if (extraOptions != null) {
12858             SystemProperties.set("dumpstate.options", extraOptions);
12859         }
12860         SystemProperties.set("ctl.start", "bugreport");
12861     }
12862
12863     /**
12864      * @deprecated This method is only used by a few internal components and it will soon be
12865      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12866      * No new code should be calling it.
12867      */
12868     @Deprecated
12869     @Override
12870     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12871
12872         if (!TextUtils.isEmpty(shareTitle)) {
12873             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12874                 String errorStr = "shareTitle should be less than " +
12875                         MAX_BUGREPORT_TITLE_SIZE + " characters";
12876                 throw new IllegalArgumentException(errorStr);
12877             } else {
12878                 if (!TextUtils.isEmpty(shareDescription)) {
12879                     int length;
12880                     try {
12881                         length = shareDescription.getBytes("UTF-8").length;
12882                     } catch (UnsupportedEncodingException e) {
12883                         String errorStr = "shareDescription: UnsupportedEncodingException";
12884                         throw new IllegalArgumentException(errorStr);
12885                     }
12886                     if (length > SystemProperties.PROP_VALUE_MAX) {
12887                         String errorStr = "shareTitle should be less than " +
12888                                 SystemProperties.PROP_VALUE_MAX + " bytes";
12889                         throw new IllegalArgumentException(errorStr);
12890                     } else {
12891                         SystemProperties.set("dumpstate.options.description", shareDescription);
12892                     }
12893                 }
12894                 SystemProperties.set("dumpstate.options.title", shareTitle);
12895             }
12896         }
12897
12898         Slog.d(TAG, "Bugreport notification title " + shareTitle
12899                 + " description " + shareDescription);
12900         requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12901     }
12902
12903     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12904         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12905     }
12906
12907     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12908         if (r != null && (r.instr != null || r.usingWrapper)) {
12909             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12910         }
12911         return KEY_DISPATCHING_TIMEOUT;
12912     }
12913
12914     @Override
12915     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12916         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12917                 != PackageManager.PERMISSION_GRANTED) {
12918             throw new SecurityException("Requires permission "
12919                     + android.Manifest.permission.FILTER_EVENTS);
12920         }
12921         ProcessRecord proc;
12922         long timeout;
12923         synchronized (this) {
12924             synchronized (mPidsSelfLocked) {
12925                 proc = mPidsSelfLocked.get(pid);
12926             }
12927             timeout = getInputDispatchingTimeoutLocked(proc);
12928         }
12929
12930         if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12931             return -1;
12932         }
12933
12934         return timeout;
12935     }
12936
12937     /**
12938      * Handle input dispatching timeouts.
12939      * Returns whether input dispatching should be aborted or not.
12940      */
12941     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12942             final ActivityRecord activity, final ActivityRecord parent,
12943             final boolean aboveSystem, String reason) {
12944         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12945                 != PackageManager.PERMISSION_GRANTED) {
12946             throw new SecurityException("Requires permission "
12947                     + android.Manifest.permission.FILTER_EVENTS);
12948         }
12949
12950         final String annotation;
12951         if (reason == null) {
12952             annotation = "Input dispatching timed out";
12953         } else {
12954             annotation = "Input dispatching timed out (" + reason + ")";
12955         }
12956
12957         if (proc != null) {
12958             synchronized (this) {
12959                 if (proc.debugging) {
12960                     return false;
12961                 }
12962
12963                 if (proc.instr != null) {
12964                     Bundle info = new Bundle();
12965                     info.putString("shortMsg", "keyDispatchingTimedOut");
12966                     info.putString("longMsg", annotation);
12967                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12968                     return true;
12969                 }
12970             }
12971             mHandler.post(new Runnable() {
12972                 @Override
12973                 public void run() {
12974                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12975                 }
12976             });
12977         }
12978
12979         return true;
12980     }
12981
12982     @Override
12983     public Bundle getAssistContextExtras(int requestType) {
12984         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12985                 null, null, true /* focused */, true /* newSessionId */,
12986                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12987         if (pae == null) {
12988             return null;
12989         }
12990         synchronized (pae) {
12991             while (!pae.haveResult) {
12992                 try {
12993                     pae.wait();
12994                 } catch (InterruptedException e) {
12995                 }
12996             }
12997         }
12998         synchronized (this) {
12999             buildAssistBundleLocked(pae, pae.result);
13000             mPendingAssistExtras.remove(pae);
13001             mUiHandler.removeCallbacks(pae);
13002         }
13003         return pae.extras;
13004     }
13005
13006     @Override
13007     public boolean isAssistDataAllowedOnCurrentActivity() {
13008         int userId;
13009         synchronized (this) {
13010             final ActivityStack focusedStack = getFocusedStack();
13011             if (focusedStack == null || focusedStack.isAssistantStack()) {
13012                 return false;
13013             }
13014
13015             final ActivityRecord activity = focusedStack.topActivity();
13016             if (activity == null) {
13017                 return false;
13018             }
13019             userId = activity.userId;
13020         }
13021         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13022                 Context.DEVICE_POLICY_SERVICE);
13023         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13024     }
13025
13026     @Override
13027     public boolean showAssistFromActivity(IBinder token, Bundle args) {
13028         long ident = Binder.clearCallingIdentity();
13029         try {
13030             synchronized (this) {
13031                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13032                 ActivityRecord top = getFocusedStack().topActivity();
13033                 if (top != caller) {
13034                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13035                             + " is not current top " + top);
13036                     return false;
13037                 }
13038                 if (!top.nowVisible) {
13039                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13040                             + " is not visible");
13041                     return false;
13042                 }
13043             }
13044             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13045                     token);
13046         } finally {
13047             Binder.restoreCallingIdentity(ident);
13048         }
13049     }
13050
13051     @Override
13052     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13053             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13054         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13055                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13056                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13057     }
13058
13059     @Override
13060     public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13061             IBinder activityToken, int flags) {
13062         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13063                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13064                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13065     }
13066
13067     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13068             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13069             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13070             int flags) {
13071         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13072                 "enqueueAssistContext()");
13073
13074         synchronized (this) {
13075             ActivityRecord activity = getFocusedStack().topActivity();
13076             if (activity == null) {
13077                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13078                 return null;
13079             }
13080             if (activity.app == null || activity.app.thread == null) {
13081                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13082                 return null;
13083             }
13084             if (focused) {
13085                 if (activityToken != null) {
13086                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13087                     if (activity != caller) {
13088                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13089                                 + " is not current top " + activity);
13090                         return null;
13091                     }
13092                 }
13093             } else {
13094                 activity = ActivityRecord.forTokenLocked(activityToken);
13095                 if (activity == null) {
13096                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13097                             + " couldn't be found");
13098                     return null;
13099                 }
13100             }
13101
13102             PendingAssistExtras pae;
13103             Bundle extras = new Bundle();
13104             if (args != null) {
13105                 extras.putAll(args);
13106             }
13107             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13108             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13109
13110             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13111                     userHandle);
13112             pae.isHome = activity.isHomeActivity();
13113
13114             // Increment the sessionId if necessary
13115             if (newSessionId) {
13116                 mViSessionId++;
13117             }
13118             try {
13119                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13120                         mViSessionId, flags);
13121                 mPendingAssistExtras.add(pae);
13122                 mUiHandler.postDelayed(pae, timeout);
13123             } catch (RemoteException e) {
13124                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13125                 return null;
13126             }
13127             return pae;
13128         }
13129     }
13130
13131     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13132         IResultReceiver receiver;
13133         synchronized (this) {
13134             mPendingAssistExtras.remove(pae);
13135             receiver = pae.receiver;
13136         }
13137         if (receiver != null) {
13138             // Caller wants result sent back to them.
13139             Bundle sendBundle = new Bundle();
13140             // At least return the receiver extras
13141             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13142                     pae.receiverExtras);
13143             try {
13144                 pae.receiver.send(0, sendBundle);
13145             } catch (RemoteException e) {
13146             }
13147         }
13148     }
13149
13150     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13151         if (result != null) {
13152             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13153         }
13154         if (pae.hint != null) {
13155             pae.extras.putBoolean(pae.hint, true);
13156         }
13157     }
13158
13159     /** Called from an app when assist data is ready. */
13160     @Override
13161     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13162             AssistContent content, Uri referrer) {
13163         PendingAssistExtras pae = (PendingAssistExtras)token;
13164         synchronized (pae) {
13165             pae.result = extras;
13166             pae.structure = structure;
13167             pae.content = content;
13168             if (referrer != null) {
13169                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13170             }
13171             if (structure != null) {
13172                 structure.setHomeActivity(pae.isHome);
13173             }
13174             pae.haveResult = true;
13175             pae.notifyAll();
13176             if (pae.intent == null && pae.receiver == null) {
13177                 // Caller is just waiting for the result.
13178                 return;
13179             }
13180         }
13181
13182         // We are now ready to launch the assist activity.
13183         IResultReceiver sendReceiver = null;
13184         Bundle sendBundle = null;
13185         synchronized (this) {
13186             buildAssistBundleLocked(pae, extras);
13187             boolean exists = mPendingAssistExtras.remove(pae);
13188             mUiHandler.removeCallbacks(pae);
13189             if (!exists) {
13190                 // Timed out.
13191                 return;
13192             }
13193             if ((sendReceiver=pae.receiver) != null) {
13194                 // Caller wants result sent back to them.
13195                 sendBundle = new Bundle();
13196                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13197                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13198                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13199                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13200                         pae.receiverExtras);
13201             }
13202         }
13203         if (sendReceiver != null) {
13204             try {
13205                 sendReceiver.send(0, sendBundle);
13206             } catch (RemoteException e) {
13207             }
13208             return;
13209         }
13210
13211         long ident = Binder.clearCallingIdentity();
13212         try {
13213             pae.intent.replaceExtras(pae.extras);
13214             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13215                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
13216                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13217             closeSystemDialogs("assist");
13218             try {
13219                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13220             } catch (ActivityNotFoundException e) {
13221                 Slog.w(TAG, "No activity to handle assist action.", e);
13222             }
13223         } finally {
13224             Binder.restoreCallingIdentity(ident);
13225         }
13226     }
13227
13228     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13229             Bundle args) {
13230         return enqueueAssistContext(requestType, intent, hint, null, null, null,
13231                 true /* focused */, true /* newSessionId */, userHandle, args,
13232                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13233     }
13234
13235     public void registerProcessObserver(IProcessObserver observer) {
13236         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13237                 "registerProcessObserver()");
13238         synchronized (this) {
13239             mProcessObservers.register(observer);
13240         }
13241     }
13242
13243     @Override
13244     public void unregisterProcessObserver(IProcessObserver observer) {
13245         synchronized (this) {
13246             mProcessObservers.unregister(observer);
13247         }
13248     }
13249
13250     @Override
13251     public int getUidProcessState(int uid, String callingPackage) {
13252         if (!hasUsageStatsPermission(callingPackage)) {
13253             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13254                     "getUidProcessState");
13255         }
13256
13257         synchronized (this) {
13258             UidRecord uidRec = mActiveUids.get(uid);
13259             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13260         }
13261     }
13262
13263     @Override
13264     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13265             String callingPackage) {
13266         if (!hasUsageStatsPermission(callingPackage)) {
13267             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13268                     "registerUidObserver");
13269         }
13270         synchronized (this) {
13271             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13272                     callingPackage, which, cutpoint));
13273         }
13274     }
13275
13276     @Override
13277     public void unregisterUidObserver(IUidObserver observer) {
13278         synchronized (this) {
13279             mUidObservers.unregister(observer);
13280         }
13281     }
13282
13283     @Override
13284     public boolean convertFromTranslucent(IBinder token) {
13285         final long origId = Binder.clearCallingIdentity();
13286         try {
13287             synchronized (this) {
13288                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13289                 if (r == null) {
13290                     return false;
13291                 }
13292                 final boolean translucentChanged = r.changeWindowTranslucency(true);
13293                 if (translucentChanged) {
13294                     r.getStack().releaseBackgroundResources(r);
13295                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13296                 }
13297                 mWindowManager.setAppFullscreen(token, true);
13298                 return translucentChanged;
13299             }
13300         } finally {
13301             Binder.restoreCallingIdentity(origId);
13302         }
13303     }
13304
13305     @Override
13306     public boolean convertToTranslucent(IBinder token, Bundle options) {
13307         final long origId = Binder.clearCallingIdentity();
13308         try {
13309             synchronized (this) {
13310                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13311                 if (r == null) {
13312                     return false;
13313                 }
13314                 final TaskRecord task = r.getTask();
13315                 int index = task.mActivities.lastIndexOf(r);
13316                 if (index > 0) {
13317                     ActivityRecord under = task.mActivities.get(index - 1);
13318                     under.returningOptions = ActivityOptions.fromBundle(options);
13319                 }
13320                 final boolean translucentChanged = r.changeWindowTranslucency(false);
13321                 if (translucentChanged) {
13322                     r.getStack().convertActivityToTranslucent(r);
13323                 }
13324                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13325                 mWindowManager.setAppFullscreen(token, false);
13326                 return translucentChanged;
13327             }
13328         } finally {
13329             Binder.restoreCallingIdentity(origId);
13330         }
13331     }
13332
13333     @Override
13334     public boolean requestVisibleBehind(IBinder token, boolean visible) {
13335         final long origId = Binder.clearCallingIdentity();
13336         try {
13337             synchronized (this) {
13338                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13339                 if (r != null) {
13340                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13341                 }
13342             }
13343             return false;
13344         } finally {
13345             Binder.restoreCallingIdentity(origId);
13346         }
13347     }
13348
13349     @Override
13350     public boolean isBackgroundVisibleBehind(IBinder token) {
13351         final long origId = Binder.clearCallingIdentity();
13352         try {
13353             synchronized (this) {
13354                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
13355                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13356                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13357                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13358                 return visible;
13359             }
13360         } finally {
13361             Binder.restoreCallingIdentity(origId);
13362         }
13363     }
13364
13365     @Override
13366     public Bundle getActivityOptions(IBinder token) {
13367         final long origId = Binder.clearCallingIdentity();
13368         try {
13369             synchronized (this) {
13370                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13371                 if (r != null) {
13372                     final ActivityOptions activityOptions = r.pendingOptions;
13373                     return activityOptions == null ? null : activityOptions.toBundle();
13374                 }
13375                 return null;
13376             }
13377         } finally {
13378             Binder.restoreCallingIdentity(origId);
13379         }
13380     }
13381
13382     @Override
13383     public void setImmersive(IBinder token, boolean immersive) {
13384         synchronized(this) {
13385             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13386             if (r == null) {
13387                 throw new IllegalArgumentException();
13388             }
13389             r.immersive = immersive;
13390
13391             // update associated state if we're frontmost
13392             if (r == mStackSupervisor.getResumedActivityLocked()) {
13393                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13394                 applyUpdateLockStateLocked(r);
13395             }
13396         }
13397     }
13398
13399     @Override
13400     public boolean isImmersive(IBinder token) {
13401         synchronized (this) {
13402             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13403             if (r == null) {
13404                 throw new IllegalArgumentException();
13405             }
13406             return r.immersive;
13407         }
13408     }
13409
13410     @Override
13411     public void setVrThread(int tid) {
13412         enforceSystemHasVrFeature();
13413         synchronized (this) {
13414             synchronized (mPidsSelfLocked) {
13415                 final int pid = Binder.getCallingPid();
13416                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13417                 mVrController.setVrThreadLocked(tid, pid, proc);
13418             }
13419         }
13420     }
13421
13422     @Override
13423     public void setPersistentVrThread(int tid) {
13424         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13425             final String msg = "Permission Denial: setPersistentVrThread() from pid="
13426                     + Binder.getCallingPid()
13427                     + ", uid=" + Binder.getCallingUid()
13428                     + " requires " + permission.RESTRICTED_VR_ACCESS;
13429             Slog.w(TAG, msg);
13430             throw new SecurityException(msg);
13431         }
13432         enforceSystemHasVrFeature();
13433         synchronized (this) {
13434             synchronized (mPidsSelfLocked) {
13435                 final int pid = Binder.getCallingPid();
13436                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13437                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13438             }
13439         }
13440     }
13441
13442     /**
13443      * Schedule the given thread a normal scheduling priority.
13444      *
13445      * @param newTid the tid of the thread to adjust the scheduling of.
13446      * @param suppressLogs {@code true} if any error logging should be disabled.
13447      *
13448      * @return {@code true} if this succeeded.
13449      */
13450     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13451         try {
13452             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13453             return true;
13454         } catch (IllegalArgumentException e) {
13455             if (!suppressLogs) {
13456                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13457             }
13458         }
13459         return false;
13460     }
13461
13462     /**
13463      * Schedule the given thread an FIFO scheduling priority.
13464      *
13465      * @param newTid the tid of the thread to adjust the scheduling of.
13466      * @param suppressLogs {@code true} if any error logging should be disabled.
13467      *
13468      * @return {@code true} if this succeeded.
13469      */
13470     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13471         try {
13472             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13473             return true;
13474         } catch (IllegalArgumentException e) {
13475             if (!suppressLogs) {
13476                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13477             }
13478         }
13479         return false;
13480     }
13481
13482     /**
13483      * Check that we have the features required for VR-related API calls, and throw an exception if
13484      * not.
13485      */
13486     private void enforceSystemHasVrFeature() {
13487         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13488             throw new UnsupportedOperationException("VR mode not supported on this device!");
13489         }
13490     }
13491
13492     @Override
13493     public void setRenderThread(int tid) {
13494         synchronized (this) {
13495             ProcessRecord proc;
13496             int pid = Binder.getCallingPid();
13497             if (pid == Process.myPid()) {
13498                 demoteSystemServerRenderThread(tid);
13499                 return;
13500             }
13501             synchronized (mPidsSelfLocked) {
13502                 proc = mPidsSelfLocked.get(pid);
13503                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13504                     // ensure the tid belongs to the process
13505                     if (!isThreadInProcess(pid, tid)) {
13506                         throw new IllegalArgumentException(
13507                             "Render thread does not belong to process");
13508                     }
13509                     proc.renderThreadTid = tid;
13510                     if (DEBUG_OOM_ADJ) {
13511                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13512                     }
13513                     // promote to FIFO now
13514                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13515                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13516                         if (mUseFifoUiScheduling) {
13517                             setThreadScheduler(proc.renderThreadTid,
13518                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13519                         } else {
13520                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13521                         }
13522                     }
13523                 } else {
13524                     if (DEBUG_OOM_ADJ) {
13525                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13526                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
13527                                mUseFifoUiScheduling);
13528                     }
13529                 }
13530             }
13531         }
13532     }
13533
13534     /**
13535      * We only use RenderThread in system_server to store task snapshots to the disk, which should
13536      * happen in the background. Thus, demote render thread from system_server to a lower priority.
13537      *
13538      * @param tid the tid of the RenderThread
13539      */
13540     private void demoteSystemServerRenderThread(int tid) {
13541         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13542     }
13543
13544     @Override
13545     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13546         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13547             throw new UnsupportedOperationException("VR mode not supported on this device!");
13548         }
13549
13550         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13551
13552         ActivityRecord r;
13553         synchronized (this) {
13554             r = ActivityRecord.isInStackLocked(token);
13555         }
13556
13557         if (r == null) {
13558             throw new IllegalArgumentException();
13559         }
13560
13561         int err;
13562         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13563                 VrManagerInternal.NO_ERROR) {
13564             return err;
13565         }
13566
13567         synchronized(this) {
13568             r.requestedVrComponent = (enabled) ? packageName : null;
13569
13570             // Update associated state if this activity is currently focused
13571             if (r == mStackSupervisor.getResumedActivityLocked()) {
13572                 applyUpdateVrModeLocked(r);
13573             }
13574             return 0;
13575         }
13576     }
13577
13578     @Override
13579     public boolean isVrModePackageEnabled(ComponentName packageName) {
13580         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13581             throw new UnsupportedOperationException("VR mode not supported on this device!");
13582         }
13583
13584         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13585
13586         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13587                 VrManagerInternal.NO_ERROR;
13588     }
13589
13590     public boolean isTopActivityImmersive() {
13591         enforceNotIsolatedCaller("startActivity");
13592         synchronized (this) {
13593             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13594             return (r != null) ? r.immersive : false;
13595         }
13596     }
13597
13598     /**
13599      * @return whether the system should disable UI modes incompatible with VR mode.
13600      */
13601     boolean shouldDisableNonVrUiLocked() {
13602         return mVrController.shouldDisableNonVrUiLocked();
13603     }
13604
13605     @Override
13606     public boolean isTopOfTask(IBinder token) {
13607         synchronized (this) {
13608             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13609             if (r == null) {
13610                 throw new IllegalArgumentException();
13611             }
13612             return r.getTask().getTopActivity() == r;
13613         }
13614     }
13615
13616     @Override
13617     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13618         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13619             String msg = "Permission Denial: setHasTopUi() from pid="
13620                     + Binder.getCallingPid()
13621                     + ", uid=" + Binder.getCallingUid()
13622                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13623             Slog.w(TAG, msg);
13624             throw new SecurityException(msg);
13625         }
13626         final int pid = Binder.getCallingPid();
13627         final long origId = Binder.clearCallingIdentity();
13628         try {
13629             synchronized (this) {
13630                 boolean changed = false;
13631                 ProcessRecord pr;
13632                 synchronized (mPidsSelfLocked) {
13633                     pr = mPidsSelfLocked.get(pid);
13634                     if (pr == null) {
13635                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13636                         return;
13637                     }
13638                     if (pr.hasTopUi != hasTopUi) {
13639                         if (DEBUG_OOM_ADJ) {
13640                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13641                         }
13642                         pr.hasTopUi = hasTopUi;
13643                         changed = true;
13644                     }
13645                 }
13646                 if (changed) {
13647                     updateOomAdjLocked(pr, true);
13648                 }
13649             }
13650         } finally {
13651             Binder.restoreCallingIdentity(origId);
13652         }
13653     }
13654
13655     public final void enterSafeMode() {
13656         synchronized(this) {
13657             // It only makes sense to do this before the system is ready
13658             // and started launching other packages.
13659             if (!mSystemReady) {
13660                 try {
13661                     AppGlobals.getPackageManager().enterSafeMode();
13662                 } catch (RemoteException e) {
13663                 }
13664             }
13665
13666             mSafeMode = true;
13667         }
13668     }
13669
13670     public final void showSafeModeOverlay() {
13671         View v = LayoutInflater.from(mContext).inflate(
13672                 com.android.internal.R.layout.safe_mode, null);
13673         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13674         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13675         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13676         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13677         lp.gravity = Gravity.BOTTOM | Gravity.START;
13678         lp.format = v.getBackground().getOpacity();
13679         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13680                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13681         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13682         ((WindowManager)mContext.getSystemService(
13683                 Context.WINDOW_SERVICE)).addView(v, lp);
13684     }
13685
13686     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13687         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13688             return;
13689         }
13690         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13691         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13692         synchronized (stats) {
13693             if (mBatteryStatsService.isOnBattery()) {
13694                 mBatteryStatsService.enforceCallingPermission();
13695                 int MY_UID = Binder.getCallingUid();
13696                 final int uid;
13697                 if (sender == null) {
13698                     uid = sourceUid;
13699                 } else {
13700                     uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13701                 }
13702                 BatteryStatsImpl.Uid.Pkg pkg =
13703                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13704                             sourcePkg != null ? sourcePkg : rec.key.packageName);
13705                 pkg.noteWakeupAlarmLocked(tag);
13706             }
13707         }
13708     }
13709
13710     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13711         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13712             return;
13713         }
13714         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13715         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13716         synchronized (stats) {
13717             mBatteryStatsService.enforceCallingPermission();
13718             int MY_UID = Binder.getCallingUid();
13719             final int uid;
13720             if (sender == null) {
13721                 uid = sourceUid;
13722             } else {
13723                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13724             }
13725             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13726         }
13727     }
13728
13729     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13730         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13731             return;
13732         }
13733         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13734         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13735         synchronized (stats) {
13736             mBatteryStatsService.enforceCallingPermission();
13737             int MY_UID = Binder.getCallingUid();
13738             final int uid;
13739             if (sender == null) {
13740                 uid = sourceUid;
13741             } else {
13742                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13743             }
13744             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13745         }
13746     }
13747
13748     public boolean killPids(int[] pids, String pReason, boolean secure) {
13749         if (Binder.getCallingUid() != SYSTEM_UID) {
13750             throw new SecurityException("killPids only available to the system");
13751         }
13752         String reason = (pReason == null) ? "Unknown" : pReason;
13753         // XXX Note: don't acquire main activity lock here, because the window
13754         // manager calls in with its locks held.
13755
13756         boolean killed = false;
13757         synchronized (mPidsSelfLocked) {
13758             int worstType = 0;
13759             for (int i=0; i<pids.length; i++) {
13760                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13761                 if (proc != null) {
13762                     int type = proc.setAdj;
13763                     if (type > worstType) {
13764                         worstType = type;
13765                     }
13766                 }
13767             }
13768
13769             // If the worst oom_adj is somewhere in the cached proc LRU range,
13770             // then constrain it so we will kill all cached procs.
13771             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13772                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13773                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13774             }
13775
13776             // If this is not a secure call, don't let it kill processes that
13777             // are important.
13778             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13779                 worstType = ProcessList.SERVICE_ADJ;
13780             }
13781
13782             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13783             for (int i=0; i<pids.length; i++) {
13784                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13785                 if (proc == null) {
13786                     continue;
13787                 }
13788                 int adj = proc.setAdj;
13789                 if (adj >= worstType && !proc.killedByAm) {
13790                     proc.kill(reason, true);
13791                     killed = true;
13792                 }
13793             }
13794         }
13795         return killed;
13796     }
13797
13798     @Override
13799     public void killUid(int appId, int userId, String reason) {
13800         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13801         synchronized (this) {
13802             final long identity = Binder.clearCallingIdentity();
13803             try {
13804                 killPackageProcessesLocked(null, appId, userId,
13805                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13806                         reason != null ? reason : "kill uid");
13807             } finally {
13808                 Binder.restoreCallingIdentity(identity);
13809             }
13810         }
13811     }
13812
13813     @Override
13814     public boolean killProcessesBelowForeground(String reason) {
13815         if (Binder.getCallingUid() != SYSTEM_UID) {
13816             throw new SecurityException("killProcessesBelowForeground() only available to system");
13817         }
13818
13819         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13820     }
13821
13822     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13823         if (Binder.getCallingUid() != SYSTEM_UID) {
13824             throw new SecurityException("killProcessesBelowAdj() only available to system");
13825         }
13826
13827         boolean killed = false;
13828         synchronized (mPidsSelfLocked) {
13829             final int size = mPidsSelfLocked.size();
13830             for (int i = 0; i < size; i++) {
13831                 final int pid = mPidsSelfLocked.keyAt(i);
13832                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13833                 if (proc == null) continue;
13834
13835                 final int adj = proc.setAdj;
13836                 if (adj > belowAdj && !proc.killedByAm) {
13837                     proc.kill(reason, true);
13838                     killed = true;
13839                 }
13840             }
13841         }
13842         return killed;
13843     }
13844
13845     @Override
13846     public void hang(final IBinder who, boolean allowRestart) {
13847         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13848                 != PackageManager.PERMISSION_GRANTED) {
13849             throw new SecurityException("Requires permission "
13850                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13851         }
13852
13853         final IBinder.DeathRecipient death = new DeathRecipient() {
13854             @Override
13855             public void binderDied() {
13856                 synchronized (this) {
13857                     notifyAll();
13858                 }
13859             }
13860         };
13861
13862         try {
13863             who.linkToDeath(death, 0);
13864         } catch (RemoteException e) {
13865             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13866             return;
13867         }
13868
13869         synchronized (this) {
13870             Watchdog.getInstance().setAllowRestart(allowRestart);
13871             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13872             synchronized (death) {
13873                 while (who.isBinderAlive()) {
13874                     try {
13875                         death.wait();
13876                     } catch (InterruptedException e) {
13877                     }
13878                 }
13879             }
13880             Watchdog.getInstance().setAllowRestart(true);
13881         }
13882     }
13883
13884     @Override
13885     public void restart() {
13886         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13887                 != PackageManager.PERMISSION_GRANTED) {
13888             throw new SecurityException("Requires permission "
13889                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13890         }
13891
13892         Log.i(TAG, "Sending shutdown broadcast...");
13893
13894         BroadcastReceiver br = new BroadcastReceiver() {
13895             @Override public void onReceive(Context context, Intent intent) {
13896                 // Now the broadcast is done, finish up the low-level shutdown.
13897                 Log.i(TAG, "Shutting down activity manager...");
13898                 shutdown(10000);
13899                 Log.i(TAG, "Shutdown complete, restarting!");
13900                 killProcess(myPid());
13901                 System.exit(10);
13902             }
13903         };
13904
13905         // First send the high-level shut down broadcast.
13906         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13907         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13908         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13909         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13910         mContext.sendOrderedBroadcastAsUser(intent,
13911                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13912         */
13913         br.onReceive(mContext, intent);
13914     }
13915
13916     private long getLowRamTimeSinceIdle(long now) {
13917         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13918     }
13919
13920     @Override
13921     public void performIdleMaintenance() {
13922         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13923                 != PackageManager.PERMISSION_GRANTED) {
13924             throw new SecurityException("Requires permission "
13925                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13926         }
13927
13928         synchronized (this) {
13929             final long now = SystemClock.uptimeMillis();
13930             final long timeSinceLastIdle = now - mLastIdleTime;
13931             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13932             mLastIdleTime = now;
13933             mLowRamTimeSinceLastIdle = 0;
13934             if (mLowRamStartTime != 0) {
13935                 mLowRamStartTime = now;
13936             }
13937
13938             StringBuilder sb = new StringBuilder(128);
13939             sb.append("Idle maintenance over ");
13940             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13941             sb.append(" low RAM for ");
13942             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13943             Slog.i(TAG, sb.toString());
13944
13945             // If at least 1/3 of our time since the last idle period has been spent
13946             // with RAM low, then we want to kill processes.
13947             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13948
13949             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13950                 ProcessRecord proc = mLruProcesses.get(i);
13951                 if (proc.notCachedSinceIdle) {
13952                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13953                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13954                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13955                         if (doKilling && proc.initialIdlePss != 0
13956                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13957                             sb = new StringBuilder(128);
13958                             sb.append("Kill");
13959                             sb.append(proc.processName);
13960                             sb.append(" in idle maint: pss=");
13961                             sb.append(proc.lastPss);
13962                             sb.append(", swapPss=");
13963                             sb.append(proc.lastSwapPss);
13964                             sb.append(", initialPss=");
13965                             sb.append(proc.initialIdlePss);
13966                             sb.append(", period=");
13967                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13968                             sb.append(", lowRamPeriod=");
13969                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13970                             Slog.wtfQuiet(TAG, sb.toString());
13971                             proc.kill("idle maint (pss " + proc.lastPss
13972                                     + " from " + proc.initialIdlePss + ")", true);
13973                         }
13974                     }
13975                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13976                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13977                     proc.notCachedSinceIdle = true;
13978                     proc.initialIdlePss = 0;
13979                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13980                             mTestPssMode, isSleepingLocked(), now);
13981                 }
13982             }
13983
13984             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13985             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13986         }
13987     }
13988
13989     @Override
13990     public void sendIdleJobTrigger() {
13991         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13992                 != PackageManager.PERMISSION_GRANTED) {
13993             throw new SecurityException("Requires permission "
13994                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13995         }
13996
13997         final long ident = Binder.clearCallingIdentity();
13998         try {
13999             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14000                     .setPackage("android")
14001                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14002             broadcastIntent(null, intent, null, null, 0, null, null, null,
14003                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14004         } finally {
14005             Binder.restoreCallingIdentity(ident);
14006         }
14007     }
14008
14009     private void retrieveSettings() {
14010         final ContentResolver resolver = mContext.getContentResolver();
14011         final boolean freeformWindowManagement =
14012                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14013                         || Settings.Global.getInt(
14014                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14015         final boolean supportsPictureInPicture =
14016                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14017
14018         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14019         final boolean supportsSplitScreenMultiWindow =
14020                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14021         final boolean supportsMultiDisplay = mContext.getPackageManager()
14022                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14023         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14024         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14025         final boolean alwaysFinishActivities =
14026                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14027         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14028         final boolean forceResizable = Settings.Global.getInt(
14029                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14030         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14031                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14032         final boolean supportsLeanbackOnly =
14033                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14034
14035         // Transfer any global setting for forcing RTL layout, into a System Property
14036         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14037
14038         final Configuration configuration = new Configuration();
14039         Settings.System.getConfiguration(resolver, configuration);
14040         if (forceRtl) {
14041             // This will take care of setting the correct layout direction flags
14042             configuration.setLayoutDirection(configuration.locale);
14043         }
14044
14045         synchronized (this) {
14046             mDebugApp = mOrigDebugApp = debugApp;
14047             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14048             mAlwaysFinishActivities = alwaysFinishActivities;
14049             mSupportsLeanbackOnly = supportsLeanbackOnly;
14050             mForceResizableActivities = forceResizable;
14051             final boolean multiWindowFormEnabled = freeformWindowManagement
14052                     || supportsSplitScreenMultiWindow
14053                     || supportsPictureInPicture
14054                     || supportsMultiDisplay;
14055             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14056                 mSupportsMultiWindow = true;
14057                 mSupportsFreeformWindowManagement = freeformWindowManagement;
14058                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14059                 mSupportsPictureInPicture = supportsPictureInPicture;
14060                 mSupportsMultiDisplay = supportsMultiDisplay;
14061             } else {
14062                 mSupportsMultiWindow = false;
14063                 mSupportsFreeformWindowManagement = false;
14064                 mSupportsSplitScreenMultiWindow = false;
14065                 mSupportsPictureInPicture = false;
14066                 mSupportsMultiDisplay = false;
14067             }
14068             mWindowManager.setForceResizableTasks(mForceResizableActivities);
14069             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14070             // This happens before any activities are started, so we can change global configuration
14071             // in-place.
14072             updateConfigurationLocked(configuration, null, true);
14073             final Configuration globalConfig = getGlobalConfiguration();
14074             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14075
14076             // Load resources only after the current configuration has been set.
14077             final Resources res = mContext.getResources();
14078             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14079             mThumbnailWidth = res.getDimensionPixelSize(
14080                     com.android.internal.R.dimen.thumbnail_width);
14081             mThumbnailHeight = res.getDimensionPixelSize(
14082                     com.android.internal.R.dimen.thumbnail_height);
14083             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14084                     com.android.internal.R.string.config_appsNotReportingCrashes));
14085             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14086                     com.android.internal.R.bool.config_customUserSwitchUi);
14087             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14088                 mFullscreenThumbnailScale = (float) res
14089                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14090                     (float) globalConfig.screenWidthDp;
14091             } else {
14092                 mFullscreenThumbnailScale = res.getFraction(
14093                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14094             }
14095             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14096         }
14097     }
14098
14099     public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
14100         traceLog.traceBegin("PhaseActivityManagerReady");
14101         synchronized(this) {
14102             if (mSystemReady) {
14103                 // If we're done calling all the receivers, run the next "boot phase" passed in
14104                 // by the SystemServer
14105                 if (goingCallback != null) {
14106                     goingCallback.run();
14107                 }
14108                 return;
14109             }
14110
14111             mLocalDeviceIdleController
14112                     = LocalServices.getService(DeviceIdleController.LocalService.class);
14113             mAssistUtils = new AssistUtils(mContext);
14114             mVrController.onSystemReady();
14115             // Make sure we have the current profile info, since it is needed for security checks.
14116             mUserController.onSystemReady();
14117             mRecentTasks.onSystemReadyLocked();
14118             mAppOpsService.systemReady();
14119             mSystemReady = true;
14120         }
14121
14122         ArrayList<ProcessRecord> procsToKill = null;
14123         synchronized(mPidsSelfLocked) {
14124             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14125                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14126                 if (!isAllowedWhileBooting(proc.info)){
14127                     if (procsToKill == null) {
14128                         procsToKill = new ArrayList<ProcessRecord>();
14129                     }
14130                     procsToKill.add(proc);
14131                 }
14132             }
14133         }
14134
14135         synchronized(this) {
14136             if (procsToKill != null) {
14137                 for (int i=procsToKill.size()-1; i>=0; i--) {
14138                     ProcessRecord proc = procsToKill.get(i);
14139                     Slog.i(TAG, "Removing system update proc: " + proc);
14140                     removeProcessLocked(proc, true, false, "system update done");
14141                 }
14142             }
14143
14144             // Now that we have cleaned up any update processes, we
14145             // are ready to start launching real processes and know that
14146             // we won't trample on them any more.
14147             mProcessesReady = true;
14148         }
14149
14150         Slog.i(TAG, "System now ready");
14151         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14152             SystemClock.uptimeMillis());
14153
14154         synchronized(this) {
14155             // Make sure we have no pre-ready processes sitting around.
14156
14157             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14158                 ResolveInfo ri = mContext.getPackageManager()
14159                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14160                                 STOCK_PM_FLAGS);
14161                 CharSequence errorMsg = null;
14162                 if (ri != null) {
14163                     ActivityInfo ai = ri.activityInfo;
14164                     ApplicationInfo app = ai.applicationInfo;
14165                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14166                         mTopAction = Intent.ACTION_FACTORY_TEST;
14167                         mTopData = null;
14168                         mTopComponent = new ComponentName(app.packageName,
14169                                 ai.name);
14170                     } else {
14171                         errorMsg = mContext.getResources().getText(
14172                                 com.android.internal.R.string.factorytest_not_system);
14173                     }
14174                 } else {
14175                     errorMsg = mContext.getResources().getText(
14176                             com.android.internal.R.string.factorytest_no_action);
14177                 }
14178                 if (errorMsg != null) {
14179                     mTopAction = null;
14180                     mTopData = null;
14181                     mTopComponent = null;
14182                     Message msg = Message.obtain();
14183                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14184                     msg.getData().putCharSequence("msg", errorMsg);
14185                     mUiHandler.sendMessage(msg);
14186                 }
14187             }
14188         }
14189
14190         retrieveSettings();
14191         final int currentUserId;
14192         synchronized (this) {
14193             currentUserId = mUserController.getCurrentUserIdLocked();
14194             readGrantedUriPermissionsLocked();
14195         }
14196
14197         if (goingCallback != null) goingCallback.run();
14198         traceLog.traceBegin("ActivityManagerStartApps");
14199         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14200                 Integer.toString(currentUserId), currentUserId);
14201         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14202                 Integer.toString(currentUserId), currentUserId);
14203         mSystemServiceManager.startUser(currentUserId);
14204
14205         synchronized (this) {
14206             // Only start up encryption-aware persistent apps; once user is
14207             // unlocked we'll come back around and start unaware apps
14208             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14209
14210             // Start up initial activity.
14211             mBooting = true;
14212             // Enable home activity for system user, so that the system can always boot. We don't
14213             // do this when the system user is not setup since the setup wizard should be the one
14214             // to handle home activity in this case.
14215             if (UserManager.isSplitSystemUser() &&
14216                     Settings.Secure.getInt(mContext.getContentResolver(),
14217                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14218                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14219                 try {
14220                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14221                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14222                             UserHandle.USER_SYSTEM);
14223                 } catch (RemoteException e) {
14224                     throw e.rethrowAsRuntimeException();
14225                 }
14226             }
14227             startHomeActivityLocked(currentUserId, "systemReady");
14228
14229             try {
14230                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14231                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14232                             + " data partition or your device will be unstable.");
14233                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14234                 }
14235             } catch (RemoteException e) {
14236             }
14237
14238             if (!Build.isBuildConsistent()) {
14239                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14240                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14241             }
14242
14243             long ident = Binder.clearCallingIdentity();
14244             try {
14245                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14246                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14247                         | Intent.FLAG_RECEIVER_FOREGROUND);
14248                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14249                 broadcastIntentLocked(null, null, intent,
14250                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14251                         null, false, false, MY_PID, SYSTEM_UID,
14252                         currentUserId);
14253                 intent = new Intent(Intent.ACTION_USER_STARTING);
14254                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14255                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14256                 broadcastIntentLocked(null, null, intent,
14257                         null, new IIntentReceiver.Stub() {
14258                             @Override
14259                             public void performReceive(Intent intent, int resultCode, String data,
14260                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14261                                     throws RemoteException {
14262                             }
14263                         }, 0, null, null,
14264                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14265                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14266             } catch (Throwable t) {
14267                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14268             } finally {
14269                 Binder.restoreCallingIdentity(ident);
14270             }
14271             mStackSupervisor.resumeFocusedStackTopActivityLocked();
14272             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14273             traceLog.traceEnd(); // ActivityManagerStartApps
14274             traceLog.traceEnd(); // PhaseActivityManagerReady
14275         }
14276     }
14277
14278     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14279         synchronized (this) {
14280             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14281         }
14282     }
14283
14284     void skipCurrentReceiverLocked(ProcessRecord app) {
14285         for (BroadcastQueue queue : mBroadcastQueues) {
14286             queue.skipCurrentReceiverLocked(app);
14287         }
14288     }
14289
14290     /**
14291      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14292      * The application process will exit immediately after this call returns.
14293      * @param app object of the crashing app, null for the system server
14294      * @param crashInfo describing the exception
14295      */
14296     public void handleApplicationCrash(IBinder app,
14297             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14298         ProcessRecord r = findAppProcess(app, "Crash");
14299         final String processName = app == null ? "system_server"
14300                 : (r == null ? "unknown" : r.processName);
14301
14302         handleApplicationCrashInner("crash", r, processName, crashInfo);
14303     }
14304
14305     /* Native crash reporting uses this inner version because it needs to be somewhat
14306      * decoupled from the AM-managed cleanup lifecycle
14307      */
14308     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14309             ApplicationErrorReport.CrashInfo crashInfo) {
14310         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14311                 UserHandle.getUserId(Binder.getCallingUid()), processName,
14312                 r == null ? -1 : r.info.flags,
14313                 crashInfo.exceptionClassName,
14314                 crashInfo.exceptionMessage,
14315                 crashInfo.throwFileName,
14316                 crashInfo.throwLineNumber);
14317
14318         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14319
14320         mAppErrors.crashApplication(r, crashInfo);
14321     }
14322
14323     public void handleApplicationStrictModeViolation(
14324             IBinder app,
14325             int violationMask,
14326             StrictMode.ViolationInfo info) {
14327         ProcessRecord r = findAppProcess(app, "StrictMode");
14328         if (r == null) {
14329             return;
14330         }
14331
14332         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14333             Integer stackFingerprint = info.hashCode();
14334             boolean logIt = true;
14335             synchronized (mAlreadyLoggedViolatedStacks) {
14336                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14337                     logIt = false;
14338                     // TODO: sub-sample into EventLog for these, with
14339                     // the info.durationMillis?  Then we'd get
14340                     // the relative pain numbers, without logging all
14341                     // the stack traces repeatedly.  We'd want to do
14342                     // likewise in the client code, which also does
14343                     // dup suppression, before the Binder call.
14344                 } else {
14345                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14346                         mAlreadyLoggedViolatedStacks.clear();
14347                     }
14348                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14349                 }
14350             }
14351             if (logIt) {
14352                 logStrictModeViolationToDropBox(r, info);
14353             }
14354         }
14355
14356         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14357             AppErrorResult result = new AppErrorResult();
14358             synchronized (this) {
14359                 final long origId = Binder.clearCallingIdentity();
14360
14361                 Message msg = Message.obtain();
14362                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14363                 HashMap<String, Object> data = new HashMap<String, Object>();
14364                 data.put("result", result);
14365                 data.put("app", r);
14366                 data.put("violationMask", violationMask);
14367                 data.put("info", info);
14368                 msg.obj = data;
14369                 mUiHandler.sendMessage(msg);
14370
14371                 Binder.restoreCallingIdentity(origId);
14372             }
14373             int res = result.get();
14374             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14375         }
14376     }
14377
14378     // Depending on the policy in effect, there could be a bunch of
14379     // these in quick succession so we try to batch these together to
14380     // minimize disk writes, number of dropbox entries, and maximize
14381     // compression, by having more fewer, larger records.
14382     private void logStrictModeViolationToDropBox(
14383             ProcessRecord process,
14384             StrictMode.ViolationInfo info) {
14385         if (info == null) {
14386             return;
14387         }
14388         final boolean isSystemApp = process == null ||
14389                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14390                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14391         final String processName = process == null ? "unknown" : process.processName;
14392         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14393         final DropBoxManager dbox = (DropBoxManager)
14394                 mContext.getSystemService(Context.DROPBOX_SERVICE);
14395
14396         // Exit early if the dropbox isn't configured to accept this report type.
14397         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14398
14399         boolean bufferWasEmpty;
14400         boolean needsFlush;
14401         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14402         synchronized (sb) {
14403             bufferWasEmpty = sb.length() == 0;
14404             appendDropBoxProcessHeaders(process, processName, sb);
14405             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14406             sb.append("System-App: ").append(isSystemApp).append("\n");
14407             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14408             if (info.violationNumThisLoop != 0) {
14409                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14410             }
14411             if (info.numAnimationsRunning != 0) {
14412                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14413             }
14414             if (info.broadcastIntentAction != null) {
14415                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14416             }
14417             if (info.durationMillis != -1) {
14418                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14419             }
14420             if (info.numInstances != -1) {
14421                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14422             }
14423             if (info.tags != null) {
14424                 for (String tag : info.tags) {
14425                     sb.append("Span-Tag: ").append(tag).append("\n");
14426                 }
14427             }
14428             sb.append("\n");
14429             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14430                 sb.append(info.crashInfo.stackTrace);
14431                 sb.append("\n");
14432             }
14433             if (info.message != null) {
14434                 sb.append(info.message);
14435                 sb.append("\n");
14436             }
14437
14438             // Only buffer up to ~64k.  Various logging bits truncate
14439             // things at 128k.
14440             needsFlush = (sb.length() > 64 * 1024);
14441         }
14442
14443         // Flush immediately if the buffer's grown too large, or this
14444         // is a non-system app.  Non-system apps are isolated with a
14445         // different tag & policy and not batched.
14446         //
14447         // Batching is useful during internal testing with
14448         // StrictMode settings turned up high.  Without batching,
14449         // thousands of separate files could be created on boot.
14450         if (!isSystemApp || needsFlush) {
14451             new Thread("Error dump: " + dropboxTag) {
14452                 @Override
14453                 public void run() {
14454                     String report;
14455                     synchronized (sb) {
14456                         report = sb.toString();
14457                         sb.delete(0, sb.length());
14458                         sb.trimToSize();
14459                     }
14460                     if (report.length() != 0) {
14461                         dbox.addText(dropboxTag, report);
14462                     }
14463                 }
14464             }.start();
14465             return;
14466         }
14467
14468         // System app batching:
14469         if (!bufferWasEmpty) {
14470             // An existing dropbox-writing thread is outstanding, so
14471             // we don't need to start it up.  The existing thread will
14472             // catch the buffer appends we just did.
14473             return;
14474         }
14475
14476         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14477         // (After this point, we shouldn't access AMS internal data structures.)
14478         new Thread("Error dump: " + dropboxTag) {
14479             @Override
14480             public void run() {
14481                 // 5 second sleep to let stacks arrive and be batched together
14482                 try {
14483                     Thread.sleep(5000);  // 5 seconds
14484                 } catch (InterruptedException e) {}
14485
14486                 String errorReport;
14487                 synchronized (mStrictModeBuffer) {
14488                     errorReport = mStrictModeBuffer.toString();
14489                     if (errorReport.length() == 0) {
14490                         return;
14491                     }
14492                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14493                     mStrictModeBuffer.trimToSize();
14494                 }
14495                 dbox.addText(dropboxTag, errorReport);
14496             }
14497         }.start();
14498     }
14499
14500     /**
14501      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14502      * @param app object of the crashing app, null for the system server
14503      * @param tag reported by the caller
14504      * @param system whether this wtf is coming from the system
14505      * @param crashInfo describing the context of the error
14506      * @return true if the process should exit immediately (WTF is fatal)
14507      */
14508     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14509             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14510         final int callingUid = Binder.getCallingUid();
14511         final int callingPid = Binder.getCallingPid();
14512
14513         if (system) {
14514             // If this is coming from the system, we could very well have low-level
14515             // system locks held, so we want to do this all asynchronously.  And we
14516             // never want this to become fatal, so there is that too.
14517             mHandler.post(new Runnable() {
14518                 @Override public void run() {
14519                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14520                 }
14521             });
14522             return false;
14523         }
14524
14525         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14526                 crashInfo);
14527
14528         final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14529                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14530         final boolean isSystem = (r == null) || r.persistent;
14531
14532         if (isFatal && !isSystem) {
14533             mAppErrors.crashApplication(r, crashInfo);
14534             return true;
14535         } else {
14536             return false;
14537         }
14538     }
14539
14540     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14541             final ApplicationErrorReport.CrashInfo crashInfo) {
14542         final ProcessRecord r = findAppProcess(app, "WTF");
14543         final String processName = app == null ? "system_server"
14544                 : (r == null ? "unknown" : r.processName);
14545
14546         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14547                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14548
14549         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14550
14551         return r;
14552     }
14553
14554     /**
14555      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14556      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14557      */
14558     private ProcessRecord findAppProcess(IBinder app, String reason) {
14559         if (app == null) {
14560             return null;
14561         }
14562
14563         synchronized (this) {
14564             final int NP = mProcessNames.getMap().size();
14565             for (int ip=0; ip<NP; ip++) {
14566                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14567                 final int NA = apps.size();
14568                 for (int ia=0; ia<NA; ia++) {
14569                     ProcessRecord p = apps.valueAt(ia);
14570                     if (p.thread != null && p.thread.asBinder() == app) {
14571                         return p;
14572                     }
14573                 }
14574             }
14575
14576             Slog.w(TAG, "Can't find mystery application for " + reason
14577                     + " from pid=" + Binder.getCallingPid()
14578                     + " uid=" + Binder.getCallingUid() + ": " + app);
14579             return null;
14580         }
14581     }
14582
14583     /**
14584      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14585      * to append various headers to the dropbox log text.
14586      */
14587     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14588             StringBuilder sb) {
14589         // Watchdog thread ends up invoking this function (with
14590         // a null ProcessRecord) to add the stack file to dropbox.
14591         // Do not acquire a lock on this (am) in such cases, as it
14592         // could cause a potential deadlock, if and when watchdog
14593         // is invoked due to unavailability of lock on am and it
14594         // would prevent watchdog from killing system_server.
14595         if (process == null) {
14596             sb.append("Process: ").append(processName).append("\n");
14597             return;
14598         }
14599         // Note: ProcessRecord 'process' is guarded by the service
14600         // instance.  (notably process.pkgList, which could otherwise change
14601         // concurrently during execution of this method)
14602         synchronized (this) {
14603             sb.append("Process: ").append(processName).append("\n");
14604             sb.append("PID: ").append(process.pid).append("\n");
14605             int flags = process.info.flags;
14606             IPackageManager pm = AppGlobals.getPackageManager();
14607             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14608             for (int ip=0; ip<process.pkgList.size(); ip++) {
14609                 String pkg = process.pkgList.keyAt(ip);
14610                 sb.append("Package: ").append(pkg);
14611                 try {
14612                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14613                     if (pi != null) {
14614                         sb.append(" v").append(pi.versionCode);
14615                         if (pi.versionName != null) {
14616                             sb.append(" (").append(pi.versionName).append(")");
14617                         }
14618                     }
14619                 } catch (RemoteException e) {
14620                     Slog.e(TAG, "Error getting package info: " + pkg, e);
14621                 }
14622                 sb.append("\n");
14623             }
14624         }
14625     }
14626
14627     private static String processClass(ProcessRecord process) {
14628         if (process == null || process.pid == MY_PID) {
14629             return "system_server";
14630         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14631             return "system_app";
14632         } else {
14633             return "data_app";
14634         }
14635     }
14636
14637     private volatile long mWtfClusterStart;
14638     private volatile int mWtfClusterCount;
14639
14640     /**
14641      * Write a description of an error (crash, WTF, ANR) to the drop box.
14642      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14643      * @param process which caused the error, null means the system server
14644      * @param activity which triggered the error, null if unknown
14645      * @param parent activity related to the error, null if unknown
14646      * @param subject line related to the error, null if absent
14647      * @param report in long form describing the error, null if absent
14648      * @param dataFile text file to include in the report, null if none
14649      * @param crashInfo giving an application stack trace, null if absent
14650      */
14651     public void addErrorToDropBox(String eventType,
14652             ProcessRecord process, String processName, ActivityRecord activity,
14653             ActivityRecord parent, String subject,
14654             final String report, final File dataFile,
14655             final ApplicationErrorReport.CrashInfo crashInfo) {
14656         // NOTE -- this must never acquire the ActivityManagerService lock,
14657         // otherwise the watchdog may be prevented from resetting the system.
14658
14659         // Bail early if not published yet
14660         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14661         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14662
14663         // Exit early if the dropbox isn't configured to accept this report type.
14664         final String dropboxTag = processClass(process) + "_" + eventType;
14665         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14666
14667         // Rate-limit how often we're willing to do the heavy lifting below to
14668         // collect and record logs; currently 5 logs per 10 second period.
14669         final long now = SystemClock.elapsedRealtime();
14670         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14671             mWtfClusterStart = now;
14672             mWtfClusterCount = 1;
14673         } else {
14674             if (mWtfClusterCount++ >= 5) return;
14675         }
14676
14677         final StringBuilder sb = new StringBuilder(1024);
14678         appendDropBoxProcessHeaders(process, processName, sb);
14679         if (process != null) {
14680             sb.append("Foreground: ")
14681                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14682                     .append("\n");
14683         }
14684         if (activity != null) {
14685             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14686         }
14687         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14688             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14689         }
14690         if (parent != null && parent != activity) {
14691             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14692         }
14693         if (subject != null) {
14694             sb.append("Subject: ").append(subject).append("\n");
14695         }
14696         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14697         if (Debug.isDebuggerConnected()) {
14698             sb.append("Debugger: Connected\n");
14699         }
14700         sb.append("\n");
14701
14702         // Do the rest in a worker thread to avoid blocking the caller on I/O
14703         // (After this point, we shouldn't access AMS internal data structures.)
14704         Thread worker = new Thread("Error dump: " + dropboxTag) {
14705             @Override
14706             public void run() {
14707                 if (report != null) {
14708                     sb.append(report);
14709                 }
14710
14711                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14712                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14713                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14714                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14715
14716                 if (dataFile != null && maxDataFileSize > 0) {
14717                     try {
14718                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14719                                     "\n\n[[TRUNCATED]]"));
14720                     } catch (IOException e) {
14721                         Slog.e(TAG, "Error reading " + dataFile, e);
14722                     }
14723                 }
14724                 if (crashInfo != null && crashInfo.stackTrace != null) {
14725                     sb.append(crashInfo.stackTrace);
14726                 }
14727
14728                 if (lines > 0) {
14729                     sb.append("\n");
14730
14731                     // Merge several logcat streams, and take the last N lines
14732                     InputStreamReader input = null;
14733                     try {
14734                         java.lang.Process logcat = new ProcessBuilder(
14735                                 "/system/bin/timeout", "-k", "15s", "10s",
14736                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14737                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14738                                         .redirectErrorStream(true).start();
14739
14740                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
14741                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
14742                         input = new InputStreamReader(logcat.getInputStream());
14743
14744                         int num;
14745                         char[] buf = new char[8192];
14746                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14747                     } catch (IOException e) {
14748                         Slog.e(TAG, "Error running logcat", e);
14749                     } finally {
14750                         if (input != null) try { input.close(); } catch (IOException e) {}
14751                     }
14752                 }
14753
14754                 dbox.addText(dropboxTag, sb.toString());
14755             }
14756         };
14757
14758         if (process == null) {
14759             // If process is null, we are being called from some internal code
14760             // and may be about to die -- run this synchronously.
14761             worker.run();
14762         } else {
14763             worker.start();
14764         }
14765     }
14766
14767     @Override
14768     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14769         enforceNotIsolatedCaller("getProcessesInErrorState");
14770         // assume our apps are happy - lazy create the list
14771         List<ActivityManager.ProcessErrorStateInfo> errList = null;
14772
14773         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14774                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14775         int userId = UserHandle.getUserId(Binder.getCallingUid());
14776
14777         synchronized (this) {
14778
14779             // iterate across all processes
14780             for (int i=mLruProcesses.size()-1; i>=0; i--) {
14781                 ProcessRecord app = mLruProcesses.get(i);
14782                 if (!allUsers && app.userId != userId) {
14783                     continue;
14784                 }
14785                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14786                     // This one's in trouble, so we'll generate a report for it
14787                     // crashes are higher priority (in case there's a crash *and* an anr)
14788                     ActivityManager.ProcessErrorStateInfo report = null;
14789                     if (app.crashing) {
14790                         report = app.crashingReport;
14791                     } else if (app.notResponding) {
14792                         report = app.notRespondingReport;
14793                     }
14794
14795                     if (report != null) {
14796                         if (errList == null) {
14797                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14798                         }
14799                         errList.add(report);
14800                     } else {
14801                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
14802                                 " crashing = " + app.crashing +
14803                                 " notResponding = " + app.notResponding);
14804                     }
14805                 }
14806             }
14807         }
14808
14809         return errList;
14810     }
14811
14812     static int procStateToImportance(int procState, int memAdj,
14813             ActivityManager.RunningAppProcessInfo currApp,
14814             int clientTargetSdk) {
14815         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14816                 procState, clientTargetSdk);
14817         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14818             currApp.lru = memAdj;
14819         } else {
14820             currApp.lru = 0;
14821         }
14822         return imp;
14823     }
14824
14825     private void fillInProcMemInfo(ProcessRecord app,
14826             ActivityManager.RunningAppProcessInfo outInfo,
14827             int clientTargetSdk) {
14828         outInfo.pid = app.pid;
14829         outInfo.uid = app.info.uid;
14830         if (mHeavyWeightProcess == app) {
14831             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14832         }
14833         if (app.persistent) {
14834             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14835         }
14836         if (app.activities.size() > 0) {
14837             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14838         }
14839         outInfo.lastTrimLevel = app.trimMemoryLevel;
14840         int adj = app.curAdj;
14841         int procState = app.curProcState;
14842         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14843         outInfo.importanceReasonCode = app.adjTypeCode;
14844         outInfo.processState = app.curProcState;
14845     }
14846
14847     @Override
14848     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14849         enforceNotIsolatedCaller("getRunningAppProcesses");
14850
14851         final int callingUid = Binder.getCallingUid();
14852         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14853
14854         // Lazy instantiation of list
14855         List<ActivityManager.RunningAppProcessInfo> runList = null;
14856         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14857                 callingUid) == PackageManager.PERMISSION_GRANTED;
14858         final int userId = UserHandle.getUserId(callingUid);
14859         final boolean allUids = isGetTasksAllowed(
14860                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14861
14862         synchronized (this) {
14863             // Iterate across all processes
14864             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14865                 ProcessRecord app = mLruProcesses.get(i);
14866                 if ((!allUsers && app.userId != userId)
14867                         || (!allUids && app.uid != callingUid)) {
14868                     continue;
14869                 }
14870                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14871                     // Generate process state info for running application
14872                     ActivityManager.RunningAppProcessInfo currApp =
14873                         new ActivityManager.RunningAppProcessInfo(app.processName,
14874                                 app.pid, app.getPackageList());
14875                     fillInProcMemInfo(app, currApp, clientTargetSdk);
14876                     if (app.adjSource instanceof ProcessRecord) {
14877                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14878                         currApp.importanceReasonImportance =
14879                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14880                                         app.adjSourceProcState);
14881                     } else if (app.adjSource instanceof ActivityRecord) {
14882                         ActivityRecord r = (ActivityRecord)app.adjSource;
14883                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14884                     }
14885                     if (app.adjTarget instanceof ComponentName) {
14886                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14887                     }
14888                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14889                     //        + " lru=" + currApp.lru);
14890                     if (runList == null) {
14891                         runList = new ArrayList<>();
14892                     }
14893                     runList.add(currApp);
14894                 }
14895             }
14896         }
14897         return runList;
14898     }
14899
14900     @Override
14901     public List<ApplicationInfo> getRunningExternalApplications() {
14902         enforceNotIsolatedCaller("getRunningExternalApplications");
14903         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14904         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14905         if (runningApps != null && runningApps.size() > 0) {
14906             Set<String> extList = new HashSet<String>();
14907             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14908                 if (app.pkgList != null) {
14909                     for (String pkg : app.pkgList) {
14910                         extList.add(pkg);
14911                     }
14912                 }
14913             }
14914             IPackageManager pm = AppGlobals.getPackageManager();
14915             for (String pkg : extList) {
14916                 try {
14917                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14918                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14919                         retList.add(info);
14920                     }
14921                 } catch (RemoteException e) {
14922                 }
14923             }
14924         }
14925         return retList;
14926     }
14927
14928     @Override
14929     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14930         enforceNotIsolatedCaller("getMyMemoryState");
14931
14932         final int callingUid = Binder.getCallingUid();
14933         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14934
14935         synchronized (this) {
14936             ProcessRecord proc;
14937             synchronized (mPidsSelfLocked) {
14938                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14939             }
14940             fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14941         }
14942     }
14943
14944     @Override
14945     public int getMemoryTrimLevel() {
14946         enforceNotIsolatedCaller("getMyMemoryState");
14947         synchronized (this) {
14948             return mLastMemoryLevel;
14949         }
14950     }
14951
14952     @Override
14953     public void onShellCommand(FileDescriptor in, FileDescriptor out,
14954             FileDescriptor err, String[] args, ShellCallback callback,
14955             ResultReceiver resultReceiver) {
14956         (new ActivityManagerShellCommand(this, false)).exec(
14957                 this, in, out, err, args, callback, resultReceiver);
14958     }
14959
14960     @Override
14961     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14962         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14963
14964         boolean dumpAll = false;
14965         boolean dumpClient = false;
14966         boolean dumpCheckin = false;
14967         boolean dumpCheckinFormat = false;
14968         boolean dumpVisibleStacksOnly = false;
14969         boolean dumpFocusedStackOnly = false;
14970         String dumpPackage = null;
14971
14972         int opti = 0;
14973         while (opti < args.length) {
14974             String opt = args[opti];
14975             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14976                 break;
14977             }
14978             opti++;
14979             if ("-a".equals(opt)) {
14980                 dumpAll = true;
14981             } else if ("-c".equals(opt)) {
14982                 dumpClient = true;
14983             } else if ("-v".equals(opt)) {
14984                 dumpVisibleStacksOnly = true;
14985             } else if ("-f".equals(opt)) {
14986                 dumpFocusedStackOnly = true;
14987             } else if ("-p".equals(opt)) {
14988                 if (opti < args.length) {
14989                     dumpPackage = args[opti];
14990                     opti++;
14991                 } else {
14992                     pw.println("Error: -p option requires package argument");
14993                     return;
14994                 }
14995                 dumpClient = true;
14996             } else if ("--checkin".equals(opt)) {
14997                 dumpCheckin = dumpCheckinFormat = true;
14998             } else if ("-C".equals(opt)) {
14999                 dumpCheckinFormat = true;
15000             } else if ("-h".equals(opt)) {
15001                 ActivityManagerShellCommand.dumpHelp(pw, true);
15002                 return;
15003             } else {
15004                 pw.println("Unknown argument: " + opt + "; use -h for help");
15005             }
15006         }
15007
15008         long origId = Binder.clearCallingIdentity();
15009         boolean more = false;
15010         // Is the caller requesting to dump a particular piece of data?
15011         if (opti < args.length) {
15012             String cmd = args[opti];
15013             opti++;
15014             if ("activities".equals(cmd) || "a".equals(cmd)) {
15015                 synchronized (this) {
15016                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15017                 }
15018             } else if ("lastanr".equals(cmd)) {
15019                 synchronized (this) {
15020                     dumpLastANRLocked(pw);
15021                 }
15022             } else if ("starter".equals(cmd)) {
15023                 synchronized (this) {
15024                     dumpActivityStarterLocked(pw);
15025                 }
15026             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15027                 synchronized (this) {
15028                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15029                 }
15030             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15031                 String[] newArgs;
15032                 String name;
15033                 if (opti >= args.length) {
15034                     name = null;
15035                     newArgs = EMPTY_STRING_ARRAY;
15036                 } else {
15037                     dumpPackage = args[opti];
15038                     opti++;
15039                     newArgs = new String[args.length - opti];
15040                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15041                             args.length - opti);
15042                 }
15043                 synchronized (this) {
15044                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15045                 }
15046             } else if ("broadcast-stats".equals(cmd)) {
15047                 String[] newArgs;
15048                 String name;
15049                 if (opti >= args.length) {
15050                     name = null;
15051                     newArgs = EMPTY_STRING_ARRAY;
15052                 } else {
15053                     dumpPackage = args[opti];
15054                     opti++;
15055                     newArgs = new String[args.length - opti];
15056                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15057                             args.length - opti);
15058                 }
15059                 synchronized (this) {
15060                     if (dumpCheckinFormat) {
15061                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15062                                 dumpPackage);
15063                     } else {
15064                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15065                     }
15066                 }
15067             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15068                 String[] newArgs;
15069                 String name;
15070                 if (opti >= args.length) {
15071                     name = null;
15072                     newArgs = EMPTY_STRING_ARRAY;
15073                 } else {
15074                     dumpPackage = args[opti];
15075                     opti++;
15076                     newArgs = new String[args.length - opti];
15077                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15078                             args.length - opti);
15079                 }
15080                 synchronized (this) {
15081                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15082                 }
15083             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15084                 String[] newArgs;
15085                 String name;
15086                 if (opti >= args.length) {
15087                     name = null;
15088                     newArgs = EMPTY_STRING_ARRAY;
15089                 } else {
15090                     dumpPackage = args[opti];
15091                     opti++;
15092                     newArgs = new String[args.length - opti];
15093                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15094                             args.length - opti);
15095                 }
15096                 synchronized (this) {
15097                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15098                 }
15099             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15100                 synchronized (this) {
15101                     dumpOomLocked(fd, pw, args, opti, true);
15102                 }
15103             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15104                 synchronized (this) {
15105                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
15106                 }
15107             } else if ("provider".equals(cmd)) {
15108                 String[] newArgs;
15109                 String name;
15110                 if (opti >= args.length) {
15111                     name = null;
15112                     newArgs = EMPTY_STRING_ARRAY;
15113                 } else {
15114                     name = args[opti];
15115                     opti++;
15116                     newArgs = new String[args.length - opti];
15117                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15118                 }
15119                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15120                     pw.println("No providers match: " + name);
15121                     pw.println("Use -h for help.");
15122                 }
15123             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15124                 synchronized (this) {
15125                     dumpProvidersLocked(fd, pw, args, opti, true, null);
15126                 }
15127             } else if ("service".equals(cmd)) {
15128                 String[] newArgs;
15129                 String name;
15130                 if (opti >= args.length) {
15131                     name = null;
15132                     newArgs = EMPTY_STRING_ARRAY;
15133                 } else {
15134                     name = args[opti];
15135                     opti++;
15136                     newArgs = new String[args.length - opti];
15137                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15138                             args.length - opti);
15139                 }
15140                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15141                     pw.println("No services match: " + name);
15142                     pw.println("Use -h for help.");
15143                 }
15144             } else if ("package".equals(cmd)) {
15145                 String[] newArgs;
15146                 if (opti >= args.length) {
15147                     pw.println("package: no package name specified");
15148                     pw.println("Use -h for help.");
15149                 } else {
15150                     dumpPackage = args[opti];
15151                     opti++;
15152                     newArgs = new String[args.length - opti];
15153                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15154                             args.length - opti);
15155                     args = newArgs;
15156                     opti = 0;
15157                     more = true;
15158                 }
15159             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15160                 synchronized (this) {
15161                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15162                 }
15163             } else if ("settings".equals(cmd)) {
15164                 synchronized (this) {
15165                     mConstants.dump(pw);
15166                 }
15167             } else if ("services".equals(cmd) || "s".equals(cmd)) {
15168                 if (dumpClient) {
15169                     ActiveServices.ServiceDumper dumper;
15170                     synchronized (this) {
15171                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15172                                 dumpPackage);
15173                     }
15174                     dumper.dumpWithClient();
15175                 } else {
15176                     synchronized (this) {
15177                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15178                                 dumpPackage).dumpLocked();
15179                     }
15180                 }
15181             } else if ("locks".equals(cmd)) {
15182                 LockGuard.dump(fd, pw, args);
15183             } else {
15184                 // Dumping a single activity?
15185                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15186                         dumpFocusedStackOnly)) {
15187                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15188                     int res = shell.exec(this, null, fd, null, args, null,
15189                             new ResultReceiver(null));
15190                     if (res < 0) {
15191                         pw.println("Bad activity command, or no activities match: " + cmd);
15192                         pw.println("Use -h for help.");
15193                     }
15194                 }
15195             }
15196             if (!more) {
15197                 Binder.restoreCallingIdentity(origId);
15198                 return;
15199             }
15200         }
15201
15202         // No piece of data specified, dump everything.
15203         if (dumpCheckinFormat) {
15204             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15205         } else if (dumpClient) {
15206             ActiveServices.ServiceDumper sdumper;
15207             synchronized (this) {
15208                 mConstants.dump(pw);
15209                 pw.println();
15210                 if (dumpAll) {
15211                     pw.println("-------------------------------------------------------------------------------");
15212                 }
15213                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15214                 pw.println();
15215                 if (dumpAll) {
15216                     pw.println("-------------------------------------------------------------------------------");
15217                 }
15218                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15219                 pw.println();
15220                 if (dumpAll) {
15221                     pw.println("-------------------------------------------------------------------------------");
15222                 }
15223                 if (dumpAll || dumpPackage != null) {
15224                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15225                     pw.println();
15226                     if (dumpAll) {
15227                         pw.println("-------------------------------------------------------------------------------");
15228                     }
15229                 }
15230                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15231                 pw.println();
15232                 if (dumpAll) {
15233                     pw.println("-------------------------------------------------------------------------------");
15234                 }
15235                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15236                 pw.println();
15237                 if (dumpAll) {
15238                     pw.println("-------------------------------------------------------------------------------");
15239                 }
15240                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15241                         dumpPackage);
15242             }
15243             sdumper.dumpWithClient();
15244             pw.println();
15245             synchronized (this) {
15246                 if (dumpAll) {
15247                     pw.println("-------------------------------------------------------------------------------");
15248                 }
15249                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15250                 pw.println();
15251                 if (dumpAll) {
15252                     pw.println("-------------------------------------------------------------------------------");
15253                 }
15254                 dumpLastANRLocked(pw);
15255                 pw.println();
15256                 if (dumpAll) {
15257                     pw.println("-------------------------------------------------------------------------------");
15258                 }
15259                 dumpActivityStarterLocked(pw);
15260                 pw.println();
15261                 if (dumpAll) {
15262                     pw.println("-------------------------------------------------------------------------------");
15263                 }
15264                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15265                 if (mAssociations.size() > 0) {
15266                     pw.println();
15267                     if (dumpAll) {
15268                         pw.println("-------------------------------------------------------------------------------");
15269                     }
15270                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15271                 }
15272                 pw.println();
15273                 if (dumpAll) {
15274                     pw.println("-------------------------------------------------------------------------------");
15275                 }
15276                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15277             }
15278
15279         } else {
15280             synchronized (this) {
15281                 mConstants.dump(pw);
15282                 pw.println();
15283                 if (dumpAll) {
15284                     pw.println("-------------------------------------------------------------------------------");
15285                 }
15286                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15287                 pw.println();
15288                 if (dumpAll) {
15289                     pw.println("-------------------------------------------------------------------------------");
15290                 }
15291                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15292                 pw.println();
15293                 if (dumpAll) {
15294                     pw.println("-------------------------------------------------------------------------------");
15295                 }
15296                 if (dumpAll || dumpPackage != null) {
15297                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15298                     pw.println();
15299                     if (dumpAll) {
15300                         pw.println("-------------------------------------------------------------------------------");
15301                     }
15302                 }
15303                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15304                 pw.println();
15305                 if (dumpAll) {
15306                     pw.println("-------------------------------------------------------------------------------");
15307                 }
15308                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15309                 pw.println();
15310                 if (dumpAll) {
15311                     pw.println("-------------------------------------------------------------------------------");
15312                 }
15313                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15314                         .dumpLocked();
15315                 pw.println();
15316                 if (dumpAll) {
15317                     pw.println("-------------------------------------------------------------------------------");
15318                 }
15319                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15320                 pw.println();
15321                 if (dumpAll) {
15322                     pw.println("-------------------------------------------------------------------------------");
15323                 }
15324                 dumpLastANRLocked(pw);
15325                 pw.println();
15326                 if (dumpAll) {
15327                     pw.println("-------------------------------------------------------------------------------");
15328                 }
15329                 dumpActivityStarterLocked(pw);
15330                 pw.println();
15331                 if (dumpAll) {
15332                     pw.println("-------------------------------------------------------------------------------");
15333                 }
15334                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15335                 if (mAssociations.size() > 0) {
15336                     pw.println();
15337                     if (dumpAll) {
15338                         pw.println("-------------------------------------------------------------------------------");
15339                     }
15340                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15341                 }
15342                 pw.println();
15343                 if (dumpAll) {
15344                     pw.println("-------------------------------------------------------------------------------");
15345                 }
15346                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15347             }
15348         }
15349         Binder.restoreCallingIdentity(origId);
15350     }
15351
15352     private void dumpLastANRLocked(PrintWriter pw) {
15353         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
15354         if (mLastANRState == null) {
15355             pw.println("  <no ANR has occurred since boot>");
15356         } else {
15357             pw.println(mLastANRState);
15358         }
15359     }
15360
15361     private void dumpActivityStarterLocked(PrintWriter pw) {
15362         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)");
15363         mActivityStarter.dump(pw, "");
15364     }
15365
15366     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15367             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15368         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15369                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15370     }
15371
15372     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15373             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15374         pw.println(header);
15375
15376         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15377                 dumpPackage);
15378         boolean needSep = printedAnything;
15379
15380         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15381                 mStackSupervisor.getResumedActivityLocked(),
15382                 dumpPackage, needSep, "  ResumedActivity: ");
15383         if (printed) {
15384             printedAnything = true;
15385             needSep = false;
15386         }
15387
15388         if (dumpPackage == null) {
15389             if (needSep) {
15390                 pw.println();
15391             }
15392             printedAnything = true;
15393             mStackSupervisor.dump(pw, "  ");
15394         }
15395
15396         if (!printedAnything) {
15397             pw.println("  (nothing)");
15398         }
15399     }
15400
15401     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15402             int opti, boolean dumpAll, String dumpPackage) {
15403         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15404
15405         boolean printedAnything = false;
15406
15407         if (mRecentTasks != null && mRecentTasks.size() > 0) {
15408             boolean printedHeader = false;
15409
15410             final int N = mRecentTasks.size();
15411             for (int i=0; i<N; i++) {
15412                 TaskRecord tr = mRecentTasks.get(i);
15413                 if (dumpPackage != null) {
15414                     if (tr.realActivity == null ||
15415                             !dumpPackage.equals(tr.realActivity.getPackageName())) {
15416                         continue;
15417                     }
15418                 }
15419                 if (!printedHeader) {
15420                     pw.println("  Recent tasks:");
15421                     printedHeader = true;
15422                     printedAnything = true;
15423                 }
15424                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15425                         pw.println(tr);
15426                 if (dumpAll) {
15427                     mRecentTasks.get(i).dump(pw, "    ");
15428                 }
15429             }
15430         }
15431
15432         if (!printedAnything) {
15433             pw.println("  (nothing)");
15434         }
15435     }
15436
15437     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15438             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15439         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15440
15441         int dumpUid = 0;
15442         if (dumpPackage != null) {
15443             IPackageManager pm = AppGlobals.getPackageManager();
15444             try {
15445                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15446             } catch (RemoteException e) {
15447             }
15448         }
15449
15450         boolean printedAnything = false;
15451
15452         final long now = SystemClock.uptimeMillis();
15453
15454         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15455             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15456                     = mAssociations.valueAt(i1);
15457             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15458                 SparseArray<ArrayMap<String, Association>> sourceUids
15459                         = targetComponents.valueAt(i2);
15460                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15461                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15462                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15463                         Association ass = sourceProcesses.valueAt(i4);
15464                         if (dumpPackage != null) {
15465                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15466                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15467                                 continue;
15468                             }
15469                         }
15470                         printedAnything = true;
15471                         pw.print("  ");
15472                         pw.print(ass.mTargetProcess);
15473                         pw.print("/");
15474                         UserHandle.formatUid(pw, ass.mTargetUid);
15475                         pw.print(" <- ");
15476                         pw.print(ass.mSourceProcess);
15477                         pw.print("/");
15478                         UserHandle.formatUid(pw, ass.mSourceUid);
15479                         pw.println();
15480                         pw.print("    via ");
15481                         pw.print(ass.mTargetComponent.flattenToShortString());
15482                         pw.println();
15483                         pw.print("    ");
15484                         long dur = ass.mTime;
15485                         if (ass.mNesting > 0) {
15486                             dur += now - ass.mStartTime;
15487                         }
15488                         TimeUtils.formatDuration(dur, pw);
15489                         pw.print(" (");
15490                         pw.print(ass.mCount);
15491                         pw.print(" times)");
15492                         pw.print("  ");
15493                         for (int i=0; i<ass.mStateTimes.length; i++) {
15494                             long amt = ass.mStateTimes[i];
15495                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15496                                 amt += now - ass.mLastStateUptime;
15497                             }
15498                             if (amt != 0) {
15499                                 pw.print(" ");
15500                                 pw.print(ProcessList.makeProcStateString(
15501                                             i + ActivityManager.MIN_PROCESS_STATE));
15502                                 pw.print("=");
15503                                 TimeUtils.formatDuration(amt, pw);
15504                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15505                                     pw.print("*");
15506                                 }
15507                             }
15508                         }
15509                         pw.println();
15510                         if (ass.mNesting > 0) {
15511                             pw.print("    Currently active: ");
15512                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
15513                             pw.println();
15514                         }
15515                     }
15516                 }
15517             }
15518
15519         }
15520
15521         if (!printedAnything) {
15522             pw.println("  (nothing)");
15523         }
15524     }
15525
15526     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15527             String header, boolean needSep) {
15528         boolean printed = false;
15529         int whichAppId = -1;
15530         if (dumpPackage != null) {
15531             try {
15532                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15533                         dumpPackage, 0);
15534                 whichAppId = UserHandle.getAppId(info.uid);
15535             } catch (NameNotFoundException e) {
15536                 e.printStackTrace();
15537             }
15538         }
15539         for (int i=0; i<uids.size(); i++) {
15540             UidRecord uidRec = uids.valueAt(i);
15541             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15542                 continue;
15543             }
15544             if (!printed) {
15545                 printed = true;
15546                 if (needSep) {
15547                     pw.println();
15548                 }
15549                 pw.print("  ");
15550                 pw.println(header);
15551                 needSep = true;
15552             }
15553             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15554             pw.print(": "); pw.println(uidRec);
15555         }
15556         return printed;
15557     }
15558
15559     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15560             int opti, boolean dumpAll, String dumpPackage) {
15561         boolean needSep = false;
15562         boolean printedAnything = false;
15563         int numPers = 0;
15564
15565         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15566
15567         if (dumpAll) {
15568             final int NP = mProcessNames.getMap().size();
15569             for (int ip=0; ip<NP; ip++) {
15570                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15571                 final int NA = procs.size();
15572                 for (int ia=0; ia<NA; ia++) {
15573                     ProcessRecord r = procs.valueAt(ia);
15574                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15575                         continue;
15576                     }
15577                     if (!needSep) {
15578                         pw.println("  All known processes:");
15579                         needSep = true;
15580                         printedAnything = true;
15581                     }
15582                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15583                         pw.print(" UID "); pw.print(procs.keyAt(ia));
15584                         pw.print(" "); pw.println(r);
15585                     r.dump(pw, "    ");
15586                     if (r.persistent) {
15587                         numPers++;
15588                     }
15589                 }
15590             }
15591         }
15592
15593         if (mIsolatedProcesses.size() > 0) {
15594             boolean printed = false;
15595             for (int i=0; i<mIsolatedProcesses.size(); i++) {
15596                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15597                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15598                     continue;
15599                 }
15600                 if (!printed) {
15601                     if (needSep) {
15602                         pw.println();
15603                     }
15604                     pw.println("  Isolated process list (sorted by uid):");
15605                     printedAnything = true;
15606                     printed = true;
15607                     needSep = true;
15608                 }
15609                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15610                 pw.println(r);
15611             }
15612         }
15613
15614         if (mActiveInstrumentation.size() > 0) {
15615             boolean printed = false;
15616             for (int i=0; i<mActiveInstrumentation.size(); i++) {
15617                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15618                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15619                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15620                     continue;
15621                 }
15622                 if (!printed) {
15623                     if (needSep) {
15624                         pw.println();
15625                     }
15626                     pw.println("  Active instrumentation:");
15627                     printedAnything = true;
15628                     printed = true;
15629                     needSep = true;
15630                 }
15631                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15632                 pw.println(ai);
15633                 ai.dump(pw, "      ");
15634             }
15635         }
15636
15637         if (mActiveUids.size() > 0) {
15638             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15639                 printedAnything = needSep = true;
15640             }
15641         }
15642         if (dumpAll) {
15643             if (mValidateUids.size() > 0) {
15644                 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15645                     printedAnything = needSep = true;
15646                 }
15647             }
15648         }
15649
15650         if (mLruProcesses.size() > 0) {
15651             if (needSep) {
15652                 pw.println();
15653             }
15654             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15655                     pw.print(" total, non-act at ");
15656                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15657                     pw.print(", non-svc at ");
15658                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15659                     pw.println("):");
15660             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15661             needSep = true;
15662             printedAnything = true;
15663         }
15664
15665         if (dumpAll || dumpPackage != null) {
15666             synchronized (mPidsSelfLocked) {
15667                 boolean printed = false;
15668                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15669                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
15670                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15671                         continue;
15672                     }
15673                     if (!printed) {
15674                         if (needSep) pw.println();
15675                         needSep = true;
15676                         pw.println("  PID mappings:");
15677                         printed = true;
15678                         printedAnything = true;
15679                     }
15680                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15681                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15682                 }
15683             }
15684         }
15685
15686         if (mImportantProcesses.size() > 0) {
15687             synchronized (mPidsSelfLocked) {
15688                 boolean printed = false;
15689                 for (int i = 0; i< mImportantProcesses.size(); i++) {
15690                     ProcessRecord r = mPidsSelfLocked.get(
15691                             mImportantProcesses.valueAt(i).pid);
15692                     if (dumpPackage != null && (r == null
15693                             || !r.pkgList.containsKey(dumpPackage))) {
15694                         continue;
15695                     }
15696                     if (!printed) {
15697                         if (needSep) pw.println();
15698                         needSep = true;
15699                         pw.println("  Foreground Processes:");
15700                         printed = true;
15701                         printedAnything = true;
15702                     }
15703                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15704                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15705                 }
15706             }
15707         }
15708
15709         if (mPersistentStartingProcesses.size() > 0) {
15710             if (needSep) pw.println();
15711             needSep = true;
15712             printedAnything = true;
15713             pw.println("  Persisent processes that are starting:");
15714             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15715                     "Starting Norm", "Restarting PERS", dumpPackage);
15716         }
15717
15718         if (mRemovedProcesses.size() > 0) {
15719             if (needSep) pw.println();
15720             needSep = true;
15721             printedAnything = true;
15722             pw.println("  Processes that are being removed:");
15723             dumpProcessList(pw, this, mRemovedProcesses, "    ",
15724                     "Removed Norm", "Removed PERS", dumpPackage);
15725         }
15726
15727         if (mProcessesOnHold.size() > 0) {
15728             if (needSep) pw.println();
15729             needSep = true;
15730             printedAnything = true;
15731             pw.println("  Processes that are on old until the system is ready:");
15732             dumpProcessList(pw, this, mProcessesOnHold, "    ",
15733                     "OnHold Norm", "OnHold PERS", dumpPackage);
15734         }
15735
15736         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15737
15738         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15739         if (needSep) {
15740             printedAnything = true;
15741         }
15742
15743         if (dumpPackage == null) {
15744             pw.println();
15745             needSep = false;
15746             mUserController.dump(pw, dumpAll);
15747         }
15748         if (mHomeProcess != null && (dumpPackage == null
15749                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15750             if (needSep) {
15751                 pw.println();
15752                 needSep = false;
15753             }
15754             pw.println("  mHomeProcess: " + mHomeProcess);
15755         }
15756         if (mPreviousProcess != null && (dumpPackage == null
15757                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15758             if (needSep) {
15759                 pw.println();
15760                 needSep = false;
15761             }
15762             pw.println("  mPreviousProcess: " + mPreviousProcess);
15763         }
15764         if (dumpAll) {
15765             StringBuilder sb = new StringBuilder(128);
15766             sb.append("  mPreviousProcessVisibleTime: ");
15767             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15768             pw.println(sb);
15769         }
15770         if (mHeavyWeightProcess != null && (dumpPackage == null
15771                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15772             if (needSep) {
15773                 pw.println();
15774                 needSep = false;
15775             }
15776             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15777         }
15778         if (dumpPackage == null) {
15779             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15780             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15781         }
15782         if (dumpAll) {
15783             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15784             if (mCompatModePackages.getPackages().size() > 0) {
15785                 boolean printed = false;
15786                 for (Map.Entry<String, Integer> entry
15787                         : mCompatModePackages.getPackages().entrySet()) {
15788                     String pkg = entry.getKey();
15789                     int mode = entry.getValue();
15790                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15791                         continue;
15792                     }
15793                     if (!printed) {
15794                         pw.println("  mScreenCompatPackages:");
15795                         printed = true;
15796                     }
15797                     pw.print("    "); pw.print(pkg); pw.print(": ");
15798                             pw.print(mode); pw.println();
15799                 }
15800             }
15801             final int NI = mUidObservers.getRegisteredCallbackCount();
15802             boolean printed = false;
15803             for (int i=0; i<NI; i++) {
15804                 final UidObserverRegistration reg = (UidObserverRegistration)
15805                         mUidObservers.getRegisteredCallbackCookie(i);
15806                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15807                     if (!printed) {
15808                         pw.println("  mUidObservers:");
15809                         printed = true;
15810                     }
15811                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15812                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
15813                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15814                         pw.print(" IDLE");
15815                     }
15816                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15817                         pw.print(" ACT" );
15818                     }
15819                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15820                         pw.print(" GONE");
15821                     }
15822                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15823                         pw.print(" STATE");
15824                         pw.print(" (cut="); pw.print(reg.cutpoint);
15825                         pw.print(")");
15826                     }
15827                     pw.println();
15828                     if (reg.lastProcStates != null) {
15829                         final int NJ = reg.lastProcStates.size();
15830                         for (int j=0; j<NJ; j++) {
15831                             pw.print("      Last ");
15832                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15833                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15834                         }
15835                     }
15836                 }
15837             }
15838             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15839             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15840             if (mPendingTempWhitelist.size() > 0) {
15841                 pw.println("  mPendingTempWhitelist:");
15842                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15843                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15844                     pw.print("    ");
15845                     UserHandle.formatUid(pw, ptw.targetUid);
15846                     pw.print(": ");
15847                     TimeUtils.formatDuration(ptw.duration, pw);
15848                     pw.print(" ");
15849                     pw.println(ptw.tag);
15850                 }
15851             }
15852         }
15853         if (dumpPackage == null) {
15854             pw.println("  mWakefulness="
15855                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
15856             pw.println("  mSleepTokens=" + mSleepTokens);
15857             pw.println("  mSleeping=" + mSleeping);
15858             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15859             if (mRunningVoice != null) {
15860                 pw.println("  mRunningVoice=" + mRunningVoice);
15861                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15862             }
15863         }
15864         pw.println("  mVrController=" + mVrController);
15865         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15866                 || mOrigWaitForDebugger) {
15867             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15868                     || dumpPackage.equals(mOrigDebugApp)) {
15869                 if (needSep) {
15870                     pw.println();
15871                     needSep = false;
15872                 }
15873                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15874                         + " mDebugTransient=" + mDebugTransient
15875                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15876             }
15877         }
15878         if (mCurAppTimeTracker != null) {
15879             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15880         }
15881         if (mMemWatchProcesses.getMap().size() > 0) {
15882             pw.println("  Mem watch processes:");
15883             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15884                     = mMemWatchProcesses.getMap();
15885             for (int i=0; i<procs.size(); i++) {
15886                 final String proc = procs.keyAt(i);
15887                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15888                 for (int j=0; j<uids.size(); j++) {
15889                     if (needSep) {
15890                         pw.println();
15891                         needSep = false;
15892                     }
15893                     StringBuilder sb = new StringBuilder();
15894                     sb.append("    ").append(proc).append('/');
15895                     UserHandle.formatUid(sb, uids.keyAt(j));
15896                     Pair<Long, String> val = uids.valueAt(j);
15897                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15898                     if (val.second != null) {
15899                         sb.append(", report to ").append(val.second);
15900                     }
15901                     pw.println(sb.toString());
15902                 }
15903             }
15904             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15905             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15906             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15907                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15908         }
15909         if (mTrackAllocationApp != null) {
15910             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15911                 if (needSep) {
15912                     pw.println();
15913                     needSep = false;
15914                 }
15915                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15916             }
15917         }
15918         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15919                 || mProfileFd != null) {
15920             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15921                 if (needSep) {
15922                     pw.println();
15923                     needSep = false;
15924                 }
15925                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15926                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15927                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15928                         + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15929                 pw.println("  mProfileType=" + mProfileType);
15930             }
15931         }
15932         if (mNativeDebuggingApp != null) {
15933             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15934                 if (needSep) {
15935                     pw.println();
15936                     needSep = false;
15937                 }
15938                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15939             }
15940         }
15941         if (dumpPackage == null) {
15942             if (mAlwaysFinishActivities) {
15943                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15944             }
15945             if (mController != null) {
15946                 pw.println("  mController=" + mController
15947                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15948             }
15949             if (dumpAll) {
15950                 pw.println("  Total persistent processes: " + numPers);
15951                 pw.println("  mProcessesReady=" + mProcessesReady
15952                         + " mSystemReady=" + mSystemReady
15953                         + " mBooted=" + mBooted
15954                         + " mFactoryTest=" + mFactoryTest);
15955                 pw.println("  mBooting=" + mBooting
15956                         + " mCallFinishBooting=" + mCallFinishBooting
15957                         + " mBootAnimationComplete=" + mBootAnimationComplete);
15958                 pw.print("  mLastPowerCheckRealtime=");
15959                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15960                         pw.println("");
15961                 pw.print("  mLastPowerCheckUptime=");
15962                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15963                         pw.println("");
15964                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15965                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15966                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15967                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15968                         + " (" + mLruProcesses.size() + " total)"
15969                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15970                         + " mNumServiceProcs=" + mNumServiceProcs
15971                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15972                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15973                         + " mLastMemoryLevel=" + mLastMemoryLevel
15974                         + " mLastNumProcesses=" + mLastNumProcesses);
15975                 long now = SystemClock.uptimeMillis();
15976                 pw.print("  mLastIdleTime=");
15977                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
15978                         pw.print(" mLowRamSinceLastIdle=");
15979                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15980                         pw.println();
15981             }
15982         }
15983
15984         if (!printedAnything) {
15985             pw.println("  (nothing)");
15986         }
15987     }
15988
15989     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15990             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15991         if (mProcessesToGc.size() > 0) {
15992             boolean printed = false;
15993             long now = SystemClock.uptimeMillis();
15994             for (int i=0; i<mProcessesToGc.size(); i++) {
15995                 ProcessRecord proc = mProcessesToGc.get(i);
15996                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15997                     continue;
15998                 }
15999                 if (!printed) {
16000                     if (needSep) pw.println();
16001                     needSep = true;
16002                     pw.println("  Processes that are waiting to GC:");
16003                     printed = true;
16004                 }
16005                 pw.print("    Process "); pw.println(proc);
16006                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16007                         pw.print(", last gced=");
16008                         pw.print(now-proc.lastRequestedGc);
16009                         pw.print(" ms ago, last lowMem=");
16010                         pw.print(now-proc.lastLowMemory);
16011                         pw.println(" ms ago");
16012
16013             }
16014         }
16015         return needSep;
16016     }
16017
16018     void printOomLevel(PrintWriter pw, String name, int adj) {
16019         pw.print("    ");
16020         if (adj >= 0) {
16021             pw.print(' ');
16022             if (adj < 10) pw.print(' ');
16023         } else {
16024             if (adj > -10) pw.print(' ');
16025         }
16026         pw.print(adj);
16027         pw.print(": ");
16028         pw.print(name);
16029         pw.print(" (");
16030         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16031         pw.println(")");
16032     }
16033
16034     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16035             int opti, boolean dumpAll) {
16036         boolean needSep = false;
16037
16038         if (mLruProcesses.size() > 0) {
16039             if (needSep) pw.println();
16040             needSep = true;
16041             pw.println("  OOM levels:");
16042             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16043             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16044             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16045             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16046             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16047             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16048             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16049             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16050             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16051             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16052             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16053             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16054             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16055             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16056
16057             if (needSep) pw.println();
16058             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16059                     pw.print(" total, non-act at ");
16060                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16061                     pw.print(", non-svc at ");
16062                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16063                     pw.println("):");
16064             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16065             needSep = true;
16066         }
16067
16068         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16069
16070         pw.println();
16071         pw.println("  mHomeProcess: " + mHomeProcess);
16072         pw.println("  mPreviousProcess: " + mPreviousProcess);
16073         if (mHeavyWeightProcess != null) {
16074             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16075         }
16076
16077         return true;
16078     }
16079
16080     /**
16081      * There are three ways to call this:
16082      *  - no provider specified: dump all the providers
16083      *  - a flattened component name that matched an existing provider was specified as the
16084      *    first arg: dump that one provider
16085      *  - the first arg isn't the flattened component name of an existing provider:
16086      *    dump all providers whose component contains the first arg as a substring
16087      */
16088     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16089             int opti, boolean dumpAll) {
16090         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16091     }
16092
16093     static class ItemMatcher {
16094         ArrayList<ComponentName> components;
16095         ArrayList<String> strings;
16096         ArrayList<Integer> objects;
16097         boolean all;
16098
16099         ItemMatcher() {
16100             all = true;
16101         }
16102
16103         void build(String name) {
16104             ComponentName componentName = ComponentName.unflattenFromString(name);
16105             if (componentName != null) {
16106                 if (components == null) {
16107                     components = new ArrayList<ComponentName>();
16108                 }
16109                 components.add(componentName);
16110                 all = false;
16111             } else {
16112                 int objectId = 0;
16113                 // Not a '/' separated full component name; maybe an object ID?
16114                 try {
16115                     objectId = Integer.parseInt(name, 16);
16116                     if (objects == null) {
16117                         objects = new ArrayList<Integer>();
16118                     }
16119                     objects.add(objectId);
16120                     all = false;
16121                 } catch (RuntimeException e) {
16122                     // Not an integer; just do string match.
16123                     if (strings == null) {
16124                         strings = new ArrayList<String>();
16125                     }
16126                     strings.add(name);
16127                     all = false;
16128                 }
16129             }
16130         }
16131
16132         int build(String[] args, int opti) {
16133             for (; opti<args.length; opti++) {
16134                 String name = args[opti];
16135                 if ("--".equals(name)) {
16136                     return opti+1;
16137                 }
16138                 build(name);
16139             }
16140             return opti;
16141         }
16142
16143         boolean match(Object object, ComponentName comp) {
16144             if (all) {
16145                 return true;
16146             }
16147             if (components != null) {
16148                 for (int i=0; i<components.size(); i++) {
16149                     if (components.get(i).equals(comp)) {
16150                         return true;
16151                     }
16152                 }
16153             }
16154             if (objects != null) {
16155                 for (int i=0; i<objects.size(); i++) {
16156                     if (System.identityHashCode(object) == objects.get(i)) {
16157                         return true;
16158                     }
16159                 }
16160             }
16161             if (strings != null) {
16162                 String flat = comp.flattenToString();
16163                 for (int i=0; i<strings.size(); i++) {
16164                     if (flat.contains(strings.get(i))) {
16165                         return true;
16166                     }
16167                 }
16168             }
16169             return false;
16170         }
16171     }
16172
16173     /**
16174      * There are three things that cmd can be:
16175      *  - a flattened component name that matches an existing activity
16176      *  - the cmd arg isn't the flattened component name of an existing activity:
16177      *    dump all activity whose component contains the cmd as a substring
16178      *  - A hex number of the ActivityRecord object instance.
16179      *
16180      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16181      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16182      */
16183     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16184             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16185         ArrayList<ActivityRecord> activities;
16186
16187         synchronized (this) {
16188             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16189                     dumpFocusedStackOnly);
16190         }
16191
16192         if (activities.size() <= 0) {
16193             return false;
16194         }
16195
16196         String[] newArgs = new String[args.length - opti];
16197         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16198
16199         TaskRecord lastTask = null;
16200         boolean needSep = false;
16201         for (int i=activities.size()-1; i>=0; i--) {
16202             ActivityRecord r = activities.get(i);
16203             if (needSep) {
16204                 pw.println();
16205             }
16206             needSep = true;
16207             synchronized (this) {
16208                 final TaskRecord task = r.getTask();
16209                 if (lastTask != task) {
16210                     lastTask = task;
16211                     pw.print("TASK "); pw.print(lastTask.affinity);
16212                             pw.print(" id="); pw.print(lastTask.taskId);
16213                             pw.print(" userId="); pw.println(lastTask.userId);
16214                     if (dumpAll) {
16215                         lastTask.dump(pw, "  ");
16216                     }
16217                 }
16218             }
16219             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16220         }
16221         return true;
16222     }
16223
16224     /**
16225      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16226      * there is a thread associated with the activity.
16227      */
16228     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16229             final ActivityRecord r, String[] args, boolean dumpAll) {
16230         String innerPrefix = prefix + "  ";
16231         synchronized (this) {
16232             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16233                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16234                     pw.print(" pid=");
16235                     if (r.app != null) pw.println(r.app.pid);
16236                     else pw.println("(not running)");
16237             if (dumpAll) {
16238                 r.dump(pw, innerPrefix);
16239             }
16240         }
16241         if (r.app != null && r.app.thread != null) {
16242             // flush anything that is already in the PrintWriter since the thread is going
16243             // to write to the file descriptor directly
16244             pw.flush();
16245             try {
16246                 TransferPipe tp = new TransferPipe();
16247                 try {
16248                     r.app.thread.dumpActivity(tp.getWriteFd(),
16249                             r.appToken, innerPrefix, args);
16250                     tp.go(fd);
16251                 } finally {
16252                     tp.kill();
16253                 }
16254             } catch (IOException e) {
16255                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16256             } catch (RemoteException e) {
16257                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16258             }
16259         }
16260     }
16261
16262     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16263             int opti, boolean dumpAll, String dumpPackage) {
16264         boolean needSep = false;
16265         boolean onlyHistory = false;
16266         boolean printedAnything = false;
16267
16268         if ("history".equals(dumpPackage)) {
16269             if (opti < args.length && "-s".equals(args[opti])) {
16270                 dumpAll = false;
16271             }
16272             onlyHistory = true;
16273             dumpPackage = null;
16274         }
16275
16276         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16277         if (!onlyHistory && dumpAll) {
16278             if (mRegisteredReceivers.size() > 0) {
16279                 boolean printed = false;
16280                 Iterator it = mRegisteredReceivers.values().iterator();
16281                 while (it.hasNext()) {
16282                     ReceiverList r = (ReceiverList)it.next();
16283                     if (dumpPackage != null && (r.app == null ||
16284                             !dumpPackage.equals(r.app.info.packageName))) {
16285                         continue;
16286                     }
16287                     if (!printed) {
16288                         pw.println("  Registered Receivers:");
16289                         needSep = true;
16290                         printed = true;
16291                         printedAnything = true;
16292                     }
16293                     pw.print("  * "); pw.println(r);
16294                     r.dump(pw, "    ");
16295                 }
16296             }
16297
16298             if (mReceiverResolver.dump(pw, needSep ?
16299                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16300                     "    ", dumpPackage, false, false)) {
16301                 needSep = true;
16302                 printedAnything = true;
16303             }
16304         }
16305
16306         for (BroadcastQueue q : mBroadcastQueues) {
16307             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16308             printedAnything |= needSep;
16309         }
16310
16311         needSep = true;
16312
16313         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16314             for (int user=0; user<mStickyBroadcasts.size(); user++) {
16315                 if (needSep) {
16316                     pw.println();
16317                 }
16318                 needSep = true;
16319                 printedAnything = true;
16320                 pw.print("  Sticky broadcasts for user ");
16321                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16322                 StringBuilder sb = new StringBuilder(128);
16323                 for (Map.Entry<String, ArrayList<Intent>> ent
16324                         : mStickyBroadcasts.valueAt(user).entrySet()) {
16325                     pw.print("  * Sticky action "); pw.print(ent.getKey());
16326                     if (dumpAll) {
16327                         pw.println(":");
16328                         ArrayList<Intent> intents = ent.getValue();
16329                         final int N = intents.size();
16330                         for (int i=0; i<N; i++) {
16331                             sb.setLength(0);
16332                             sb.append("    Intent: ");
16333                             intents.get(i).toShortString(sb, false, true, false, false);
16334                             pw.println(sb.toString());
16335                             Bundle bundle = intents.get(i).getExtras();
16336                             if (bundle != null) {
16337                                 pw.print("      ");
16338                                 pw.println(bundle.toString());
16339                             }
16340                         }
16341                     } else {
16342                         pw.println("");
16343                     }
16344                 }
16345             }
16346         }
16347
16348         if (!onlyHistory && dumpAll) {
16349             pw.println();
16350             for (BroadcastQueue queue : mBroadcastQueues) {
16351                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16352                         + queue.mBroadcastsScheduled);
16353             }
16354             pw.println("  mHandler:");
16355             mHandler.dump(new PrintWriterPrinter(pw), "    ");
16356             needSep = true;
16357             printedAnything = true;
16358         }
16359
16360         if (!printedAnything) {
16361             pw.println("  (nothing)");
16362         }
16363     }
16364
16365     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16366             int opti, boolean dumpAll, String dumpPackage) {
16367         if (mCurBroadcastStats == null) {
16368             return;
16369         }
16370
16371         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16372         final long now = SystemClock.elapsedRealtime();
16373         if (mLastBroadcastStats != null) {
16374             pw.print("  Last stats (from ");
16375             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16376             pw.print(" to ");
16377             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16378             pw.print(", ");
16379             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16380                     - mLastBroadcastStats.mStartUptime, pw);
16381             pw.println(" uptime):");
16382             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16383                 pw.println("    (nothing)");
16384             }
16385             pw.println();
16386         }
16387         pw.print("  Current stats (from ");
16388         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16389         pw.print(" to now, ");
16390         TimeUtils.formatDuration(SystemClock.uptimeMillis()
16391                 - mCurBroadcastStats.mStartUptime, pw);
16392         pw.println(" uptime):");
16393         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16394             pw.println("    (nothing)");
16395         }
16396     }
16397
16398     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16399             int opti, boolean fullCheckin, String dumpPackage) {
16400         if (mCurBroadcastStats == null) {
16401             return;
16402         }
16403
16404         if (mLastBroadcastStats != null) {
16405             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16406             if (fullCheckin) {
16407                 mLastBroadcastStats = null;
16408                 return;
16409             }
16410         }
16411         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16412         if (fullCheckin) {
16413             mCurBroadcastStats = null;
16414         }
16415     }
16416
16417     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16418             int opti, boolean dumpAll, String dumpPackage) {
16419         boolean needSep;
16420         boolean printedAnything = false;
16421
16422         ItemMatcher matcher = new ItemMatcher();
16423         matcher.build(args, opti);
16424
16425         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16426
16427         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16428         printedAnything |= needSep;
16429
16430         if (mLaunchingProviders.size() > 0) {
16431             boolean printed = false;
16432             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16433                 ContentProviderRecord r = mLaunchingProviders.get(i);
16434                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16435                     continue;
16436                 }
16437                 if (!printed) {
16438                     if (needSep) pw.println();
16439                     needSep = true;
16440                     pw.println("  Launching content providers:");
16441                     printed = true;
16442                     printedAnything = true;
16443                 }
16444                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
16445                         pw.println(r);
16446             }
16447         }
16448
16449         if (!printedAnything) {
16450             pw.println("  (nothing)");
16451         }
16452     }
16453
16454     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16455             int opti, boolean dumpAll, String dumpPackage) {
16456         boolean needSep = false;
16457         boolean printedAnything = false;
16458
16459         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16460
16461         if (mGrantedUriPermissions.size() > 0) {
16462             boolean printed = false;
16463             int dumpUid = -2;
16464             if (dumpPackage != null) {
16465                 try {
16466                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16467                             MATCH_ANY_USER, 0);
16468                 } catch (NameNotFoundException e) {
16469                     dumpUid = -1;
16470                 }
16471             }
16472             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16473                 int uid = mGrantedUriPermissions.keyAt(i);
16474                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16475                     continue;
16476                 }
16477                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16478                 if (!printed) {
16479                     if (needSep) pw.println();
16480                     needSep = true;
16481                     pw.println("  Granted Uri Permissions:");
16482                     printed = true;
16483                     printedAnything = true;
16484                 }
16485                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16486                 for (UriPermission perm : perms.values()) {
16487                     pw.print("    "); pw.println(perm);
16488                     if (dumpAll) {
16489                         perm.dump(pw, "      ");
16490                     }
16491                 }
16492             }
16493         }
16494
16495         if (!printedAnything) {
16496             pw.println("  (nothing)");
16497         }
16498     }
16499
16500     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16501             int opti, boolean dumpAll, String dumpPackage) {
16502         boolean printed = false;
16503
16504         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16505
16506         if (mIntentSenderRecords.size() > 0) {
16507             // Organize these by package name, so they are easier to read.
16508             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16509             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16510             final Iterator<WeakReference<PendingIntentRecord>> it
16511                     = mIntentSenderRecords.values().iterator();
16512             while (it.hasNext()) {
16513                 WeakReference<PendingIntentRecord> ref = it.next();
16514                 PendingIntentRecord rec = ref != null ? ref.get() : null;
16515                 if (rec == null) {
16516                     weakRefs.add(ref);
16517                     continue;
16518                 }
16519                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16520                     continue;
16521                 }
16522                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16523                 if (list == null) {
16524                     list = new ArrayList<>();
16525                     byPackage.put(rec.key.packageName, list);
16526                 }
16527                 list.add(rec);
16528             }
16529             for (int i = 0; i < byPackage.size(); i++) {
16530                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16531                 printed = true;
16532                 pw.print("  * "); pw.print(byPackage.keyAt(i));
16533                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16534                 for (int j = 0; j < intents.size(); j++) {
16535                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16536                     if (dumpAll) {
16537                         intents.get(j).dump(pw, "      ");
16538                     }
16539                 }
16540             }
16541             if (weakRefs.size() > 0) {
16542                 printed = true;
16543                 pw.println("  * WEAK REFS:");
16544                 for (int i = 0; i < weakRefs.size(); i++) {
16545                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16546                 }
16547             }
16548         }
16549
16550         if (!printed) {
16551             pw.println("  (nothing)");
16552         }
16553     }
16554
16555     private static final int dumpProcessList(PrintWriter pw,
16556             ActivityManagerService service, List list,
16557             String prefix, String normalLabel, String persistentLabel,
16558             String dumpPackage) {
16559         int numPers = 0;
16560         final int N = list.size()-1;
16561         for (int i=N; i>=0; i--) {
16562             ProcessRecord r = (ProcessRecord)list.get(i);
16563             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16564                 continue;
16565             }
16566             pw.println(String.format("%s%s #%2d: %s",
16567                     prefix, (r.persistent ? persistentLabel : normalLabel),
16568                     i, r.toString()));
16569             if (r.persistent) {
16570                 numPers++;
16571             }
16572         }
16573         return numPers;
16574     }
16575
16576     private static final boolean dumpProcessOomList(PrintWriter pw,
16577             ActivityManagerService service, List<ProcessRecord> origList,
16578             String prefix, String normalLabel, String persistentLabel,
16579             boolean inclDetails, String dumpPackage) {
16580
16581         ArrayList<Pair<ProcessRecord, Integer>> list
16582                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16583         for (int i=0; i<origList.size(); i++) {
16584             ProcessRecord r = origList.get(i);
16585             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16586                 continue;
16587             }
16588             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16589         }
16590
16591         if (list.size() <= 0) {
16592             return false;
16593         }
16594
16595         Comparator<Pair<ProcessRecord, Integer>> comparator
16596                 = new Comparator<Pair<ProcessRecord, Integer>>() {
16597             @Override
16598             public int compare(Pair<ProcessRecord, Integer> object1,
16599                     Pair<ProcessRecord, Integer> object2) {
16600                 if (object1.first.setAdj != object2.first.setAdj) {
16601                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16602                 }
16603                 if (object1.first.setProcState != object2.first.setProcState) {
16604                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16605                 }
16606                 if (object1.second.intValue() != object2.second.intValue()) {
16607                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16608                 }
16609                 return 0;
16610             }
16611         };
16612
16613         Collections.sort(list, comparator);
16614
16615         final long curRealtime = SystemClock.elapsedRealtime();
16616         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16617         final long curUptime = SystemClock.uptimeMillis();
16618         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16619
16620         for (int i=list.size()-1; i>=0; i--) {
16621             ProcessRecord r = list.get(i).first;
16622             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16623             char schedGroup;
16624             switch (r.setSchedGroup) {
16625                 case ProcessList.SCHED_GROUP_BACKGROUND:
16626                     schedGroup = 'B';
16627                     break;
16628                 case ProcessList.SCHED_GROUP_DEFAULT:
16629                     schedGroup = 'F';
16630                     break;
16631                 case ProcessList.SCHED_GROUP_TOP_APP:
16632                     schedGroup = 'T';
16633                     break;
16634                 default:
16635                     schedGroup = '?';
16636                     break;
16637             }
16638             char foreground;
16639             if (r.foregroundActivities) {
16640                 foreground = 'A';
16641             } else if (r.foregroundServices) {
16642                 foreground = 'S';
16643             } else {
16644                 foreground = ' ';
16645             }
16646             String procState = ProcessList.makeProcStateString(r.curProcState);
16647             pw.print(prefix);
16648             pw.print(r.persistent ? persistentLabel : normalLabel);
16649             pw.print(" #");
16650             int num = (origList.size()-1)-list.get(i).second;
16651             if (num < 10) pw.print(' ');
16652             pw.print(num);
16653             pw.print(": ");
16654             pw.print(oomAdj);
16655             pw.print(' ');
16656             pw.print(schedGroup);
16657             pw.print('/');
16658             pw.print(foreground);
16659             pw.print('/');
16660             pw.print(procState);
16661             pw.print(" trm:");
16662             if (r.trimMemoryLevel < 10) pw.print(' ');
16663             pw.print(r.trimMemoryLevel);
16664             pw.print(' ');
16665             pw.print(r.toShortString());
16666             pw.print(" (");
16667             pw.print(r.adjType);
16668             pw.println(')');
16669             if (r.adjSource != null || r.adjTarget != null) {
16670                 pw.print(prefix);
16671                 pw.print("    ");
16672                 if (r.adjTarget instanceof ComponentName) {
16673                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16674                 } else if (r.adjTarget != null) {
16675                     pw.print(r.adjTarget.toString());
16676                 } else {
16677                     pw.print("{null}");
16678                 }
16679                 pw.print("<=");
16680                 if (r.adjSource instanceof ProcessRecord) {
16681                     pw.print("Proc{");
16682                     pw.print(((ProcessRecord)r.adjSource).toShortString());
16683                     pw.println("}");
16684                 } else if (r.adjSource != null) {
16685                     pw.println(r.adjSource.toString());
16686                 } else {
16687                     pw.println("{null}");
16688                 }
16689             }
16690             if (inclDetails) {
16691                 pw.print(prefix);
16692                 pw.print("    ");
16693                 pw.print("oom: max="); pw.print(r.maxAdj);
16694                 pw.print(" curRaw="); pw.print(r.curRawAdj);
16695                 pw.print(" setRaw="); pw.print(r.setRawAdj);
16696                 pw.print(" cur="); pw.print(r.curAdj);
16697                 pw.print(" set="); pw.println(r.setAdj);
16698                 pw.print(prefix);
16699                 pw.print("    ");
16700                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16701                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16702                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16703                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16704                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16705                 pw.println();
16706                 pw.print(prefix);
16707                 pw.print("    ");
16708                 pw.print("cached="); pw.print(r.cached);
16709                 pw.print(" empty="); pw.print(r.empty);
16710                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16711
16712                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16713                     if (r.lastWakeTime != 0) {
16714                         long wtime;
16715                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16716                         synchronized (stats) {
16717                             wtime = stats.getProcessWakeTime(r.info.uid,
16718                                     r.pid, curRealtime);
16719                         }
16720                         long timeUsed = wtime - r.lastWakeTime;
16721                         pw.print(prefix);
16722                         pw.print("    ");
16723                         pw.print("keep awake over ");
16724                         TimeUtils.formatDuration(realtimeSince, pw);
16725                         pw.print(" used ");
16726                         TimeUtils.formatDuration(timeUsed, pw);
16727                         pw.print(" (");
16728                         pw.print((timeUsed*100)/realtimeSince);
16729                         pw.println("%)");
16730                     }
16731                     if (r.lastCpuTime != 0) {
16732                         long timeUsed = r.curCpuTime - r.lastCpuTime;
16733                         pw.print(prefix);
16734                         pw.print("    ");
16735                         pw.print("run cpu over ");
16736                         TimeUtils.formatDuration(uptimeSince, pw);
16737                         pw.print(" used ");
16738                         TimeUtils.formatDuration(timeUsed, pw);
16739                         pw.print(" (");
16740                         pw.print((timeUsed*100)/uptimeSince);
16741                         pw.println("%)");
16742                     }
16743                 }
16744             }
16745         }
16746         return true;
16747     }
16748
16749     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16750             String[] args) {
16751         ArrayList<ProcessRecord> procs;
16752         synchronized (this) {
16753             if (args != null && args.length > start
16754                     && args[start].charAt(0) != '-') {
16755                 procs = new ArrayList<ProcessRecord>();
16756                 int pid = -1;
16757                 try {
16758                     pid = Integer.parseInt(args[start]);
16759                 } catch (NumberFormatException e) {
16760                 }
16761                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16762                     ProcessRecord proc = mLruProcesses.get(i);
16763                     if (proc.pid == pid) {
16764                         procs.add(proc);
16765                     } else if (allPkgs && proc.pkgList != null
16766                             && proc.pkgList.containsKey(args[start])) {
16767                         procs.add(proc);
16768                     } else if (proc.processName.equals(args[start])) {
16769                         procs.add(proc);
16770                     }
16771                 }
16772                 if (procs.size() <= 0) {
16773                     return null;
16774                 }
16775             } else {
16776                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16777             }
16778         }
16779         return procs;
16780     }
16781
16782     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16783             PrintWriter pw, String[] args) {
16784         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16785         if (procs == null) {
16786             pw.println("No process found for: " + args[0]);
16787             return;
16788         }
16789
16790         long uptime = SystemClock.uptimeMillis();
16791         long realtime = SystemClock.elapsedRealtime();
16792         pw.println("Applications Graphics Acceleration Info:");
16793         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16794
16795         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16796             ProcessRecord r = procs.get(i);
16797             if (r.thread != null) {
16798                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16799                 pw.flush();
16800                 try {
16801                     TransferPipe tp = new TransferPipe();
16802                     try {
16803                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16804                         tp.go(fd);
16805                     } finally {
16806                         tp.kill();
16807                     }
16808                 } catch (IOException e) {
16809                     pw.println("Failure while dumping the app: " + r);
16810                     pw.flush();
16811                 } catch (RemoteException e) {
16812                     pw.println("Got a RemoteException while dumping the app " + r);
16813                     pw.flush();
16814                 }
16815             }
16816         }
16817     }
16818
16819     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16820         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16821         if (procs == null) {
16822             pw.println("No process found for: " + args[0]);
16823             return;
16824         }
16825
16826         pw.println("Applications Database Info:");
16827
16828         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16829             ProcessRecord r = procs.get(i);
16830             if (r.thread != null) {
16831                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16832                 pw.flush();
16833                 try {
16834                     TransferPipe tp = new TransferPipe();
16835                     try {
16836                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
16837                         tp.go(fd);
16838                     } finally {
16839                         tp.kill();
16840                     }
16841                 } catch (IOException e) {
16842                     pw.println("Failure while dumping the app: " + r);
16843                     pw.flush();
16844                 } catch (RemoteException e) {
16845                     pw.println("Got a RemoteException while dumping the app " + r);
16846                     pw.flush();
16847                 }
16848             }
16849         }
16850     }
16851
16852     final static class MemItem {
16853         final boolean isProc;
16854         final String label;
16855         final String shortLabel;
16856         final long pss;
16857         final long swapPss;
16858         final int id;
16859         final boolean hasActivities;
16860         ArrayList<MemItem> subitems;
16861
16862         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16863                 boolean _hasActivities) {
16864             isProc = true;
16865             label = _label;
16866             shortLabel = _shortLabel;
16867             pss = _pss;
16868             swapPss = _swapPss;
16869             id = _id;
16870             hasActivities = _hasActivities;
16871         }
16872
16873         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16874             isProc = false;
16875             label = _label;
16876             shortLabel = _shortLabel;
16877             pss = _pss;
16878             swapPss = _swapPss;
16879             id = _id;
16880             hasActivities = false;
16881         }
16882     }
16883
16884     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16885             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16886         if (sort && !isCompact) {
16887             Collections.sort(items, new Comparator<MemItem>() {
16888                 @Override
16889                 public int compare(MemItem lhs, MemItem rhs) {
16890                     if (lhs.pss < rhs.pss) {
16891                         return 1;
16892                     } else if (lhs.pss > rhs.pss) {
16893                         return -1;
16894                     }
16895                     return 0;
16896                 }
16897             });
16898         }
16899
16900         for (int i=0; i<items.size(); i++) {
16901             MemItem mi = items.get(i);
16902             if (!isCompact) {
16903                 if (dumpSwapPss) {
16904                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16905                             mi.label, stringifyKBSize(mi.swapPss));
16906                 } else {
16907                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16908                 }
16909             } else if (mi.isProc) {
16910                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16911                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16912                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16913                 pw.println(mi.hasActivities ? ",a" : ",e");
16914             } else {
16915                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16916                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16917             }
16918             if (mi.subitems != null) {
16919                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16920                         true, isCompact, dumpSwapPss);
16921             }
16922         }
16923     }
16924
16925     // These are in KB.
16926     static final long[] DUMP_MEM_BUCKETS = new long[] {
16927         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16928         120*1024, 160*1024, 200*1024,
16929         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16930         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16931     };
16932
16933     static final void appendMemBucket(StringBuilder out, long memKB, String label,
16934             boolean stackLike) {
16935         int start = label.lastIndexOf('.');
16936         if (start >= 0) start++;
16937         else start = 0;
16938         int end = label.length();
16939         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16940             if (DUMP_MEM_BUCKETS[i] >= memKB) {
16941                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16942                 out.append(bucket);
16943                 out.append(stackLike ? "MB." : "MB ");
16944                 out.append(label, start, end);
16945                 return;
16946             }
16947         }
16948         out.append(memKB/1024);
16949         out.append(stackLike ? "MB." : "MB ");
16950         out.append(label, start, end);
16951     }
16952
16953     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16954             ProcessList.NATIVE_ADJ,
16955             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16956             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16957             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16958             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16959             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16960             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16961     };
16962     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16963             "Native",
16964             "System", "Persistent", "Persistent Service", "Foreground",
16965             "Visible", "Perceptible",
16966             "Heavy Weight", "Backup",
16967             "A Services", "Home",
16968             "Previous", "B Services", "Cached"
16969     };
16970     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16971             "native",
16972             "sys", "pers", "persvc", "fore",
16973             "vis", "percept",
16974             "heavy", "backup",
16975             "servicea", "home",
16976             "prev", "serviceb", "cached"
16977     };
16978
16979     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16980             long realtime, boolean isCheckinRequest, boolean isCompact) {
16981         if (isCompact) {
16982             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16983         }
16984         if (isCheckinRequest || isCompact) {
16985             // short checkin version
16986             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16987         } else {
16988             pw.println("Applications Memory Usage (in Kilobytes):");
16989             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16990         }
16991     }
16992
16993     private static final int KSM_SHARED = 0;
16994     private static final int KSM_SHARING = 1;
16995     private static final int KSM_UNSHARED = 2;
16996     private static final int KSM_VOLATILE = 3;
16997
16998     private final long[] getKsmInfo() {
16999         long[] longOut = new long[4];
17000         final int[] SINGLE_LONG_FORMAT = new int[] {
17001             PROC_SPACE_TERM| PROC_OUT_LONG
17002         };
17003         long[] longTmp = new long[1];
17004         readProcFile("/sys/kernel/mm/ksm/pages_shared",
17005                 SINGLE_LONG_FORMAT, null, longTmp, null);
17006         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17007         longTmp[0] = 0;
17008         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17009                 SINGLE_LONG_FORMAT, null, longTmp, null);
17010         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17011         longTmp[0] = 0;
17012         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17013                 SINGLE_LONG_FORMAT, null, longTmp, null);
17014         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17015         longTmp[0] = 0;
17016         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17017                 SINGLE_LONG_FORMAT, null, longTmp, null);
17018         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17019         return longOut;
17020     }
17021
17022     private static String stringifySize(long size, int order) {
17023         Locale locale = Locale.US;
17024         switch (order) {
17025             case 1:
17026                 return String.format(locale, "%,13d", size);
17027             case 1024:
17028                 return String.format(locale, "%,9dK", size / 1024);
17029             case 1024 * 1024:
17030                 return String.format(locale, "%,5dM", size / 1024 / 1024);
17031             case 1024 * 1024 * 1024:
17032                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17033             default:
17034                 throw new IllegalArgumentException("Invalid size order");
17035         }
17036     }
17037
17038     private static String stringifyKBSize(long size) {
17039         return stringifySize(size * 1024, 1024);
17040     }
17041
17042     // Update this version number in case you change the 'compact' format
17043     private static final int MEMINFO_COMPACT_VERSION = 1;
17044
17045     final void dumpApplicationMemoryUsage(FileDescriptor fd,
17046             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17047         boolean dumpDetails = false;
17048         boolean dumpFullDetails = false;
17049         boolean dumpDalvik = false;
17050         boolean dumpSummaryOnly = false;
17051         boolean dumpUnreachable = false;
17052         boolean oomOnly = false;
17053         boolean isCompact = false;
17054         boolean localOnly = false;
17055         boolean packages = false;
17056         boolean isCheckinRequest = false;
17057         boolean dumpSwapPss = false;
17058
17059         int opti = 0;
17060         while (opti < args.length) {
17061             String opt = args[opti];
17062             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17063                 break;
17064             }
17065             opti++;
17066             if ("-a".equals(opt)) {
17067                 dumpDetails = true;
17068                 dumpFullDetails = true;
17069                 dumpDalvik = true;
17070                 dumpSwapPss = true;
17071             } else if ("-d".equals(opt)) {
17072                 dumpDalvik = true;
17073             } else if ("-c".equals(opt)) {
17074                 isCompact = true;
17075             } else if ("-s".equals(opt)) {
17076                 dumpDetails = true;
17077                 dumpSummaryOnly = true;
17078             } else if ("-S".equals(opt)) {
17079                 dumpSwapPss = true;
17080             } else if ("--unreachable".equals(opt)) {
17081                 dumpUnreachable = true;
17082             } else if ("--oom".equals(opt)) {
17083                 oomOnly = true;
17084             } else if ("--local".equals(opt)) {
17085                 localOnly = true;
17086             } else if ("--package".equals(opt)) {
17087                 packages = true;
17088             } else if ("--checkin".equals(opt)) {
17089                 isCheckinRequest = true;
17090
17091             } else if ("-h".equals(opt)) {
17092                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17093                 pw.println("  -a: include all available information for each process.");
17094                 pw.println("  -d: include dalvik details.");
17095                 pw.println("  -c: dump in a compact machine-parseable representation.");
17096                 pw.println("  -s: dump only summary of application memory usage.");
17097                 pw.println("  -S: dump also SwapPss.");
17098                 pw.println("  --oom: only show processes organized by oom adj.");
17099                 pw.println("  --local: only collect details locally, don't call process.");
17100                 pw.println("  --package: interpret process arg as package, dumping all");
17101                 pw.println("             processes that have loaded that package.");
17102                 pw.println("  --checkin: dump data for a checkin");
17103                 pw.println("If [process] is specified it can be the name or ");
17104                 pw.println("pid of a specific process to dump.");
17105                 return;
17106             } else {
17107                 pw.println("Unknown argument: " + opt + "; use -h for help");
17108             }
17109         }
17110
17111         long uptime = SystemClock.uptimeMillis();
17112         long realtime = SystemClock.elapsedRealtime();
17113         final long[] tmpLong = new long[1];
17114
17115         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17116         if (procs == null) {
17117             // No Java processes.  Maybe they want to print a native process.
17118             if (args != null && args.length > opti
17119                     && args[opti].charAt(0) != '-') {
17120                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17121                         = new ArrayList<ProcessCpuTracker.Stats>();
17122                 updateCpuStatsNow();
17123                 int findPid = -1;
17124                 try {
17125                     findPid = Integer.parseInt(args[opti]);
17126                 } catch (NumberFormatException e) {
17127                 }
17128                 synchronized (mProcessCpuTracker) {
17129                     final int N = mProcessCpuTracker.countStats();
17130                     for (int i=0; i<N; i++) {
17131                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17132                         if (st.pid == findPid || (st.baseName != null
17133                                 && st.baseName.equals(args[opti]))) {
17134                             nativeProcs.add(st);
17135                         }
17136                     }
17137                 }
17138                 if (nativeProcs.size() > 0) {
17139                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17140                             isCompact);
17141                     Debug.MemoryInfo mi = null;
17142                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17143                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17144                         final int pid = r.pid;
17145                         if (!isCheckinRequest && dumpDetails) {
17146                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17147                         }
17148                         if (mi == null) {
17149                             mi = new Debug.MemoryInfo();
17150                         }
17151                         if (dumpDetails || (!brief && !oomOnly)) {
17152                             Debug.getMemoryInfo(pid, mi);
17153                         } else {
17154                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17155                             mi.dalvikPrivateDirty = (int)tmpLong[0];
17156                         }
17157                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17158                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17159                         if (isCheckinRequest) {
17160                             pw.println();
17161                         }
17162                     }
17163                     return;
17164                 }
17165             }
17166             pw.println("No process found for: " + args[opti]);
17167             return;
17168         }
17169
17170         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17171             dumpDetails = true;
17172         }
17173
17174         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17175
17176         String[] innerArgs = new String[args.length-opti];
17177         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17178
17179         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17180         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17181         long nativePss = 0;
17182         long nativeSwapPss = 0;
17183         long dalvikPss = 0;
17184         long dalvikSwapPss = 0;
17185         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17186                 EmptyArray.LONG;
17187         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17188                 EmptyArray.LONG;
17189         long otherPss = 0;
17190         long otherSwapPss = 0;
17191         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17192         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17193
17194         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17195         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17196         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17197                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17198
17199         long totalPss = 0;
17200         long totalSwapPss = 0;
17201         long cachedPss = 0;
17202         long cachedSwapPss = 0;
17203         boolean hasSwapPss = false;
17204
17205         Debug.MemoryInfo mi = null;
17206         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17207             final ProcessRecord r = procs.get(i);
17208             final IApplicationThread thread;
17209             final int pid;
17210             final int oomAdj;
17211             final boolean hasActivities;
17212             synchronized (this) {
17213                 thread = r.thread;
17214                 pid = r.pid;
17215                 oomAdj = r.getSetAdjWithServices();
17216                 hasActivities = r.activities.size() > 0;
17217             }
17218             if (thread != null) {
17219                 if (!isCheckinRequest && dumpDetails) {
17220                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17221                 }
17222                 if (mi == null) {
17223                     mi = new Debug.MemoryInfo();
17224                 }
17225                 if (dumpDetails || (!brief && !oomOnly)) {
17226                     Debug.getMemoryInfo(pid, mi);
17227                     hasSwapPss = mi.hasSwappedOutPss;
17228                 } else {
17229                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17230                     mi.dalvikPrivateDirty = (int)tmpLong[0];
17231                 }
17232                 if (dumpDetails) {
17233                     if (localOnly) {
17234                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17235                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17236                         if (isCheckinRequest) {
17237                             pw.println();
17238                         }
17239                     } else {
17240                         pw.flush();
17241                         try {
17242                             TransferPipe tp = new TransferPipe();
17243                             try {
17244                                 thread.dumpMemInfo(tp.getWriteFd(),
17245                                         mi, isCheckinRequest, dumpFullDetails,
17246                                         dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17247                                 tp.go(fd);
17248                             } finally {
17249                                 tp.kill();
17250                             }
17251                         } catch (IOException e) {
17252                             if (!isCheckinRequest) {
17253                                 pw.println("Got IoException!");
17254                                 pw.flush();
17255                             }
17256                         } catch (RemoteException e) {
17257                             if (!isCheckinRequest) {
17258                                 pw.println("Got RemoteException!");
17259                                 pw.flush();
17260                             }
17261                         }
17262                     }
17263                 }
17264
17265                 final long myTotalPss = mi.getTotalPss();
17266                 final long myTotalUss = mi.getTotalUss();
17267                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17268
17269                 synchronized (this) {
17270                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17271                         // Record this for posterity if the process has been stable.
17272                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17273                     }
17274                 }
17275
17276                 if (!isCheckinRequest && mi != null) {
17277                     totalPss += myTotalPss;
17278                     totalSwapPss += myTotalSwapPss;
17279                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17280                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17281                             myTotalSwapPss, pid, hasActivities);
17282                     procMems.add(pssItem);
17283                     procMemsMap.put(pid, pssItem);
17284
17285                     nativePss += mi.nativePss;
17286                     nativeSwapPss += mi.nativeSwappedOutPss;
17287                     dalvikPss += mi.dalvikPss;
17288                     dalvikSwapPss += mi.dalvikSwappedOutPss;
17289                     for (int j=0; j<dalvikSubitemPss.length; j++) {
17290                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17291                         dalvikSubitemSwapPss[j] +=
17292                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17293                     }
17294                     otherPss += mi.otherPss;
17295                     otherSwapPss += mi.otherSwappedOutPss;
17296                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17297                         long mem = mi.getOtherPss(j);
17298                         miscPss[j] += mem;
17299                         otherPss -= mem;
17300                         mem = mi.getOtherSwappedOutPss(j);
17301                         miscSwapPss[j] += mem;
17302                         otherSwapPss -= mem;
17303                     }
17304
17305                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17306                         cachedPss += myTotalPss;
17307                         cachedSwapPss += myTotalSwapPss;
17308                     }
17309
17310                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17311                         if (oomIndex == (oomPss.length - 1)
17312                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17313                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17314                             oomPss[oomIndex] += myTotalPss;
17315                             oomSwapPss[oomIndex] += myTotalSwapPss;
17316                             if (oomProcs[oomIndex] == null) {
17317                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
17318                             }
17319                             oomProcs[oomIndex].add(pssItem);
17320                             break;
17321                         }
17322                     }
17323                 }
17324             }
17325         }
17326
17327         long nativeProcTotalPss = 0;
17328
17329         if (!isCheckinRequest && procs.size() > 1 && !packages) {
17330             // If we are showing aggregations, also look for native processes to
17331             // include so that our aggregations are more accurate.
17332             updateCpuStatsNow();
17333             mi = null;
17334             synchronized (mProcessCpuTracker) {
17335                 final int N = mProcessCpuTracker.countStats();
17336                 for (int i=0; i<N; i++) {
17337                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17338                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17339                         if (mi == null) {
17340                             mi = new Debug.MemoryInfo();
17341                         }
17342                         if (!brief && !oomOnly) {
17343                             Debug.getMemoryInfo(st.pid, mi);
17344                         } else {
17345                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17346                             mi.nativePrivateDirty = (int)tmpLong[0];
17347                         }
17348
17349                         final long myTotalPss = mi.getTotalPss();
17350                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17351                         totalPss += myTotalPss;
17352                         nativeProcTotalPss += myTotalPss;
17353
17354                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17355                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17356                         procMems.add(pssItem);
17357
17358                         nativePss += mi.nativePss;
17359                         nativeSwapPss += mi.nativeSwappedOutPss;
17360                         dalvikPss += mi.dalvikPss;
17361                         dalvikSwapPss += mi.dalvikSwappedOutPss;
17362                         for (int j=0; j<dalvikSubitemPss.length; j++) {
17363                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17364                             dalvikSubitemSwapPss[j] +=
17365                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17366                         }
17367                         otherPss += mi.otherPss;
17368                         otherSwapPss += mi.otherSwappedOutPss;
17369                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17370                             long mem = mi.getOtherPss(j);
17371                             miscPss[j] += mem;
17372                             otherPss -= mem;
17373                             mem = mi.getOtherSwappedOutPss(j);
17374                             miscSwapPss[j] += mem;
17375                             otherSwapPss -= mem;
17376                         }
17377                         oomPss[0] += myTotalPss;
17378                         oomSwapPss[0] += myTotalSwapPss;
17379                         if (oomProcs[0] == null) {
17380                             oomProcs[0] = new ArrayList<MemItem>();
17381                         }
17382                         oomProcs[0].add(pssItem);
17383                     }
17384                 }
17385             }
17386
17387             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17388
17389             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17390             final MemItem dalvikItem =
17391                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17392             if (dalvikSubitemPss.length > 0) {
17393                 dalvikItem.subitems = new ArrayList<MemItem>();
17394                 for (int j=0; j<dalvikSubitemPss.length; j++) {
17395                     final String name = Debug.MemoryInfo.getOtherLabel(
17396                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
17397                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17398                                     dalvikSubitemSwapPss[j], j));
17399                 }
17400             }
17401             catMems.add(dalvikItem);
17402             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17403             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17404                 String label = Debug.MemoryInfo.getOtherLabel(j);
17405                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17406             }
17407
17408             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17409             for (int j=0; j<oomPss.length; j++) {
17410                 if (oomPss[j] != 0) {
17411                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17412                             : DUMP_MEM_OOM_LABEL[j];
17413                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17414                             DUMP_MEM_OOM_ADJ[j]);
17415                     item.subitems = oomProcs[j];
17416                     oomMems.add(item);
17417                 }
17418             }
17419
17420             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17421             if (!brief && !oomOnly && !isCompact) {
17422                 pw.println();
17423                 pw.println("Total PSS by process:");
17424                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17425                 pw.println();
17426             }
17427             if (!isCompact) {
17428                 pw.println("Total PSS by OOM adjustment:");
17429             }
17430             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17431             if (!brief && !oomOnly) {
17432                 PrintWriter out = categoryPw != null ? categoryPw : pw;
17433                 if (!isCompact) {
17434                     out.println();
17435                     out.println("Total PSS by category:");
17436                 }
17437                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17438             }
17439             if (!isCompact) {
17440                 pw.println();
17441             }
17442             MemInfoReader memInfo = new MemInfoReader();
17443             memInfo.readMemInfo();
17444             if (nativeProcTotalPss > 0) {
17445                 synchronized (this) {
17446                     final long cachedKb = memInfo.getCachedSizeKb();
17447                     final long freeKb = memInfo.getFreeSizeKb();
17448                     final long zramKb = memInfo.getZramTotalSizeKb();
17449                     final long kernelKb = memInfo.getKernelUsedSizeKb();
17450                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17451                             kernelKb*1024, nativeProcTotalPss*1024);
17452                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17453                             nativeProcTotalPss);
17454                 }
17455             }
17456             if (!brief) {
17457                 if (!isCompact) {
17458                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17459                     pw.print(" (status ");
17460                     switch (mLastMemoryLevel) {
17461                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17462                             pw.println("normal)");
17463                             break;
17464                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17465                             pw.println("moderate)");
17466                             break;
17467                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
17468                             pw.println("low)");
17469                             break;
17470                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17471                             pw.println("critical)");
17472                             break;
17473                         default:
17474                             pw.print(mLastMemoryLevel);
17475                             pw.println(")");
17476                             break;
17477                     }
17478                     pw.print(" Free RAM: ");
17479                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17480                             + memInfo.getFreeSizeKb()));
17481                     pw.print(" (");
17482                     pw.print(stringifyKBSize(cachedPss));
17483                     pw.print(" cached pss + ");
17484                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17485                     pw.print(" cached kernel + ");
17486                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17487                     pw.println(" free)");
17488                 } else {
17489                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17490                     pw.print(cachedPss + memInfo.getCachedSizeKb()
17491                             + memInfo.getFreeSizeKb()); pw.print(",");
17492                     pw.println(totalPss - cachedPss);
17493                 }
17494             }
17495             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17496                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17497                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17498             if (!isCompact) {
17499                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17500                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17501                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17502                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17503                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17504             } else {
17505                 pw.print("lostram,"); pw.println(lostRAM);
17506             }
17507             if (!brief) {
17508                 if (memInfo.getZramTotalSizeKb() != 0) {
17509                     if (!isCompact) {
17510                         pw.print("     ZRAM: ");
17511                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17512                                 pw.print(" physical used for ");
17513                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17514                                         - memInfo.getSwapFreeSizeKb()));
17515                                 pw.print(" in swap (");
17516                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17517                                 pw.println(" total swap)");
17518                     } else {
17519                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17520                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17521                                 pw.println(memInfo.getSwapFreeSizeKb());
17522                     }
17523                 }
17524                 final long[] ksm = getKsmInfo();
17525                 if (!isCompact) {
17526                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17527                             || ksm[KSM_VOLATILE] != 0) {
17528                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17529                                 pw.print(" saved from shared ");
17530                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17531                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17532                                 pw.print(" unshared; ");
17533                                 pw.print(stringifyKBSize(
17534                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
17535                     }
17536                     pw.print("   Tuning: ");
17537                     pw.print(ActivityManager.staticGetMemoryClass());
17538                     pw.print(" (large ");
17539                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17540                     pw.print("), oom ");
17541                     pw.print(stringifySize(
17542                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17543                     pw.print(", restore limit ");
17544                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17545                     if (ActivityManager.isLowRamDeviceStatic()) {
17546                         pw.print(" (low-ram)");
17547                     }
17548                     if (ActivityManager.isHighEndGfx()) {
17549                         pw.print(" (high-end-gfx)");
17550                     }
17551                     pw.println();
17552                 } else {
17553                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17554                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17555                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17556                     pw.print("tuning,");
17557                     pw.print(ActivityManager.staticGetMemoryClass());
17558                     pw.print(',');
17559                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17560                     pw.print(',');
17561                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17562                     if (ActivityManager.isLowRamDeviceStatic()) {
17563                         pw.print(",low-ram");
17564                     }
17565                     if (ActivityManager.isHighEndGfx()) {
17566                         pw.print(",high-end-gfx");
17567                     }
17568                     pw.println();
17569                 }
17570             }
17571         }
17572     }
17573
17574     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17575             long memtrack, String name) {
17576         sb.append("  ");
17577         sb.append(ProcessList.makeOomAdjString(oomAdj));
17578         sb.append(' ');
17579         sb.append(ProcessList.makeProcStateString(procState));
17580         sb.append(' ');
17581         ProcessList.appendRamKb(sb, pss);
17582         sb.append(": ");
17583         sb.append(name);
17584         if (memtrack > 0) {
17585             sb.append(" (");
17586             sb.append(stringifyKBSize(memtrack));
17587             sb.append(" memtrack)");
17588         }
17589     }
17590
17591     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17592         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17593         sb.append(" (pid ");
17594         sb.append(mi.pid);
17595         sb.append(") ");
17596         sb.append(mi.adjType);
17597         sb.append('\n');
17598         if (mi.adjReason != null) {
17599             sb.append("                      ");
17600             sb.append(mi.adjReason);
17601             sb.append('\n');
17602         }
17603     }
17604
17605     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17606         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17607         for (int i=0, N=memInfos.size(); i<N; i++) {
17608             ProcessMemInfo mi = memInfos.get(i);
17609             infoMap.put(mi.pid, mi);
17610         }
17611         updateCpuStatsNow();
17612         long[] memtrackTmp = new long[1];
17613         final List<ProcessCpuTracker.Stats> stats;
17614         // Get a list of Stats that have vsize > 0
17615         synchronized (mProcessCpuTracker) {
17616             stats = mProcessCpuTracker.getStats((st) -> {
17617                 return st.vsize > 0;
17618             });
17619         }
17620         final int statsCount = stats.size();
17621         for (int i = 0; i < statsCount; i++) {
17622             ProcessCpuTracker.Stats st = stats.get(i);
17623             long pss = Debug.getPss(st.pid, null, memtrackTmp);
17624             if (pss > 0) {
17625                 if (infoMap.indexOfKey(st.pid) < 0) {
17626                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17627                             ProcessList.NATIVE_ADJ, -1, "native", null);
17628                     mi.pss = pss;
17629                     mi.memtrack = memtrackTmp[0];
17630                     memInfos.add(mi);
17631                 }
17632             }
17633         }
17634
17635         long totalPss = 0;
17636         long totalMemtrack = 0;
17637         for (int i=0, N=memInfos.size(); i<N; i++) {
17638             ProcessMemInfo mi = memInfos.get(i);
17639             if (mi.pss == 0) {
17640                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17641                 mi.memtrack = memtrackTmp[0];
17642             }
17643             totalPss += mi.pss;
17644             totalMemtrack += mi.memtrack;
17645         }
17646         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17647             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17648                 if (lhs.oomAdj != rhs.oomAdj) {
17649                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17650                 }
17651                 if (lhs.pss != rhs.pss) {
17652                     return lhs.pss < rhs.pss ? 1 : -1;
17653                 }
17654                 return 0;
17655             }
17656         });
17657
17658         StringBuilder tag = new StringBuilder(128);
17659         StringBuilder stack = new StringBuilder(128);
17660         tag.append("Low on memory -- ");
17661         appendMemBucket(tag, totalPss, "total", false);
17662         appendMemBucket(stack, totalPss, "total", true);
17663
17664         StringBuilder fullNativeBuilder = new StringBuilder(1024);
17665         StringBuilder shortNativeBuilder = new StringBuilder(1024);
17666         StringBuilder fullJavaBuilder = new StringBuilder(1024);
17667
17668         boolean firstLine = true;
17669         int lastOomAdj = Integer.MIN_VALUE;
17670         long extraNativeRam = 0;
17671         long extraNativeMemtrack = 0;
17672         long cachedPss = 0;
17673         for (int i=0, N=memInfos.size(); i<N; i++) {
17674             ProcessMemInfo mi = memInfos.get(i);
17675
17676             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17677                 cachedPss += mi.pss;
17678             }
17679
17680             if (mi.oomAdj != ProcessList.NATIVE_ADJ
17681                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
17682                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
17683                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17684                 if (lastOomAdj != mi.oomAdj) {
17685                     lastOomAdj = mi.oomAdj;
17686                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17687                         tag.append(" / ");
17688                     }
17689                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17690                         if (firstLine) {
17691                             stack.append(":");
17692                             firstLine = false;
17693                         }
17694                         stack.append("\n\t at ");
17695                     } else {
17696                         stack.append("$");
17697                     }
17698                 } else {
17699                     tag.append(" ");
17700                     stack.append("$");
17701                 }
17702                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17703                     appendMemBucket(tag, mi.pss, mi.name, false);
17704                 }
17705                 appendMemBucket(stack, mi.pss, mi.name, true);
17706                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17707                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17708                     stack.append("(");
17709                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17710                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17711                             stack.append(DUMP_MEM_OOM_LABEL[k]);
17712                             stack.append(":");
17713                             stack.append(DUMP_MEM_OOM_ADJ[k]);
17714                         }
17715                     }
17716                     stack.append(")");
17717                 }
17718             }
17719
17720             appendMemInfo(fullNativeBuilder, mi);
17721             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17722                 // The short form only has native processes that are >= 512K.
17723                 if (mi.pss >= 512) {
17724                     appendMemInfo(shortNativeBuilder, mi);
17725                 } else {
17726                     extraNativeRam += mi.pss;
17727                     extraNativeMemtrack += mi.memtrack;
17728                 }
17729             } else {
17730                 // Short form has all other details, but if we have collected RAM
17731                 // from smaller native processes let's dump a summary of that.
17732                 if (extraNativeRam > 0) {
17733                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17734                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17735                     shortNativeBuilder.append('\n');
17736                     extraNativeRam = 0;
17737                 }
17738                 appendMemInfo(fullJavaBuilder, mi);
17739             }
17740         }
17741
17742         fullJavaBuilder.append("           ");
17743         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17744         fullJavaBuilder.append(": TOTAL");
17745         if (totalMemtrack > 0) {
17746             fullJavaBuilder.append(" (");
17747             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17748             fullJavaBuilder.append(" memtrack)");
17749         } else {
17750         }
17751         fullJavaBuilder.append("\n");
17752
17753         MemInfoReader memInfo = new MemInfoReader();
17754         memInfo.readMemInfo();
17755         final long[] infos = memInfo.getRawInfo();
17756
17757         StringBuilder memInfoBuilder = new StringBuilder(1024);
17758         Debug.getMemInfo(infos);
17759         memInfoBuilder.append("  MemInfo: ");
17760         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17761         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17762         memInfoBuilder.append(stringifyKBSize(
17763                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17764         memInfoBuilder.append(stringifyKBSize(
17765                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17766         memInfoBuilder.append(stringifyKBSize(
17767                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17768         memInfoBuilder.append("           ");
17769         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17770         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17771         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17772         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17773         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17774             memInfoBuilder.append("  ZRAM: ");
17775             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17776             memInfoBuilder.append(" RAM, ");
17777             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17778             memInfoBuilder.append(" swap total, ");
17779             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17780             memInfoBuilder.append(" swap free\n");
17781         }
17782         final long[] ksm = getKsmInfo();
17783         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17784                 || ksm[KSM_VOLATILE] != 0) {
17785             memInfoBuilder.append("  KSM: ");
17786             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17787             memInfoBuilder.append(" saved from shared ");
17788             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17789             memInfoBuilder.append("\n       ");
17790             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17791             memInfoBuilder.append(" unshared; ");
17792             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17793             memInfoBuilder.append(" volatile\n");
17794         }
17795         memInfoBuilder.append("  Free RAM: ");
17796         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17797                 + memInfo.getFreeSizeKb()));
17798         memInfoBuilder.append("\n");
17799         memInfoBuilder.append("  Used RAM: ");
17800         memInfoBuilder.append(stringifyKBSize(
17801                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17802         memInfoBuilder.append("\n");
17803         memInfoBuilder.append("  Lost RAM: ");
17804         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17805                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17806                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17807         memInfoBuilder.append("\n");
17808         Slog.i(TAG, "Low on memory:");
17809         Slog.i(TAG, shortNativeBuilder.toString());
17810         Slog.i(TAG, fullJavaBuilder.toString());
17811         Slog.i(TAG, memInfoBuilder.toString());
17812
17813         StringBuilder dropBuilder = new StringBuilder(1024);
17814         /*
17815         StringWriter oomSw = new StringWriter();
17816         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17817         StringWriter catSw = new StringWriter();
17818         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17819         String[] emptyArgs = new String[] { };
17820         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17821         oomPw.flush();
17822         String oomString = oomSw.toString();
17823         */
17824         dropBuilder.append("Low on memory:");
17825         dropBuilder.append(stack);
17826         dropBuilder.append('\n');
17827         dropBuilder.append(fullNativeBuilder);
17828         dropBuilder.append(fullJavaBuilder);
17829         dropBuilder.append('\n');
17830         dropBuilder.append(memInfoBuilder);
17831         dropBuilder.append('\n');
17832         /*
17833         dropBuilder.append(oomString);
17834         dropBuilder.append('\n');
17835         */
17836         StringWriter catSw = new StringWriter();
17837         synchronized (ActivityManagerService.this) {
17838             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17839             String[] emptyArgs = new String[] { };
17840             catPw.println();
17841             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17842             catPw.println();
17843             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17844                     false, null).dumpLocked();
17845             catPw.println();
17846             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17847             catPw.flush();
17848         }
17849         dropBuilder.append(catSw.toString());
17850         addErrorToDropBox("lowmem", null, "system_server", null,
17851                 null, tag.toString(), dropBuilder.toString(), null, null);
17852         //Slog.i(TAG, "Sent to dropbox:");
17853         //Slog.i(TAG, dropBuilder.toString());
17854         synchronized (ActivityManagerService.this) {
17855             long now = SystemClock.uptimeMillis();
17856             if (mLastMemUsageReportTime < now) {
17857                 mLastMemUsageReportTime = now;
17858             }
17859         }
17860     }
17861
17862     /**
17863      * Searches array of arguments for the specified string
17864      * @param args array of argument strings
17865      * @param value value to search for
17866      * @return true if the value is contained in the array
17867      */
17868     private static boolean scanArgs(String[] args, String value) {
17869         if (args != null) {
17870             for (String arg : args) {
17871                 if (value.equals(arg)) {
17872                     return true;
17873                 }
17874             }
17875         }
17876         return false;
17877     }
17878
17879     private final boolean removeDyingProviderLocked(ProcessRecord proc,
17880             ContentProviderRecord cpr, boolean always) {
17881         final boolean inLaunching = mLaunchingProviders.contains(cpr);
17882
17883         if (!inLaunching || always) {
17884             synchronized (cpr) {
17885                 cpr.launchingApp = null;
17886                 cpr.notifyAll();
17887             }
17888             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17889             String names[] = cpr.info.authority.split(";");
17890             for (int j = 0; j < names.length; j++) {
17891                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17892             }
17893         }
17894
17895         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17896             ContentProviderConnection conn = cpr.connections.get(i);
17897             if (conn.waiting) {
17898                 // If this connection is waiting for the provider, then we don't
17899                 // need to mess with its process unless we are always removing
17900                 // or for some reason the provider is not currently launching.
17901                 if (inLaunching && !always) {
17902                     continue;
17903                 }
17904             }
17905             ProcessRecord capp = conn.client;
17906             conn.dead = true;
17907             if (conn.stableCount > 0) {
17908                 if (!capp.persistent && capp.thread != null
17909                         && capp.pid != 0
17910                         && capp.pid != MY_PID) {
17911                     capp.kill("depends on provider "
17912                             + cpr.name.flattenToShortString()
17913                             + " in dying proc " + (proc != null ? proc.processName : "??")
17914                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17915                 }
17916             } else if (capp.thread != null && conn.provider.provider != null) {
17917                 try {
17918                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17919                 } catch (RemoteException e) {
17920                 }
17921                 // In the protocol here, we don't expect the client to correctly
17922                 // clean up this connection, we'll just remove it.
17923                 cpr.connections.remove(i);
17924                 if (conn.client.conProviders.remove(conn)) {
17925                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17926                 }
17927             }
17928         }
17929
17930         if (inLaunching && always) {
17931             mLaunchingProviders.remove(cpr);
17932         }
17933         return inLaunching;
17934     }
17935
17936     /**
17937      * Main code for cleaning up a process when it has gone away.  This is
17938      * called both as a result of the process dying, or directly when stopping
17939      * a process when running in single process mode.
17940      *
17941      * @return Returns true if the given process has been restarted, so the
17942      * app that was passed in must remain on the process lists.
17943      */
17944     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17945             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17946         if (index >= 0) {
17947             removeLruProcessLocked(app);
17948             ProcessList.remove(app.pid);
17949         }
17950
17951         mProcessesToGc.remove(app);
17952         mPendingPssProcesses.remove(app);
17953
17954         // Dismiss any open dialogs.
17955         if (app.crashDialog != null && !app.forceCrashReport) {
17956             app.crashDialog.dismiss();
17957             app.crashDialog = null;
17958         }
17959         if (app.anrDialog != null) {
17960             app.anrDialog.dismiss();
17961             app.anrDialog = null;
17962         }
17963         if (app.waitDialog != null) {
17964             app.waitDialog.dismiss();
17965             app.waitDialog = null;
17966         }
17967
17968         app.crashing = false;
17969         app.notResponding = false;
17970
17971         app.resetPackageList(mProcessStats);
17972         app.unlinkDeathRecipient();
17973         app.makeInactive(mProcessStats);
17974         app.waitingToKill = null;
17975         app.forcingToImportant = null;
17976         updateProcessForegroundLocked(app, false, false);
17977         app.foregroundActivities = false;
17978         app.hasShownUi = false;
17979         app.treatLikeActivity = false;
17980         app.hasAboveClient = false;
17981         app.hasClientActivities = false;
17982
17983         mServices.killServicesLocked(app, allowRestart);
17984
17985         boolean restart = false;
17986
17987         // Remove published content providers.
17988         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17989             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17990             final boolean always = app.bad || !allowRestart;
17991             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17992             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17993                 // We left the provider in the launching list, need to
17994                 // restart it.
17995                 restart = true;
17996             }
17997
17998             cpr.provider = null;
17999             cpr.proc = null;
18000         }
18001         app.pubProviders.clear();
18002
18003         // Take care of any launching providers waiting for this process.
18004         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18005             restart = true;
18006         }
18007
18008         // Unregister from connected content providers.
18009         if (!app.conProviders.isEmpty()) {
18010             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18011                 ContentProviderConnection conn = app.conProviders.get(i);
18012                 conn.provider.connections.remove(conn);
18013                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18014                         conn.provider.name);
18015             }
18016             app.conProviders.clear();
18017         }
18018
18019         // At this point there may be remaining entries in mLaunchingProviders
18020         // where we were the only one waiting, so they are no longer of use.
18021         // Look for these and clean up if found.
18022         // XXX Commented out for now.  Trying to figure out a way to reproduce
18023         // the actual situation to identify what is actually going on.
18024         if (false) {
18025             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18026                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18027                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18028                     synchronized (cpr) {
18029                         cpr.launchingApp = null;
18030                         cpr.notifyAll();
18031                     }
18032                 }
18033             }
18034         }
18035
18036         skipCurrentReceiverLocked(app);
18037
18038         // Unregister any receivers.
18039         for (int i = app.receivers.size() - 1; i >= 0; i--) {
18040             removeReceiverLocked(app.receivers.valueAt(i));
18041         }
18042         app.receivers.clear();
18043
18044         // If the app is undergoing backup, tell the backup manager about it
18045         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18046             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18047                     + mBackupTarget.appInfo + " died during backup");
18048             mHandler.post(new Runnable() {
18049                 @Override
18050                 public void run(){
18051                     try {
18052                         IBackupManager bm = IBackupManager.Stub.asInterface(
18053                                 ServiceManager.getService(Context.BACKUP_SERVICE));
18054                         bm.agentDisconnected(app.info.packageName);
18055                     } catch (RemoteException e) {
18056                         // can't happen; backup manager is local
18057                     }
18058                 }
18059             });
18060         }
18061
18062         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18063             ProcessChangeItem item = mPendingProcessChanges.get(i);
18064             if (item.pid == app.pid) {
18065                 mPendingProcessChanges.remove(i);
18066                 mAvailProcessChanges.add(item);
18067             }
18068         }
18069         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18070                 null).sendToTarget();
18071
18072         // If the caller is restarting this app, then leave it in its
18073         // current lists and let the caller take care of it.
18074         if (restarting) {
18075             return false;
18076         }
18077
18078         if (!app.persistent || app.isolated) {
18079             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18080                     "Removing non-persistent process during cleanup: " + app);
18081             if (!replacingPid) {
18082                 removeProcessNameLocked(app.processName, app.uid, app);
18083             }
18084             if (mHeavyWeightProcess == app) {
18085                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18086                         mHeavyWeightProcess.userId, 0));
18087                 mHeavyWeightProcess = null;
18088             }
18089         } else if (!app.removed) {
18090             // This app is persistent, so we need to keep its record around.
18091             // If it is not already on the pending app list, add it there
18092             // and start a new process for it.
18093             if (mPersistentStartingProcesses.indexOf(app) < 0) {
18094                 mPersistentStartingProcesses.add(app);
18095                 restart = true;
18096             }
18097         }
18098         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18099                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18100         mProcessesOnHold.remove(app);
18101
18102         if (app == mHomeProcess) {
18103             mHomeProcess = null;
18104         }
18105         if (app == mPreviousProcess) {
18106             mPreviousProcess = null;
18107         }
18108
18109         if (restart && !app.isolated) {
18110             // We have components that still need to be running in the
18111             // process, so re-launch it.
18112             if (index < 0) {
18113                 ProcessList.remove(app.pid);
18114             }
18115             addProcessNameLocked(app);
18116             startProcessLocked(app, "restart", app.processName);
18117             return true;
18118         } else if (app.pid > 0 && app.pid != MY_PID) {
18119             // Goodbye!
18120             boolean removed;
18121             synchronized (mPidsSelfLocked) {
18122                 mPidsSelfLocked.remove(app.pid);
18123                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18124             }
18125             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18126             if (app.isolated) {
18127                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18128             }
18129             app.setPid(0);
18130         }
18131         return false;
18132     }
18133
18134     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18135         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18136             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18137             if (cpr.launchingApp == app) {
18138                 return true;
18139             }
18140         }
18141         return false;
18142     }
18143
18144     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18145         // Look through the content providers we are waiting to have launched,
18146         // and if any run in this process then either schedule a restart of
18147         // the process or kill the client waiting for it if this process has
18148         // gone bad.
18149         boolean restart = false;
18150         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18151             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18152             if (cpr.launchingApp == app) {
18153                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18154                     restart = true;
18155                 } else {
18156                     removeDyingProviderLocked(app, cpr, true);
18157                 }
18158             }
18159         }
18160         return restart;
18161     }
18162
18163     // =========================================================
18164     // SERVICES
18165     // =========================================================
18166
18167     @Override
18168     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18169             int flags) {
18170         enforceNotIsolatedCaller("getServices");
18171
18172         final int callingUid = Binder.getCallingUid();
18173         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18174             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18175         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18176             callingUid);
18177         synchronized (this) {
18178             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18179                 allowed, canInteractAcrossUsers);
18180         }
18181     }
18182
18183     @Override
18184     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18185         enforceNotIsolatedCaller("getRunningServiceControlPanel");
18186         synchronized (this) {
18187             return mServices.getRunningServiceControlPanelLocked(name);
18188         }
18189     }
18190
18191     @Override
18192     public ComponentName startService(IApplicationThread caller, Intent service,
18193             String resolvedType, boolean requireForeground, String callingPackage, int userId)
18194             throws TransactionTooLargeException {
18195         enforceNotIsolatedCaller("startService");
18196         // Refuse possible leaked file descriptors
18197         if (service != null && service.hasFileDescriptors() == true) {
18198             throw new IllegalArgumentException("File descriptors passed in Intent");
18199         }
18200
18201         if (callingPackage == null) {
18202             throw new IllegalArgumentException("callingPackage cannot be null");
18203         }
18204
18205         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18206                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18207         synchronized(this) {
18208             final int callingPid = Binder.getCallingPid();
18209             final int callingUid = Binder.getCallingUid();
18210             final long origId = Binder.clearCallingIdentity();
18211             ComponentName res;
18212             try {
18213                 res = mServices.startServiceLocked(caller, service,
18214                         resolvedType, callingPid, callingUid,
18215                         requireForeground, callingPackage, userId);
18216             } finally {
18217                 Binder.restoreCallingIdentity(origId);
18218             }
18219             return res;
18220         }
18221     }
18222
18223     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18224             boolean fgRequired, String callingPackage, int userId)
18225             throws TransactionTooLargeException {
18226         synchronized(this) {
18227             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18228                     "startServiceInPackage: " + service + " type=" + resolvedType);
18229             final long origId = Binder.clearCallingIdentity();
18230             ComponentName res;
18231             try {
18232                 res = mServices.startServiceLocked(null, service,
18233                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
18234             } finally {
18235                 Binder.restoreCallingIdentity(origId);
18236             }
18237             return res;
18238         }
18239     }
18240
18241     @Override
18242     public int stopService(IApplicationThread caller, Intent service,
18243             String resolvedType, int userId) {
18244         enforceNotIsolatedCaller("stopService");
18245         // Refuse possible leaked file descriptors
18246         if (service != null && service.hasFileDescriptors() == true) {
18247             throw new IllegalArgumentException("File descriptors passed in Intent");
18248         }
18249
18250         synchronized(this) {
18251             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18252         }
18253     }
18254
18255     @Override
18256     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18257         enforceNotIsolatedCaller("peekService");
18258         // Refuse possible leaked file descriptors
18259         if (service != null && service.hasFileDescriptors() == true) {
18260             throw new IllegalArgumentException("File descriptors passed in Intent");
18261         }
18262
18263         if (callingPackage == null) {
18264             throw new IllegalArgumentException("callingPackage cannot be null");
18265         }
18266
18267         synchronized(this) {
18268             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18269         }
18270     }
18271
18272     @Override
18273     public boolean stopServiceToken(ComponentName className, IBinder token,
18274             int startId) {
18275         synchronized(this) {
18276             return mServices.stopServiceTokenLocked(className, token, startId);
18277         }
18278     }
18279
18280     @Override
18281     public void setServiceForeground(ComponentName className, IBinder token,
18282             int id, Notification notification, int flags) {
18283         synchronized(this) {
18284             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18285         }
18286     }
18287
18288     @Override
18289     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18290             boolean requireFull, String name, String callerPackage) {
18291         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18292                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18293     }
18294
18295     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18296             String className, int flags) {
18297         boolean result = false;
18298         // For apps that don't have pre-defined UIDs, check for permission
18299         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18300             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18301                 if (ActivityManager.checkUidPermission(
18302                         INTERACT_ACROSS_USERS,
18303                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18304                     ComponentName comp = new ComponentName(aInfo.packageName, className);
18305                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
18306                             + " requests FLAG_SINGLE_USER, but app does not hold "
18307                             + INTERACT_ACROSS_USERS;
18308                     Slog.w(TAG, msg);
18309                     throw new SecurityException(msg);
18310                 }
18311                 // Permission passed
18312                 result = true;
18313             }
18314         } else if ("system".equals(componentProcessName)) {
18315             result = true;
18316         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18317             // Phone app and persistent apps are allowed to export singleuser providers.
18318             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18319                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18320         }
18321         if (DEBUG_MU) Slog.v(TAG_MU,
18322                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18323                 + Integer.toHexString(flags) + ") = " + result);
18324         return result;
18325     }
18326
18327     /**
18328      * Checks to see if the caller is in the same app as the singleton
18329      * component, or the component is in a special app. It allows special apps
18330      * to export singleton components but prevents exporting singleton
18331      * components for regular apps.
18332      */
18333     boolean isValidSingletonCall(int callingUid, int componentUid) {
18334         int componentAppId = UserHandle.getAppId(componentUid);
18335         return UserHandle.isSameApp(callingUid, componentUid)
18336                 || componentAppId == SYSTEM_UID
18337                 || componentAppId == PHONE_UID
18338                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18339                         == PackageManager.PERMISSION_GRANTED;
18340     }
18341
18342     public int bindService(IApplicationThread caller, IBinder token, Intent service,
18343             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18344             int userId) throws TransactionTooLargeException {
18345         enforceNotIsolatedCaller("bindService");
18346
18347         // Refuse possible leaked file descriptors
18348         if (service != null && service.hasFileDescriptors() == true) {
18349             throw new IllegalArgumentException("File descriptors passed in Intent");
18350         }
18351
18352         if (callingPackage == null) {
18353             throw new IllegalArgumentException("callingPackage cannot be null");
18354         }
18355
18356         synchronized(this) {
18357             return mServices.bindServiceLocked(caller, token, service,
18358                     resolvedType, connection, flags, callingPackage, userId);
18359         }
18360     }
18361
18362     public boolean unbindService(IServiceConnection connection) {
18363         synchronized (this) {
18364             return mServices.unbindServiceLocked(connection);
18365         }
18366     }
18367
18368     public void publishService(IBinder token, Intent intent, IBinder service) {
18369         // Refuse possible leaked file descriptors
18370         if (intent != null && intent.hasFileDescriptors() == true) {
18371             throw new IllegalArgumentException("File descriptors passed in Intent");
18372         }
18373
18374         synchronized(this) {
18375             if (!(token instanceof ServiceRecord)) {
18376                 throw new IllegalArgumentException("Invalid service token");
18377             }
18378             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18379         }
18380     }
18381
18382     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18383         // Refuse possible leaked file descriptors
18384         if (intent != null && intent.hasFileDescriptors() == true) {
18385             throw new IllegalArgumentException("File descriptors passed in Intent");
18386         }
18387
18388         synchronized(this) {
18389             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18390         }
18391     }
18392
18393     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18394         synchronized(this) {
18395             if (!(token instanceof ServiceRecord)) {
18396                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18397                 throw new IllegalArgumentException("Invalid service token");
18398             }
18399             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18400         }
18401     }
18402
18403     // =========================================================
18404     // BACKUP AND RESTORE
18405     // =========================================================
18406
18407     // Cause the target app to be launched if necessary and its backup agent
18408     // instantiated.  The backup agent will invoke backupAgentCreated() on the
18409     // activity manager to announce its creation.
18410     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18411         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18412         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18413
18414         IPackageManager pm = AppGlobals.getPackageManager();
18415         ApplicationInfo app = null;
18416         try {
18417             app = pm.getApplicationInfo(packageName, 0, userId);
18418         } catch (RemoteException e) {
18419             // can't happen; package manager is process-local
18420         }
18421         if (app == null) {
18422             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18423             return false;
18424         }
18425
18426         int oldBackupUid;
18427         int newBackupUid;
18428
18429         synchronized(this) {
18430             // !!! TODO: currently no check here that we're already bound
18431             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18432             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18433             synchronized (stats) {
18434                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18435             }
18436
18437             // Backup agent is now in use, its package can't be stopped.
18438             try {
18439                 AppGlobals.getPackageManager().setPackageStoppedState(
18440                         app.packageName, false, UserHandle.getUserId(app.uid));
18441             } catch (RemoteException e) {
18442             } catch (IllegalArgumentException e) {
18443                 Slog.w(TAG, "Failed trying to unstop package "
18444                         + app.packageName + ": " + e);
18445             }
18446
18447             BackupRecord r = new BackupRecord(ss, app, backupMode);
18448             ComponentName hostingName =
18449                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18450                             ? new ComponentName(app.packageName, app.backupAgentName)
18451                             : new ComponentName("android", "FullBackupAgent");
18452             // startProcessLocked() returns existing proc's record if it's already running
18453             ProcessRecord proc = startProcessLocked(app.processName, app,
18454                     false, 0, "backup", hostingName, false, false, false);
18455             if (proc == null) {
18456                 Slog.e(TAG, "Unable to start backup agent process " + r);
18457                 return false;
18458             }
18459
18460             // If the app is a regular app (uid >= 10000) and not the system server or phone
18461             // process, etc, then mark it as being in full backup so that certain calls to the
18462             // process can be blocked. This is not reset to false anywhere because we kill the
18463             // process after the full backup is done and the ProcessRecord will vaporize anyway.
18464             if (UserHandle.isApp(app.uid) &&
18465                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18466                 proc.inFullBackup = true;
18467             }
18468             r.app = proc;
18469             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18470             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18471             mBackupTarget = r;
18472             mBackupAppName = app.packageName;
18473
18474             // Try not to kill the process during backup
18475             updateOomAdjLocked(proc, true);
18476
18477             // If the process is already attached, schedule the creation of the backup agent now.
18478             // If it is not yet live, this will be done when it attaches to the framework.
18479             if (proc.thread != null) {
18480                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18481                 try {
18482                     proc.thread.scheduleCreateBackupAgent(app,
18483                             compatibilityInfoForPackageLocked(app), backupMode);
18484                 } catch (RemoteException e) {
18485                     // Will time out on the backup manager side
18486                 }
18487             } else {
18488                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18489             }
18490             // Invariants: at this point, the target app process exists and the application
18491             // is either already running or in the process of coming up.  mBackupTarget and
18492             // mBackupAppName describe the app, so that when it binds back to the AM we
18493             // know that it's scheduled for a backup-agent operation.
18494         }
18495
18496         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18497         if (oldBackupUid != -1) {
18498             js.removeBackingUpUid(oldBackupUid);
18499         }
18500         if (newBackupUid != -1) {
18501             js.addBackingUpUid(newBackupUid);
18502         }
18503
18504         return true;
18505     }
18506
18507     @Override
18508     public void clearPendingBackup() {
18509         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18510         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18511
18512         synchronized (this) {
18513             mBackupTarget = null;
18514             mBackupAppName = null;
18515         }
18516
18517         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18518         js.clearAllBackingUpUids();
18519     }
18520
18521     // A backup agent has just come up
18522     public void backupAgentCreated(String agentPackageName, IBinder agent) {
18523         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18524                 + " = " + agent);
18525
18526         synchronized(this) {
18527             if (!agentPackageName.equals(mBackupAppName)) {
18528                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18529                 return;
18530             }
18531         }
18532
18533         long oldIdent = Binder.clearCallingIdentity();
18534         try {
18535             IBackupManager bm = IBackupManager.Stub.asInterface(
18536                     ServiceManager.getService(Context.BACKUP_SERVICE));
18537             bm.agentConnected(agentPackageName, agent);
18538         } catch (RemoteException e) {
18539             // can't happen; the backup manager service is local
18540         } catch (Exception e) {
18541             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18542             e.printStackTrace();
18543         } finally {
18544             Binder.restoreCallingIdentity(oldIdent);
18545         }
18546     }
18547
18548     // done with this agent
18549     public void unbindBackupAgent(ApplicationInfo appInfo) {
18550         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18551         if (appInfo == null) {
18552             Slog.w(TAG, "unbind backup agent for null app");
18553             return;
18554         }
18555
18556         int oldBackupUid;
18557
18558         synchronized(this) {
18559             try {
18560                 if (mBackupAppName == null) {
18561                     Slog.w(TAG, "Unbinding backup agent with no active backup");
18562                     return;
18563                 }
18564
18565                 if (!mBackupAppName.equals(appInfo.packageName)) {
18566                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18567                     return;
18568                 }
18569
18570                 // Not backing this app up any more; reset its OOM adjustment
18571                 final ProcessRecord proc = mBackupTarget.app;
18572                 updateOomAdjLocked(proc, true);
18573                 proc.inFullBackup = false;
18574
18575                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18576
18577                 // If the app crashed during backup, 'thread' will be null here
18578                 if (proc.thread != null) {
18579                     try {
18580                         proc.thread.scheduleDestroyBackupAgent(appInfo,
18581                                 compatibilityInfoForPackageLocked(appInfo));
18582                     } catch (Exception e) {
18583                         Slog.e(TAG, "Exception when unbinding backup agent:");
18584                         e.printStackTrace();
18585                     }
18586                 }
18587             } finally {
18588                 mBackupTarget = null;
18589                 mBackupAppName = null;
18590             }
18591         }
18592
18593         if (oldBackupUid != -1) {
18594             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18595             js.removeBackingUpUid(oldBackupUid);
18596         }
18597     }
18598
18599     // =========================================================
18600     // BROADCASTS
18601     // =========================================================
18602
18603     private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18604         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18605             return false;
18606         }
18607         // Easy case -- we have the app's ProcessRecord.
18608         if (record != null) {
18609             return record.info.isInstantApp();
18610         }
18611         // Otherwise check with PackageManager.
18612         if (callerPackage == null) {
18613             Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18614             throw new IllegalArgumentException("Calling application did not provide package name");
18615         }
18616         mAppOpsService.checkPackage(uid, callerPackage);
18617         try {
18618             IPackageManager pm = AppGlobals.getPackageManager();
18619             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18620         } catch (RemoteException e) {
18621             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18622             return true;
18623         }
18624     }
18625
18626     boolean isPendingBroadcastProcessLocked(int pid) {
18627         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18628                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18629     }
18630
18631     void skipPendingBroadcastLocked(int pid) {
18632             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18633             for (BroadcastQueue queue : mBroadcastQueues) {
18634                 queue.skipPendingBroadcastLocked(pid);
18635             }
18636     }
18637
18638     // The app just attached; send any pending broadcasts that it should receive
18639     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18640         boolean didSomething = false;
18641         for (BroadcastQueue queue : mBroadcastQueues) {
18642             didSomething |= queue.sendPendingBroadcastsLocked(app);
18643         }
18644         return didSomething;
18645     }
18646
18647     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18648             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18649             int flags) {
18650         enforceNotIsolatedCaller("registerReceiver");
18651         ArrayList<Intent> stickyIntents = null;
18652         ProcessRecord callerApp = null;
18653         final boolean visibleToInstantApps
18654                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18655         int callingUid;
18656         int callingPid;
18657         boolean instantApp;
18658         synchronized(this) {
18659             if (caller != null) {
18660                 callerApp = getRecordForAppLocked(caller);
18661                 if (callerApp == null) {
18662                     throw new SecurityException(
18663                             "Unable to find app for caller " + caller
18664                             + " (pid=" + Binder.getCallingPid()
18665                             + ") when registering receiver " + receiver);
18666                 }
18667                 if (callerApp.info.uid != SYSTEM_UID &&
18668                         !callerApp.pkgList.containsKey(callerPackage) &&
18669                         !"android".equals(callerPackage)) {
18670                     throw new SecurityException("Given caller package " + callerPackage
18671                             + " is not running in process " + callerApp);
18672                 }
18673                 callingUid = callerApp.info.uid;
18674                 callingPid = callerApp.pid;
18675             } else {
18676                 callerPackage = null;
18677                 callingUid = Binder.getCallingUid();
18678                 callingPid = Binder.getCallingPid();
18679             }
18680
18681             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18682             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18683                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18684
18685             Iterator<String> actions = filter.actionsIterator();
18686             if (actions == null) {
18687                 ArrayList<String> noAction = new ArrayList<String>(1);
18688                 noAction.add(null);
18689                 actions = noAction.iterator();
18690             }
18691
18692             // Collect stickies of users
18693             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18694             while (actions.hasNext()) {
18695                 String action = actions.next();
18696                 for (int id : userIds) {
18697                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18698                     if (stickies != null) {
18699                         ArrayList<Intent> intents = stickies.get(action);
18700                         if (intents != null) {
18701                             if (stickyIntents == null) {
18702                                 stickyIntents = new ArrayList<Intent>();
18703                             }
18704                             stickyIntents.addAll(intents);
18705                         }
18706                     }
18707                 }
18708             }
18709         }
18710
18711         ArrayList<Intent> allSticky = null;
18712         if (stickyIntents != null) {
18713             final ContentResolver resolver = mContext.getContentResolver();
18714             // Look for any matching sticky broadcasts...
18715             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18716                 Intent intent = stickyIntents.get(i);
18717                 // Don't provided intents that aren't available to instant apps.
18718                 if (instantApp &&
18719                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18720                     continue;
18721                 }
18722                 // If intent has scheme "content", it will need to acccess
18723                 // provider that needs to lock mProviderMap in ActivityThread
18724                 // and also it may need to wait application response, so we
18725                 // cannot lock ActivityManagerService here.
18726                 if (filter.match(resolver, intent, true, TAG) >= 0) {
18727                     if (allSticky == null) {
18728                         allSticky = new ArrayList<Intent>();
18729                     }
18730                     allSticky.add(intent);
18731                 }
18732             }
18733         }
18734
18735         // The first sticky in the list is returned directly back to the client.
18736         Intent sticky = allSticky != null ? allSticky.get(0) : null;
18737         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18738         if (receiver == null) {
18739             return sticky;
18740         }
18741
18742         synchronized (this) {
18743             if (callerApp != null && (callerApp.thread == null
18744                     || callerApp.thread.asBinder() != caller.asBinder())) {
18745                 // Original caller already died
18746                 return null;
18747             }
18748             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18749             if (rl == null) {
18750                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18751                         userId, receiver);
18752                 if (rl.app != null) {
18753                     rl.app.receivers.add(rl);
18754                 } else {
18755                     try {
18756                         receiver.asBinder().linkToDeath(rl, 0);
18757                     } catch (RemoteException e) {
18758                         return sticky;
18759                     }
18760                     rl.linkedToDeath = true;
18761                 }
18762                 mRegisteredReceivers.put(receiver.asBinder(), rl);
18763             } else if (rl.uid != callingUid) {
18764                 throw new IllegalArgumentException(
18765                         "Receiver requested to register for uid " + callingUid
18766                         + " was previously registered for uid " + rl.uid
18767                         + " callerPackage is " + callerPackage);
18768             } else if (rl.pid != callingPid) {
18769                 throw new IllegalArgumentException(
18770                         "Receiver requested to register for pid " + callingPid
18771                         + " was previously registered for pid " + rl.pid
18772                         + " callerPackage is " + callerPackage);
18773             } else if (rl.userId != userId) {
18774                 throw new IllegalArgumentException(
18775                         "Receiver requested to register for user " + userId
18776                         + " was previously registered for user " + rl.userId
18777                         + " callerPackage is " + callerPackage);
18778             }
18779             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18780                     permission, callingUid, userId, instantApp, visibleToInstantApps);
18781             rl.add(bf);
18782             if (!bf.debugCheck()) {
18783                 Slog.w(TAG, "==> For Dynamic broadcast");
18784             }
18785             mReceiverResolver.addFilter(bf);
18786
18787             // Enqueue broadcasts for all existing stickies that match
18788             // this filter.
18789             if (allSticky != null) {
18790                 ArrayList receivers = new ArrayList();
18791                 receivers.add(bf);
18792
18793                 final int stickyCount = allSticky.size();
18794                 for (int i = 0; i < stickyCount; i++) {
18795                     Intent intent = allSticky.get(i);
18796                     BroadcastQueue queue = broadcastQueueForIntent(intent);
18797                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18798                             null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18799                             null, 0, null, null, false, true, true, -1);
18800                     queue.enqueueParallelBroadcastLocked(r);
18801                     queue.scheduleBroadcastsLocked();
18802                 }
18803             }
18804
18805             return sticky;
18806         }
18807     }
18808
18809     public void unregisterReceiver(IIntentReceiver receiver) {
18810         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18811
18812         final long origId = Binder.clearCallingIdentity();
18813         try {
18814             boolean doTrim = false;
18815
18816             synchronized(this) {
18817                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18818                 if (rl != null) {
18819                     final BroadcastRecord r = rl.curBroadcast;
18820                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18821                         final boolean doNext = r.queue.finishReceiverLocked(
18822                                 r, r.resultCode, r.resultData, r.resultExtras,
18823                                 r.resultAbort, false);
18824                         if (doNext) {
18825                             doTrim = true;
18826                             r.queue.processNextBroadcast(false);
18827                         }
18828                     }
18829
18830                     if (rl.app != null) {
18831                         rl.app.receivers.remove(rl);
18832                     }
18833                     removeReceiverLocked(rl);
18834                     if (rl.linkedToDeath) {
18835                         rl.linkedToDeath = false;
18836                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
18837                     }
18838                 }
18839             }
18840
18841             // If we actually concluded any broadcasts, we might now be able
18842             // to trim the recipients' apps from our working set
18843             if (doTrim) {
18844                 trimApplications();
18845                 return;
18846             }
18847
18848         } finally {
18849             Binder.restoreCallingIdentity(origId);
18850         }
18851     }
18852
18853     void removeReceiverLocked(ReceiverList rl) {
18854         mRegisteredReceivers.remove(rl.receiver.asBinder());
18855         for (int i = rl.size() - 1; i >= 0; i--) {
18856             mReceiverResolver.removeFilter(rl.get(i));
18857         }
18858     }
18859
18860     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18861         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18862             ProcessRecord r = mLruProcesses.get(i);
18863             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18864                 try {
18865                     r.thread.dispatchPackageBroadcast(cmd, packages);
18866                 } catch (RemoteException ex) {
18867                 }
18868             }
18869         }
18870     }
18871
18872     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18873             int callingUid, int[] users) {
18874         // TODO: come back and remove this assumption to triage all broadcasts
18875         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18876
18877         List<ResolveInfo> receivers = null;
18878         try {
18879             HashSet<ComponentName> singleUserReceivers = null;
18880             boolean scannedFirstReceivers = false;
18881             for (int user : users) {
18882                 // Skip users that have Shell restrictions, with exception of always permitted
18883                 // Shell broadcasts
18884                 if (callingUid == SHELL_UID
18885                         && mUserController.hasUserRestriction(
18886                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18887                         && !isPermittedShellBroadcast(intent)) {
18888                     continue;
18889                 }
18890                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18891                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18892                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18893                     // If this is not the system user, we need to check for
18894                     // any receivers that should be filtered out.
18895                     for (int i=0; i<newReceivers.size(); i++) {
18896                         ResolveInfo ri = newReceivers.get(i);
18897                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18898                             newReceivers.remove(i);
18899                             i--;
18900                         }
18901                     }
18902                 }
18903                 if (newReceivers != null && newReceivers.size() == 0) {
18904                     newReceivers = null;
18905                 }
18906                 if (receivers == null) {
18907                     receivers = newReceivers;
18908                 } else if (newReceivers != null) {
18909                     // We need to concatenate the additional receivers
18910                     // found with what we have do far.  This would be easy,
18911                     // but we also need to de-dup any receivers that are
18912                     // singleUser.
18913                     if (!scannedFirstReceivers) {
18914                         // Collect any single user receivers we had already retrieved.
18915                         scannedFirstReceivers = true;
18916                         for (int i=0; i<receivers.size(); i++) {
18917                             ResolveInfo ri = receivers.get(i);
18918                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18919                                 ComponentName cn = new ComponentName(
18920                                         ri.activityInfo.packageName, ri.activityInfo.name);
18921                                 if (singleUserReceivers == null) {
18922                                     singleUserReceivers = new HashSet<ComponentName>();
18923                                 }
18924                                 singleUserReceivers.add(cn);
18925                             }
18926                         }
18927                     }
18928                     // Add the new results to the existing results, tracking
18929                     // and de-dupping single user receivers.
18930                     for (int i=0; i<newReceivers.size(); i++) {
18931                         ResolveInfo ri = newReceivers.get(i);
18932                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18933                             ComponentName cn = new ComponentName(
18934                                     ri.activityInfo.packageName, ri.activityInfo.name);
18935                             if (singleUserReceivers == null) {
18936                                 singleUserReceivers = new HashSet<ComponentName>();
18937                             }
18938                             if (!singleUserReceivers.contains(cn)) {
18939                                 singleUserReceivers.add(cn);
18940                                 receivers.add(ri);
18941                             }
18942                         } else {
18943                             receivers.add(ri);
18944                         }
18945                     }
18946                 }
18947             }
18948         } catch (RemoteException ex) {
18949             // pm is in same process, this will never happen.
18950         }
18951         return receivers;
18952     }
18953
18954     private boolean isPermittedShellBroadcast(Intent intent) {
18955         // remote bugreport should always be allowed to be taken
18956         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18957     }
18958
18959     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18960             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18961         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18962             // Don't yell about broadcasts sent via shell
18963             return;
18964         }
18965
18966         final String action = intent.getAction();
18967         if (isProtectedBroadcast
18968                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18969                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18970                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
18971                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18972                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18973                 || Intent.ACTION_MASTER_CLEAR.equals(action)
18974                 || Intent.ACTION_FACTORY_RESET.equals(action)
18975                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18976                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18977                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18978                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18979                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18980                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18981                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18982             // Broadcast is either protected, or it's a public action that
18983             // we've relaxed, so it's fine for system internals to send.
18984             return;
18985         }
18986
18987         // This broadcast may be a problem...  but there are often system components that
18988         // want to send an internal broadcast to themselves, which is annoying to have to
18989         // explicitly list each action as a protected broadcast, so we will check for that
18990         // one safe case and allow it: an explicit broadcast, only being received by something
18991         // that has protected itself.
18992         if (receivers != null && receivers.size() > 0
18993                 && (intent.getPackage() != null || intent.getComponent() != null)) {
18994             boolean allProtected = true;
18995             for (int i = receivers.size()-1; i >= 0; i--) {
18996                 Object target = receivers.get(i);
18997                 if (target instanceof ResolveInfo) {
18998                     ResolveInfo ri = (ResolveInfo)target;
18999                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19000                         allProtected = false;
19001                         break;
19002                     }
19003                 } else {
19004                     BroadcastFilter bf = (BroadcastFilter)target;
19005                     if (bf.requiredPermission == null) {
19006                         allProtected = false;
19007                         break;
19008                     }
19009                 }
19010             }
19011             if (allProtected) {
19012                 // All safe!
19013                 return;
19014             }
19015         }
19016
19017         // The vast majority of broadcasts sent from system internals
19018         // should be protected to avoid security holes, so yell loudly
19019         // to ensure we examine these cases.
19020         if (callerApp != null) {
19021             Log.wtf(TAG, "Sending non-protected broadcast " + action
19022                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19023                     new Throwable());
19024         } else {
19025             Log.wtf(TAG, "Sending non-protected broadcast " + action
19026                             + " from system uid " + UserHandle.formatUid(callingUid)
19027                             + " pkg " + callerPackage,
19028                     new Throwable());
19029         }
19030     }
19031
19032     final int broadcastIntentLocked(ProcessRecord callerApp,
19033             String callerPackage, Intent intent, String resolvedType,
19034             IIntentReceiver resultTo, int resultCode, String resultData,
19035             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19036             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19037         intent = new Intent(intent);
19038
19039         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19040         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19041         if (callerInstantApp) {
19042             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19043         }
19044
19045         // By default broadcasts do not go to stopped apps.
19046         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19047
19048         // If we have not finished booting, don't allow this to launch new processes.
19049         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19050             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19051         }
19052
19053         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19054                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19055                 + " ordered=" + ordered + " userid=" + userId);
19056         if ((resultTo != null) && !ordered) {
19057             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19058         }
19059
19060         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19061                 ALLOW_NON_FULL, "broadcast", callerPackage);
19062
19063         // Make sure that the user who is receiving this broadcast is running.
19064         // If not, we will just skip it. Make an exception for shutdown broadcasts
19065         // and upgrade steps.
19066
19067         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19068             if ((callingUid != SYSTEM_UID
19069                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19070                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19071                 Slog.w(TAG, "Skipping broadcast of " + intent
19072                         + ": user " + userId + " is stopped");
19073                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19074             }
19075         }
19076
19077         BroadcastOptions brOptions = null;
19078         if (bOptions != null) {
19079             brOptions = new BroadcastOptions(bOptions);
19080             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19081                 // See if the caller is allowed to do this.  Note we are checking against
19082                 // the actual real caller (not whoever provided the operation as say a
19083                 // PendingIntent), because that who is actually supplied the arguments.
19084                 if (checkComponentPermission(
19085                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19086                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19087                         != PackageManager.PERMISSION_GRANTED) {
19088                     String msg = "Permission Denial: " + intent.getAction()
19089                             + " broadcast from " + callerPackage + " (pid=" + callingPid
19090                             + ", uid=" + callingUid + ")"
19091                             + " requires "
19092                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19093                     Slog.w(TAG, msg);
19094                     throw new SecurityException(msg);
19095                 }
19096             }
19097         }
19098
19099         // Verify that protected broadcasts are only being sent by system code,
19100         // and that system code is only sending protected broadcasts.
19101         final String action = intent.getAction();
19102         final boolean isProtectedBroadcast;
19103         try {
19104             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19105         } catch (RemoteException e) {
19106             Slog.w(TAG, "Remote exception", e);
19107             return ActivityManager.BROADCAST_SUCCESS;
19108         }
19109
19110         final boolean isCallerSystem;
19111         switch (UserHandle.getAppId(callingUid)) {
19112             case ROOT_UID:
19113             case SYSTEM_UID:
19114             case PHONE_UID:
19115             case BLUETOOTH_UID:
19116             case NFC_UID:
19117                 isCallerSystem = true;
19118                 break;
19119             default:
19120                 isCallerSystem = (callerApp != null) && callerApp.persistent;
19121                 break;
19122         }
19123
19124         // First line security check before anything else: stop non-system apps from
19125         // sending protected broadcasts.
19126         if (!isCallerSystem) {
19127             if (isProtectedBroadcast) {
19128                 String msg = "Permission Denial: not allowed to send broadcast "
19129                         + action + " from pid="
19130                         + callingPid + ", uid=" + callingUid;
19131                 Slog.w(TAG, msg);
19132                 throw new SecurityException(msg);
19133
19134             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19135                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19136                 // Special case for compatibility: we don't want apps to send this,
19137                 // but historically it has not been protected and apps may be using it
19138                 // to poke their own app widget.  So, instead of making it protected,
19139                 // just limit it to the caller.
19140                 if (callerPackage == null) {
19141                     String msg = "Permission Denial: not allowed to send broadcast "
19142                             + action + " from unknown caller.";
19143                     Slog.w(TAG, msg);
19144                     throw new SecurityException(msg);
19145                 } else if (intent.getComponent() != null) {
19146                     // They are good enough to send to an explicit component...  verify
19147                     // it is being sent to the calling app.
19148                     if (!intent.getComponent().getPackageName().equals(
19149                             callerPackage)) {
19150                         String msg = "Permission Denial: not allowed to send broadcast "
19151                                 + action + " to "
19152                                 + intent.getComponent().getPackageName() + " from "
19153                                 + callerPackage;
19154                         Slog.w(TAG, msg);
19155                         throw new SecurityException(msg);
19156                     }
19157                 } else {
19158                     // Limit broadcast to their own package.
19159                     intent.setPackage(callerPackage);
19160                 }
19161             }
19162         }
19163
19164         if (action != null) {
19165             if (getBackgroundLaunchBroadcasts().contains(action)) {
19166                 if (DEBUG_BACKGROUND_CHECK) {
19167                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19168                 }
19169                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19170             }
19171
19172             switch (action) {
19173                 case Intent.ACTION_UID_REMOVED:
19174                 case Intent.ACTION_PACKAGE_REMOVED:
19175                 case Intent.ACTION_PACKAGE_CHANGED:
19176                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19177                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19178                 case Intent.ACTION_PACKAGES_SUSPENDED:
19179                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19180                     // Handle special intents: if this broadcast is from the package
19181                     // manager about a package being removed, we need to remove all of
19182                     // its activities from the history stack.
19183                     if (checkComponentPermission(
19184                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19185                             callingPid, callingUid, -1, true)
19186                             != PackageManager.PERMISSION_GRANTED) {
19187                         String msg = "Permission Denial: " + intent.getAction()
19188                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
19189                                 + ", uid=" + callingUid + ")"
19190                                 + " requires "
19191                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19192                         Slog.w(TAG, msg);
19193                         throw new SecurityException(msg);
19194                     }
19195                     switch (action) {
19196                         case Intent.ACTION_UID_REMOVED:
19197                             final int uid = getUidFromIntent(intent);
19198                             if (uid >= 0) {
19199                                 mBatteryStatsService.removeUid(uid);
19200                                 mAppOpsService.uidRemoved(uid);
19201                             }
19202                             break;
19203                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19204                             // If resources are unavailable just force stop all those packages
19205                             // and flush the attribute cache as well.
19206                             String list[] =
19207                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19208                             if (list != null && list.length > 0) {
19209                                 for (int i = 0; i < list.length; i++) {
19210                                     forceStopPackageLocked(list[i], -1, false, true, true,
19211                                             false, false, userId, "storage unmount");
19212                                 }
19213                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19214                                 sendPackageBroadcastLocked(
19215                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19216                                         list, userId);
19217                             }
19218                             break;
19219                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19220                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19221                             break;
19222                         case Intent.ACTION_PACKAGE_REMOVED:
19223                         case Intent.ACTION_PACKAGE_CHANGED:
19224                             Uri data = intent.getData();
19225                             String ssp;
19226                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19227                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19228                                 final boolean replacing =
19229                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19230                                 final boolean killProcess =
19231                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19232                                 final boolean fullUninstall = removed && !replacing;
19233                                 if (removed) {
19234                                     if (killProcess) {
19235                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
19236                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19237                                                 false, true, true, false, fullUninstall, userId,
19238                                                 removed ? "pkg removed" : "pkg changed");
19239                                     }
19240                                     final int cmd = killProcess
19241                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
19242                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19243                                     sendPackageBroadcastLocked(cmd,
19244                                             new String[] {ssp}, userId);
19245                                     if (fullUninstall) {
19246                                         mAppOpsService.packageRemoved(
19247                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19248
19249                                         // Remove all permissions granted from/to this package
19250                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
19251
19252                                         removeTasksByPackageNameLocked(ssp, userId);
19253
19254                                         mServices.forceStopPackageLocked(ssp, userId);
19255
19256                                         // Hide the "unsupported display" dialog if necessary.
19257                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19258                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19259                                             mUnsupportedDisplaySizeDialog.dismiss();
19260                                             mUnsupportedDisplaySizeDialog = null;
19261                                         }
19262                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
19263                                         mBatteryStatsService.notePackageUninstalled(ssp);
19264                                     }
19265                                 } else {
19266                                     if (killProcess) {
19267                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
19268                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19269                                                 userId, ProcessList.INVALID_ADJ,
19270                                                 false, true, true, false, "change " + ssp);
19271                                     }
19272                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19273                                             intent.getStringArrayExtra(
19274                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19275                                 }
19276                             }
19277                             break;
19278                         case Intent.ACTION_PACKAGES_SUSPENDED:
19279                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
19280                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19281                                     intent.getAction());
19282                             final String[] packageNames = intent.getStringArrayExtra(
19283                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
19284                             final int userHandle = intent.getIntExtra(
19285                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19286
19287                             synchronized(ActivityManagerService.this) {
19288                                 mRecentTasks.onPackagesSuspendedChanged(
19289                                         packageNames, suspended, userHandle);
19290                             }
19291                             break;
19292                     }
19293                     break;
19294                 case Intent.ACTION_PACKAGE_REPLACED:
19295                 {
19296                     final Uri data = intent.getData();
19297                     final String ssp;
19298                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19299                         ApplicationInfo aInfo = null;
19300                         try {
19301                             aInfo = AppGlobals.getPackageManager()
19302                                     .getApplicationInfo(ssp, 0 /*flags*/, userId);
19303                         } catch (RemoteException ignore) {}
19304                         if (aInfo == null) {
19305                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19306                                     + " ssp=" + ssp + " data=" + data);
19307                             return ActivityManager.BROADCAST_SUCCESS;
19308                         }
19309                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19310                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19311                                 new String[] {ssp}, userId);
19312                     }
19313                     break;
19314                 }
19315                 case Intent.ACTION_PACKAGE_ADDED:
19316                 {
19317                     // Special case for adding a package: by default turn on compatibility mode.
19318                     Uri data = intent.getData();
19319                     String ssp;
19320                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19321                         final boolean replacing =
19322                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19323                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19324
19325                         try {
19326                             ApplicationInfo ai = AppGlobals.getPackageManager().
19327                                     getApplicationInfo(ssp, 0, 0);
19328                             mBatteryStatsService.notePackageInstalled(ssp,
19329                                     ai != null ? ai.versionCode : 0);
19330                         } catch (RemoteException e) {
19331                         }
19332                     }
19333                     break;
19334                 }
19335                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19336                 {
19337                     Uri data = intent.getData();
19338                     String ssp;
19339                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19340                         // Hide the "unsupported display" dialog if necessary.
19341                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19342                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19343                             mUnsupportedDisplaySizeDialog.dismiss();
19344                             mUnsupportedDisplaySizeDialog = null;
19345                         }
19346                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
19347                     }
19348                     break;
19349                 }
19350                 case Intent.ACTION_TIMEZONE_CHANGED:
19351                     // If this is the time zone changed action, queue up a message that will reset
19352                     // the timezone of all currently running processes. This message will get
19353                     // queued up before the broadcast happens.
19354                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19355                     break;
19356                 case Intent.ACTION_TIME_CHANGED:
19357                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19358                     // the tri-state value it may contain and "unknown".
19359                     // For convenience we re-use the Intent extra values.
19360                     final int NO_EXTRA_VALUE_FOUND = -1;
19361                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19362                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19363                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
19364                     // Only send a message if the time preference is available.
19365                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19366                         Message updateTimePreferenceMsg =
19367                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19368                                         timeFormatPreferenceMsgValue, 0);
19369                         mHandler.sendMessage(updateTimePreferenceMsg);
19370                     }
19371                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19372                     synchronized (stats) {
19373                         stats.noteCurrentTimeChangedLocked();
19374                     }
19375                     break;
19376                 case Intent.ACTION_CLEAR_DNS_CACHE:
19377                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19378                     break;
19379                 case Proxy.PROXY_CHANGE_ACTION:
19380                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19381                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19382                     break;
19383                 case android.hardware.Camera.ACTION_NEW_PICTURE:
19384                 case android.hardware.Camera.ACTION_NEW_VIDEO:
19385                     // In N we just turned these off; in O we are turing them back on partly,
19386                     // only for registered receivers.  This will still address the main problem
19387                     // (a spam of apps waking up when a picture is taken putting significant
19388                     // memory pressure on the system at a bad point), while still allowing apps
19389                     // that are already actively running to know about this happening.
19390                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19391                     break;
19392                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19393                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19394                     break;
19395                 case "com.android.launcher.action.INSTALL_SHORTCUT":
19396                     // As of O, we no longer support this broadcasts, even for pre-O apps.
19397                     // Apps should now be using ShortcutManager.pinRequestShortcut().
19398                     Log.w(TAG, "Broadcast " + action
19399                             + " no longer supported. It will not be delivered.");
19400                     return ActivityManager.BROADCAST_SUCCESS;
19401             }
19402
19403             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19404                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19405                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19406                 final int uid = getUidFromIntent(intent);
19407                 if (uid != -1) {
19408                     final UidRecord uidRec = mActiveUids.get(uid);
19409                     if (uidRec != null) {
19410                         uidRec.updateHasInternetPermission();
19411                     }
19412                 }
19413             }
19414         }
19415
19416         // Add to the sticky list if requested.
19417         if (sticky) {
19418             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19419                     callingPid, callingUid)
19420                     != PackageManager.PERMISSION_GRANTED) {
19421                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19422                         + callingPid + ", uid=" + callingUid
19423                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19424                 Slog.w(TAG, msg);
19425                 throw new SecurityException(msg);
19426             }
19427             if (requiredPermissions != null && requiredPermissions.length > 0) {
19428                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19429                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
19430                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19431             }
19432             if (intent.getComponent() != null) {
19433                 throw new SecurityException(
19434                         "Sticky broadcasts can't target a specific component");
19435             }
19436             // We use userId directly here, since the "all" target is maintained
19437             // as a separate set of sticky broadcasts.
19438             if (userId != UserHandle.USER_ALL) {
19439                 // But first, if this is not a broadcast to all users, then
19440                 // make sure it doesn't conflict with an existing broadcast to
19441                 // all users.
19442                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19443                         UserHandle.USER_ALL);
19444                 if (stickies != null) {
19445                     ArrayList<Intent> list = stickies.get(intent.getAction());
19446                     if (list != null) {
19447                         int N = list.size();
19448                         int i;
19449                         for (i=0; i<N; i++) {
19450                             if (intent.filterEquals(list.get(i))) {
19451                                 throw new IllegalArgumentException(
19452                                         "Sticky broadcast " + intent + " for user "
19453                                         + userId + " conflicts with existing global broadcast");
19454                             }
19455                         }
19456                     }
19457                 }
19458             }
19459             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19460             if (stickies == null) {
19461                 stickies = new ArrayMap<>();
19462                 mStickyBroadcasts.put(userId, stickies);
19463             }
19464             ArrayList<Intent> list = stickies.get(intent.getAction());
19465             if (list == null) {
19466                 list = new ArrayList<>();
19467                 stickies.put(intent.getAction(), list);
19468             }
19469             final int stickiesCount = list.size();
19470             int i;
19471             for (i = 0; i < stickiesCount; i++) {
19472                 if (intent.filterEquals(list.get(i))) {
19473                     // This sticky already exists, replace it.
19474                     list.set(i, new Intent(intent));
19475                     break;
19476                 }
19477             }
19478             if (i >= stickiesCount) {
19479                 list.add(new Intent(intent));
19480             }
19481         }
19482
19483         int[] users;
19484         if (userId == UserHandle.USER_ALL) {
19485             // Caller wants broadcast to go to all started users.
19486             users = mUserController.getStartedUserArrayLocked();
19487         } else {
19488             // Caller wants broadcast to go to one specific user.
19489             users = new int[] {userId};
19490         }
19491
19492         // Figure out who all will receive this broadcast.
19493         List receivers = null;
19494         List<BroadcastFilter> registeredReceivers = null;
19495         // Need to resolve the intent to interested receivers...
19496         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19497                  == 0) {
19498             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19499         }
19500         if (intent.getComponent() == null) {
19501             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19502                 // Query one target user at a time, excluding shell-restricted users
19503                 for (int i = 0; i < users.length; i++) {
19504                     if (mUserController.hasUserRestriction(
19505                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19506                         continue;
19507                     }
19508                     List<BroadcastFilter> registeredReceiversForUser =
19509                             mReceiverResolver.queryIntent(intent,
19510                                     resolvedType, false /*defaultOnly*/, users[i]);
19511                     if (registeredReceivers == null) {
19512                         registeredReceivers = registeredReceiversForUser;
19513                     } else if (registeredReceiversForUser != null) {
19514                         registeredReceivers.addAll(registeredReceiversForUser);
19515                     }
19516                 }
19517             } else {
19518                 registeredReceivers = mReceiverResolver.queryIntent(intent,
19519                         resolvedType, false /*defaultOnly*/, userId);
19520             }
19521         }
19522
19523         final boolean replacePending =
19524                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19525
19526         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19527                 + " replacePending=" + replacePending);
19528
19529         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19530         if (!ordered && NR > 0) {
19531             // If we are not serializing this broadcast, then send the
19532             // registered receivers separately so they don't wait for the
19533             // components to be launched.
19534             if (isCallerSystem) {
19535                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19536                         isProtectedBroadcast, registeredReceivers);
19537             }
19538             final BroadcastQueue queue = broadcastQueueForIntent(intent);
19539             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19540                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19541                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19542                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19543             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19544             final boolean replaced = replacePending
19545                     && (queue.replaceParallelBroadcastLocked(r) != null);
19546             // Note: We assume resultTo is null for non-ordered broadcasts.
19547             if (!replaced) {
19548                 queue.enqueueParallelBroadcastLocked(r);
19549                 queue.scheduleBroadcastsLocked();
19550             }
19551             registeredReceivers = null;
19552             NR = 0;
19553         }
19554
19555         // Merge into one list.
19556         int ir = 0;
19557         if (receivers != null) {
19558             // A special case for PACKAGE_ADDED: do not allow the package
19559             // being added to see this broadcast.  This prevents them from
19560             // using this as a back door to get run as soon as they are
19561             // installed.  Maybe in the future we want to have a special install
19562             // broadcast or such for apps, but we'd like to deliberately make
19563             // this decision.
19564             String skipPackages[] = null;
19565             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19566                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19567                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19568                 Uri data = intent.getData();
19569                 if (data != null) {
19570                     String pkgName = data.getSchemeSpecificPart();
19571                     if (pkgName != null) {
19572                         skipPackages = new String[] { pkgName };
19573                     }
19574                 }
19575             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19576                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19577             }
19578             if (skipPackages != null && (skipPackages.length > 0)) {
19579                 for (String skipPackage : skipPackages) {
19580                     if (skipPackage != null) {
19581                         int NT = receivers.size();
19582                         for (int it=0; it<NT; it++) {
19583                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
19584                             if (curt.activityInfo.packageName.equals(skipPackage)) {
19585                                 receivers.remove(it);
19586                                 it--;
19587                                 NT--;
19588                             }
19589                         }
19590                     }
19591                 }
19592             }
19593
19594             int NT = receivers != null ? receivers.size() : 0;
19595             int it = 0;
19596             ResolveInfo curt = null;
19597             BroadcastFilter curr = null;
19598             while (it < NT && ir < NR) {
19599                 if (curt == null) {
19600                     curt = (ResolveInfo)receivers.get(it);
19601                 }
19602                 if (curr == null) {
19603                     curr = registeredReceivers.get(ir);
19604                 }
19605                 if (curr.getPriority() >= curt.priority) {
19606                     // Insert this broadcast record into the final list.
19607                     receivers.add(it, curr);
19608                     ir++;
19609                     curr = null;
19610                     it++;
19611                     NT++;
19612                 } else {
19613                     // Skip to the next ResolveInfo in the final list.
19614                     it++;
19615                     curt = null;
19616                 }
19617             }
19618         }
19619         while (ir < NR) {
19620             if (receivers == null) {
19621                 receivers = new ArrayList();
19622             }
19623             receivers.add(registeredReceivers.get(ir));
19624             ir++;
19625         }
19626
19627         if (isCallerSystem) {
19628             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19629                     isProtectedBroadcast, receivers);
19630         }
19631
19632         if ((receivers != null && receivers.size() > 0)
19633                 || resultTo != null) {
19634             BroadcastQueue queue = broadcastQueueForIntent(intent);
19635             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19636                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19637                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19638                     resultData, resultExtras, ordered, sticky, false, userId);
19639
19640             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19641                     + ": prev had " + queue.mOrderedBroadcasts.size());
19642             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19643                     "Enqueueing broadcast " + r.intent.getAction());
19644
19645             final BroadcastRecord oldRecord =
19646                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19647             if (oldRecord != null) {
19648                 // Replaced, fire the result-to receiver.
19649                 if (oldRecord.resultTo != null) {
19650                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19651                     try {
19652                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19653                                 oldRecord.intent,
19654                                 Activity.RESULT_CANCELED, null, null,
19655                                 false, false, oldRecord.userId);
19656                     } catch (RemoteException e) {
19657                         Slog.w(TAG, "Failure ["
19658                                 + queue.mQueueName + "] sending broadcast result of "
19659                                 + intent, e);
19660
19661                     }
19662                 }
19663             } else {
19664                 queue.enqueueOrderedBroadcastLocked(r);
19665                 queue.scheduleBroadcastsLocked();
19666             }
19667         } else {
19668             // There was nobody interested in the broadcast, but we still want to record
19669             // that it happened.
19670             if (intent.getComponent() == null && intent.getPackage() == null
19671                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19672                 // This was an implicit broadcast... let's record it for posterity.
19673                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19674             }
19675         }
19676
19677         return ActivityManager.BROADCAST_SUCCESS;
19678     }
19679
19680     /**
19681      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19682      */
19683     private int getUidFromIntent(Intent intent) {
19684         if (intent == null) {
19685             return -1;
19686         }
19687         final Bundle intentExtras = intent.getExtras();
19688         return intent.hasExtra(Intent.EXTRA_UID)
19689                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19690     }
19691
19692     final void rotateBroadcastStatsIfNeededLocked() {
19693         final long now = SystemClock.elapsedRealtime();
19694         if (mCurBroadcastStats == null ||
19695                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19696             mLastBroadcastStats = mCurBroadcastStats;
19697             if (mLastBroadcastStats != null) {
19698                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19699                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19700             }
19701             mCurBroadcastStats = new BroadcastStats();
19702         }
19703     }
19704
19705     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19706             int skipCount, long dispatchTime) {
19707         rotateBroadcastStatsIfNeededLocked();
19708         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19709     }
19710
19711     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19712         rotateBroadcastStatsIfNeededLocked();
19713         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19714     }
19715
19716     final Intent verifyBroadcastLocked(Intent intent) {
19717         // Refuse possible leaked file descriptors
19718         if (intent != null && intent.hasFileDescriptors() == true) {
19719             throw new IllegalArgumentException("File descriptors passed in Intent");
19720         }
19721
19722         int flags = intent.getFlags();
19723
19724         if (!mProcessesReady) {
19725             // if the caller really truly claims to know what they're doing, go
19726             // ahead and allow the broadcast without launching any receivers
19727             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19728                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19729             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19730                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19731                         + " before boot completion");
19732                 throw new IllegalStateException("Cannot broadcast before boot completed");
19733             }
19734         }
19735
19736         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19737             throw new IllegalArgumentException(
19738                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19739         }
19740
19741         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19742             switch (Binder.getCallingUid()) {
19743                 case ROOT_UID:
19744                 case SHELL_UID:
19745                     break;
19746                 default:
19747                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19748                             + Binder.getCallingUid());
19749                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19750                     break;
19751             }
19752         }
19753
19754         return intent;
19755     }
19756
19757     public final int broadcastIntent(IApplicationThread caller,
19758             Intent intent, String resolvedType, IIntentReceiver resultTo,
19759             int resultCode, String resultData, Bundle resultExtras,
19760             String[] requiredPermissions, int appOp, Bundle bOptions,
19761             boolean serialized, boolean sticky, int userId) {
19762         enforceNotIsolatedCaller("broadcastIntent");
19763         synchronized(this) {
19764             intent = verifyBroadcastLocked(intent);
19765
19766             final ProcessRecord callerApp = getRecordForAppLocked(caller);
19767             final int callingPid = Binder.getCallingPid();
19768             final int callingUid = Binder.getCallingUid();
19769             final long origId = Binder.clearCallingIdentity();
19770             int res = broadcastIntentLocked(callerApp,
19771                     callerApp != null ? callerApp.info.packageName : null,
19772                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19773                     requiredPermissions, appOp, bOptions, serialized, sticky,
19774                     callingPid, callingUid, userId);
19775             Binder.restoreCallingIdentity(origId);
19776             return res;
19777         }
19778     }
19779
19780
19781     int broadcastIntentInPackage(String packageName, int uid,
19782             Intent intent, String resolvedType, IIntentReceiver resultTo,
19783             int resultCode, String resultData, Bundle resultExtras,
19784             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19785             int userId) {
19786         synchronized(this) {
19787             intent = verifyBroadcastLocked(intent);
19788
19789             final long origId = Binder.clearCallingIdentity();
19790             String[] requiredPermissions = requiredPermission == null ? null
19791                     : new String[] {requiredPermission};
19792             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19793                     resultTo, resultCode, resultData, resultExtras,
19794                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19795                     sticky, -1, uid, userId);
19796             Binder.restoreCallingIdentity(origId);
19797             return res;
19798         }
19799     }
19800
19801     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19802         // Refuse possible leaked file descriptors
19803         if (intent != null && intent.hasFileDescriptors() == true) {
19804             throw new IllegalArgumentException("File descriptors passed in Intent");
19805         }
19806
19807         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19808                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19809
19810         synchronized(this) {
19811             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19812                     != PackageManager.PERMISSION_GRANTED) {
19813                 String msg = "Permission Denial: unbroadcastIntent() from pid="
19814                         + Binder.getCallingPid()
19815                         + ", uid=" + Binder.getCallingUid()
19816                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19817                 Slog.w(TAG, msg);
19818                 throw new SecurityException(msg);
19819             }
19820             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19821             if (stickies != null) {
19822                 ArrayList<Intent> list = stickies.get(intent.getAction());
19823                 if (list != null) {
19824                     int N = list.size();
19825                     int i;
19826                     for (i=0; i<N; i++) {
19827                         if (intent.filterEquals(list.get(i))) {
19828                             list.remove(i);
19829                             break;
19830                         }
19831                     }
19832                     if (list.size() <= 0) {
19833                         stickies.remove(intent.getAction());
19834                     }
19835                 }
19836                 if (stickies.size() <= 0) {
19837                     mStickyBroadcasts.remove(userId);
19838                 }
19839             }
19840         }
19841     }
19842
19843     void backgroundServicesFinishedLocked(int userId) {
19844         for (BroadcastQueue queue : mBroadcastQueues) {
19845             queue.backgroundServicesFinishedLocked(userId);
19846         }
19847     }
19848
19849     public void finishReceiver(IBinder who, int resultCode, String resultData,
19850             Bundle resultExtras, boolean resultAbort, int flags) {
19851         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19852
19853         // Refuse possible leaked file descriptors
19854         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19855             throw new IllegalArgumentException("File descriptors passed in Bundle");
19856         }
19857
19858         final long origId = Binder.clearCallingIdentity();
19859         try {
19860             boolean doNext = false;
19861             BroadcastRecord r;
19862
19863             synchronized(this) {
19864                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19865                         ? mFgBroadcastQueue : mBgBroadcastQueue;
19866                 r = queue.getMatchingOrderedReceiver(who);
19867                 if (r != null) {
19868                     doNext = r.queue.finishReceiverLocked(r, resultCode,
19869                         resultData, resultExtras, resultAbort, true);
19870                 }
19871             }
19872
19873             if (doNext) {
19874                 r.queue.processNextBroadcast(false);
19875             }
19876             trimApplications();
19877         } finally {
19878             Binder.restoreCallingIdentity(origId);
19879         }
19880     }
19881
19882     // =========================================================
19883     // INSTRUMENTATION
19884     // =========================================================
19885
19886     public boolean startInstrumentation(ComponentName className,
19887             String profileFile, int flags, Bundle arguments,
19888             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19889             int userId, String abiOverride) {
19890         enforceNotIsolatedCaller("startInstrumentation");
19891         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19892                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19893         // Refuse possible leaked file descriptors
19894         if (arguments != null && arguments.hasFileDescriptors()) {
19895             throw new IllegalArgumentException("File descriptors passed in Bundle");
19896         }
19897
19898         synchronized(this) {
19899             InstrumentationInfo ii = null;
19900             ApplicationInfo ai = null;
19901             try {
19902                 ii = mContext.getPackageManager().getInstrumentationInfo(
19903                     className, STOCK_PM_FLAGS);
19904                 ai = AppGlobals.getPackageManager().getApplicationInfo(
19905                         ii.targetPackage, STOCK_PM_FLAGS, userId);
19906             } catch (PackageManager.NameNotFoundException e) {
19907             } catch (RemoteException e) {
19908             }
19909             if (ii == null) {
19910                 reportStartInstrumentationFailureLocked(watcher, className,
19911                         "Unable to find instrumentation info for: " + className);
19912                 return false;
19913             }
19914             if (ai == null) {
19915                 reportStartInstrumentationFailureLocked(watcher, className,
19916                         "Unable to find instrumentation target package: " + ii.targetPackage);
19917                 return false;
19918             }
19919             if (!ai.hasCode()) {
19920                 reportStartInstrumentationFailureLocked(watcher, className,
19921                         "Instrumentation target has no code: " + ii.targetPackage);
19922                 return false;
19923             }
19924
19925             int match = mContext.getPackageManager().checkSignatures(
19926                     ii.targetPackage, ii.packageName);
19927             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19928                 String msg = "Permission Denial: starting instrumentation "
19929                         + className + " from pid="
19930                         + Binder.getCallingPid()
19931                         + ", uid=" + Binder.getCallingPid()
19932                         + " not allowed because package " + ii.packageName
19933                         + " does not have a signature matching the target "
19934                         + ii.targetPackage;
19935                 reportStartInstrumentationFailureLocked(watcher, className, msg);
19936                 throw new SecurityException(msg);
19937             }
19938
19939             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19940             activeInstr.mClass = className;
19941             String defProcess = ai.processName;;
19942             if (ii.targetProcesses == null) {
19943                 activeInstr.mTargetProcesses = new String[]{ai.processName};
19944             } else if (ii.targetProcesses.equals("*")) {
19945                 activeInstr.mTargetProcesses = new String[0];
19946             } else {
19947                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19948                 defProcess = activeInstr.mTargetProcesses[0];
19949             }
19950             activeInstr.mTargetInfo = ai;
19951             activeInstr.mProfileFile = profileFile;
19952             activeInstr.mArguments = arguments;
19953             activeInstr.mWatcher = watcher;
19954             activeInstr.mUiAutomationConnection = uiAutomationConnection;
19955             activeInstr.mResultClass = className;
19956
19957             final long origId = Binder.clearCallingIdentity();
19958             // Instrumentation can kill and relaunch even persistent processes
19959             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19960                     "start instr");
19961             ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19962             app.instr = activeInstr;
19963             activeInstr.mFinished = false;
19964             activeInstr.mRunningProcesses.add(app);
19965             if (!mActiveInstrumentation.contains(activeInstr)) {
19966                 mActiveInstrumentation.add(activeInstr);
19967             }
19968             Binder.restoreCallingIdentity(origId);
19969         }
19970
19971         return true;
19972     }
19973
19974     /**
19975      * Report errors that occur while attempting to start Instrumentation.  Always writes the
19976      * error to the logs, but if somebody is watching, send the report there too.  This enables
19977      * the "am" command to report errors with more information.
19978      *
19979      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19980      * @param cn The component name of the instrumentation.
19981      * @param report The error report.
19982      */
19983     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19984             ComponentName cn, String report) {
19985         Slog.w(TAG, report);
19986         if (watcher != null) {
19987             Bundle results = new Bundle();
19988             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19989             results.putString("Error", report);
19990             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19991         }
19992     }
19993
19994     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19995         if (app.instr == null) {
19996             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19997             return;
19998         }
19999
20000         if (!app.instr.mFinished && results != null) {
20001             if (app.instr.mCurResults == null) {
20002                 app.instr.mCurResults = new Bundle(results);
20003             } else {
20004                 app.instr.mCurResults.putAll(results);
20005             }
20006         }
20007     }
20008
20009     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20010         int userId = UserHandle.getCallingUserId();
20011         // Refuse possible leaked file descriptors
20012         if (results != null && results.hasFileDescriptors()) {
20013             throw new IllegalArgumentException("File descriptors passed in Intent");
20014         }
20015
20016         synchronized(this) {
20017             ProcessRecord app = getRecordForAppLocked(target);
20018             if (app == null) {
20019                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20020                 return;
20021             }
20022             final long origId = Binder.clearCallingIdentity();
20023             addInstrumentationResultsLocked(app, results);
20024             Binder.restoreCallingIdentity(origId);
20025         }
20026     }
20027
20028     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20029         if (app.instr == null) {
20030             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20031             return;
20032         }
20033
20034         if (!app.instr.mFinished) {
20035             if (app.instr.mWatcher != null) {
20036                 Bundle finalResults = app.instr.mCurResults;
20037                 if (finalResults != null) {
20038                     if (app.instr.mCurResults != null && results != null) {
20039                         finalResults.putAll(results);
20040                     }
20041                 } else {
20042                     finalResults = results;
20043                 }
20044                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20045                         app.instr.mClass, resultCode, finalResults);
20046             }
20047
20048             // Can't call out of the system process with a lock held, so post a message.
20049             if (app.instr.mUiAutomationConnection != null) {
20050                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20051                         app.instr.mUiAutomationConnection).sendToTarget();
20052             }
20053             app.instr.mFinished = true;
20054         }
20055
20056         app.instr.removeProcess(app);
20057         app.instr = null;
20058
20059         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20060                 "finished inst");
20061     }
20062
20063     public void finishInstrumentation(IApplicationThread target,
20064             int resultCode, Bundle results) {
20065         int userId = UserHandle.getCallingUserId();
20066         // Refuse possible leaked file descriptors
20067         if (results != null && results.hasFileDescriptors()) {
20068             throw new IllegalArgumentException("File descriptors passed in Intent");
20069         }
20070
20071         synchronized(this) {
20072             ProcessRecord app = getRecordForAppLocked(target);
20073             if (app == null) {
20074                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20075                 return;
20076             }
20077             final long origId = Binder.clearCallingIdentity();
20078             finishInstrumentationLocked(app, resultCode, results);
20079             Binder.restoreCallingIdentity(origId);
20080         }
20081     }
20082
20083     // =========================================================
20084     // CONFIGURATION
20085     // =========================================================
20086
20087     public ConfigurationInfo getDeviceConfigurationInfo() {
20088         ConfigurationInfo config = new ConfigurationInfo();
20089         synchronized (this) {
20090             final Configuration globalConfig = getGlobalConfiguration();
20091             config.reqTouchScreen = globalConfig.touchscreen;
20092             config.reqKeyboardType = globalConfig.keyboard;
20093             config.reqNavigation = globalConfig.navigation;
20094             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20095                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20096                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20097             }
20098             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20099                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20100                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20101             }
20102             config.reqGlEsVersion = GL_ES_VERSION;
20103         }
20104         return config;
20105     }
20106
20107     ActivityStack getFocusedStack() {
20108         return mStackSupervisor.getFocusedStack();
20109     }
20110
20111     @Override
20112     public int getFocusedStackId() throws RemoteException {
20113         ActivityStack focusedStack = getFocusedStack();
20114         if (focusedStack != null) {
20115             return focusedStack.getStackId();
20116         }
20117         return -1;
20118     }
20119
20120     public Configuration getConfiguration() {
20121         Configuration ci;
20122         synchronized(this) {
20123             ci = new Configuration(getGlobalConfiguration());
20124             ci.userSetLocale = false;
20125         }
20126         return ci;
20127     }
20128
20129     @Override
20130     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20131         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20132         synchronized (this) {
20133             mSuppressResizeConfigChanges = suppress;
20134         }
20135     }
20136
20137     /**
20138      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20139      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20140      *       activity and clearing the task at the same time.
20141      */
20142     @Override
20143     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20144         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20145         if (StackId.isHomeOrRecentsStack(fromStackId)) {
20146             throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20147         }
20148         synchronized (this) {
20149             final long origId = Binder.clearCallingIdentity();
20150             try {
20151                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20152             } finally {
20153                 Binder.restoreCallingIdentity(origId);
20154             }
20155         }
20156     }
20157
20158     @Override
20159     public void updatePersistentConfiguration(Configuration values) {
20160         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20161         enforceWriteSettingsPermission("updatePersistentConfiguration()");
20162         if (values == null) {
20163             throw new NullPointerException("Configuration must not be null");
20164         }
20165
20166         int userId = UserHandle.getCallingUserId();
20167
20168         synchronized(this) {
20169             updatePersistentConfigurationLocked(values, userId);
20170         }
20171     }
20172
20173     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20174         final long origId = Binder.clearCallingIdentity();
20175         try {
20176             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20177         } finally {
20178             Binder.restoreCallingIdentity(origId);
20179         }
20180     }
20181
20182     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20183         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20184                 FONT_SCALE, 1.0f, userId);
20185
20186         synchronized (this) {
20187             if (getGlobalConfiguration().fontScale == scaleFactor) {
20188                 return;
20189             }
20190
20191             final Configuration configuration
20192                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20193             configuration.fontScale = scaleFactor;
20194             updatePersistentConfigurationLocked(configuration, userId);
20195         }
20196     }
20197
20198     private void enforceWriteSettingsPermission(String func) {
20199         int uid = Binder.getCallingUid();
20200         if (uid == ROOT_UID) {
20201             return;
20202         }
20203
20204         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20205                 Settings.getPackageNameForUid(mContext, uid), false)) {
20206             return;
20207         }
20208
20209         String msg = "Permission Denial: " + func + " from pid="
20210                 + Binder.getCallingPid()
20211                 + ", uid=" + uid
20212                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20213         Slog.w(TAG, msg);
20214         throw new SecurityException(msg);
20215     }
20216
20217     @Override
20218     public boolean updateConfiguration(Configuration values) {
20219         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20220
20221         synchronized(this) {
20222             if (values == null && mWindowManager != null) {
20223                 // sentinel: fetch the current configuration from the window manager
20224                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20225             }
20226
20227             if (mWindowManager != null) {
20228                 // Update OOM levels based on display size.
20229                 mProcessList.applyDisplaySize(mWindowManager);
20230             }
20231
20232             final long origId = Binder.clearCallingIdentity();
20233             try {
20234                 if (values != null) {
20235                     Settings.System.clearConfiguration(values);
20236                 }
20237                 updateConfigurationLocked(values, null, false, false /* persistent */,
20238                         UserHandle.USER_NULL, false /* deferResume */,
20239                         mTmpUpdateConfigurationResult);
20240                 return mTmpUpdateConfigurationResult.changes != 0;
20241             } finally {
20242                 Binder.restoreCallingIdentity(origId);
20243             }
20244         }
20245     }
20246
20247     void updateUserConfigurationLocked() {
20248         final Configuration configuration = new Configuration(getGlobalConfiguration());
20249         final int currentUserId = mUserController.getCurrentUserIdLocked();
20250         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20251                 currentUserId, Settings.System.canWrite(mContext));
20252         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20253                 false /* persistent */, currentUserId, false /* deferResume */);
20254     }
20255
20256     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20257             boolean initLocale) {
20258         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20259     }
20260
20261     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20262             boolean initLocale, boolean deferResume) {
20263         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20264         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20265                 UserHandle.USER_NULL, deferResume);
20266     }
20267
20268     // To cache the list of supported system locales
20269     private String[] mSupportedSystemLocales = null;
20270
20271     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20272             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20273         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20274                 deferResume, null /* result */);
20275     }
20276
20277     /**
20278      * Do either or both things: (1) change the current configuration, and (2)
20279      * make sure the given activity is running with the (now) current
20280      * configuration.  Returns true if the activity has been left running, or
20281      * false if <var>starting</var> is being destroyed to match the new
20282      * configuration.
20283      *
20284      * @param userId is only used when persistent parameter is set to true to persist configuration
20285      *               for that particular user
20286      */
20287     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20288             boolean initLocale, boolean persistent, int userId, boolean deferResume,
20289             UpdateConfigurationResult result) {
20290         int changes = 0;
20291         boolean kept = true;
20292
20293         if (mWindowManager != null) {
20294             mWindowManager.deferSurfaceLayout();
20295         }
20296         try {
20297             if (values != null) {
20298                 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20299                         deferResume);
20300             }
20301
20302             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20303         } finally {
20304             if (mWindowManager != null) {
20305                 mWindowManager.continueSurfaceLayout();
20306             }
20307         }
20308
20309         if (result != null) {
20310             result.changes = changes;
20311             result.activityRelaunched = !kept;
20312         }
20313         return kept;
20314     }
20315
20316     /** Update default (global) configuration and notify listeners about changes. */
20317     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20318             boolean persistent, int userId, boolean deferResume) {
20319         mTempConfig.setTo(getGlobalConfiguration());
20320         final int changes = mTempConfig.updateFrom(values);
20321         if (changes == 0) {
20322             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20323             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20324             // performDisplayOverrideConfigUpdate in order to send the new display configuration
20325             // (even if there are no actual changes) to unfreeze the window.
20326             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20327             return 0;
20328         }
20329
20330         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20331                 "Updating global configuration to: " + values);
20332
20333         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20334
20335         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20336             final LocaleList locales = values.getLocales();
20337             int bestLocaleIndex = 0;
20338             if (locales.size() > 1) {
20339                 if (mSupportedSystemLocales == null) {
20340                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20341                 }
20342                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20343             }
20344             SystemProperties.set("persist.sys.locale",
20345                     locales.get(bestLocaleIndex).toLanguageTag());
20346             LocaleList.setDefault(locales, bestLocaleIndex);
20347             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20348                     locales.get(bestLocaleIndex)));
20349         }
20350
20351         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20352         mTempConfig.seq = mConfigurationSeq;
20353
20354         // Update stored global config and notify everyone about the change.
20355         mStackSupervisor.onConfigurationChanged(mTempConfig);
20356
20357         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20358         // TODO(multi-display): Update UsageEvents#Event to include displayId.
20359         mUsageStatsService.reportConfigurationChange(mTempConfig,
20360                 mUserController.getCurrentUserIdLocked());
20361
20362         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20363         mShowDialogs = shouldShowDialogs(mTempConfig);
20364
20365         AttributeCache ac = AttributeCache.instance();
20366         if (ac != null) {
20367             ac.updateConfiguration(mTempConfig);
20368         }
20369
20370         // Make sure all resources in our process are updated right now, so that anyone who is going
20371         // to retrieve resource values after we return will be sure to get the new ones. This is
20372         // especially important during boot, where the first config change needs to guarantee all
20373         // resources have that config before following boot code is executed.
20374         mSystemThread.applyConfigurationToResources(mTempConfig);
20375
20376         // We need another copy of global config because we're scheduling some calls instead of
20377         // running them in place. We need to be sure that object we send will be handled unchanged.
20378         final Configuration configCopy = new Configuration(mTempConfig);
20379         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20380             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20381             msg.obj = configCopy;
20382             msg.arg1 = userId;
20383             mHandler.sendMessage(msg);
20384         }
20385
20386         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20387             ProcessRecord app = mLruProcesses.get(i);
20388             try {
20389                 if (app.thread != null) {
20390                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20391                             + app.processName + " new config " + configCopy);
20392                     app.thread.scheduleConfigurationChanged(configCopy);
20393                 }
20394             } catch (Exception e) {
20395             }
20396         }
20397
20398         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20399         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20400                 | Intent.FLAG_RECEIVER_FOREGROUND
20401                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20402         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20403                 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20404                 UserHandle.USER_ALL);
20405         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20406             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20407             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20408                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20409                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20410             if (initLocale || !mProcessesReady) {
20411                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20412             }
20413             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20414                     AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20415                     UserHandle.USER_ALL);
20416         }
20417
20418         // Override configuration of the default display duplicates global config, so we need to
20419         // update it also. This will also notify WindowManager about changes.
20420         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20421                 DEFAULT_DISPLAY);
20422
20423         return changes;
20424     }
20425
20426     @Override
20427     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20428         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20429
20430         synchronized (this) {
20431             // Check if display is initialized in AM.
20432             if (!mStackSupervisor.isDisplayAdded(displayId)) {
20433                 // Call might come when display is not yet added or has already been removed.
20434                 if (DEBUG_CONFIGURATION) {
20435                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20436                             + displayId);
20437                 }
20438                 return false;
20439             }
20440
20441             if (values == null && mWindowManager != null) {
20442                 // sentinel: fetch the current configuration from the window manager
20443                 values = mWindowManager.computeNewConfiguration(displayId);
20444             }
20445
20446             if (mWindowManager != null) {
20447                 // Update OOM levels based on display size.
20448                 mProcessList.applyDisplaySize(mWindowManager);
20449             }
20450
20451             final long origId = Binder.clearCallingIdentity();
20452             try {
20453                 if (values != null) {
20454                     Settings.System.clearConfiguration(values);
20455                 }
20456                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20457                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20458                 return mTmpUpdateConfigurationResult.changes != 0;
20459             } finally {
20460                 Binder.restoreCallingIdentity(origId);
20461             }
20462         }
20463     }
20464
20465     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20466             boolean deferResume, int displayId) {
20467         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20468                 displayId, null /* result */);
20469     }
20470
20471     /**
20472      * Updates override configuration specific for the selected display. If no config is provided,
20473      * new one will be computed in WM based on current display info.
20474      */
20475     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20476             ActivityRecord starting, boolean deferResume, int displayId,
20477             UpdateConfigurationResult result) {
20478         int changes = 0;
20479         boolean kept = true;
20480
20481         if (mWindowManager != null) {
20482             mWindowManager.deferSurfaceLayout();
20483         }
20484         try {
20485             if (values != null) {
20486                 if (displayId == DEFAULT_DISPLAY) {
20487                     // Override configuration of the default display duplicates global config, so
20488                     // we're calling global config update instead for default display. It will also
20489                     // apply the correct override config.
20490                     changes = updateGlobalConfiguration(values, false /* initLocale */,
20491                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20492                 } else {
20493                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20494                 }
20495             }
20496
20497             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20498         } finally {
20499             if (mWindowManager != null) {
20500                 mWindowManager.continueSurfaceLayout();
20501             }
20502         }
20503
20504         if (result != null) {
20505             result.changes = changes;
20506             result.activityRelaunched = !kept;
20507         }
20508         return kept;
20509     }
20510
20511     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20512             int displayId) {
20513         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20514         final int changes = mTempConfig.updateFrom(values);
20515         if (changes != 0) {
20516             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20517                     + mTempConfig + " for displayId=" + displayId);
20518             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20519
20520             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20521             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20522                 // Reset the unsupported display size dialog.
20523                 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20524
20525                 killAllBackgroundProcessesExcept(N,
20526                         ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20527             }
20528         }
20529
20530         // Update the configuration with WM first and check if any of the stacks need to be resized
20531         // due to the configuration change. If so, resize the stacks now and do any relaunches if
20532         // necessary. This way we don't need to relaunch again afterwards in
20533         // ensureActivityConfigurationLocked().
20534         if (mWindowManager != null) {
20535             final int[] resizedStacks =
20536                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20537             if (resizedStacks != null) {
20538                 for (int stackId : resizedStacks) {
20539                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20540                 }
20541             }
20542         }
20543
20544         return changes;
20545     }
20546
20547     /** Applies latest configuration and/or visibility updates if needed. */
20548     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20549         boolean kept = true;
20550         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20551         // mainStack is null during startup.
20552         if (mainStack != null) {
20553             if (changes != 0 && starting == null) {
20554                 // If the configuration changed, and the caller is not already
20555                 // in the process of starting an activity, then find the top
20556                 // activity to check if its configuration needs to change.
20557                 starting = mainStack.topRunningActivityLocked();
20558             }
20559
20560             if (starting != null) {
20561                 kept = starting.ensureActivityConfigurationLocked(changes,
20562                         false /* preserveWindow */);
20563                 // And we need to make sure at this point that all other activities
20564                 // are made visible with the correct configuration.
20565                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20566                         !PRESERVE_WINDOWS);
20567             }
20568         }
20569
20570         return kept;
20571     }
20572
20573     /** Helper method that requests bounds from WM and applies them to stack. */
20574     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20575         final Rect newStackBounds = new Rect();
20576         mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20577         mStackSupervisor.resizeStackLocked(
20578                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20579                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20580                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20581     }
20582
20583     /**
20584      * Decide based on the configuration whether we should show the ANR,
20585      * crash, etc dialogs.  The idea is that if there is no affordance to
20586      * press the on-screen buttons, or the user experience would be more
20587      * greatly impacted than the crash itself, we shouldn't show the dialog.
20588      *
20589      * A thought: SystemUI might also want to get told about this, the Power
20590      * dialog / global actions also might want different behaviors.
20591      */
20592     private static boolean shouldShowDialogs(Configuration config) {
20593         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20594                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20595                                    && config.navigation == Configuration.NAVIGATION_NONAV);
20596         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20597         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20598                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20599                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20600                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20601         return inputMethodExists && uiModeSupportsDialogs;
20602     }
20603
20604     @Override
20605     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20606         synchronized (this) {
20607             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20608             if (srec != null) {
20609                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20610             }
20611         }
20612         return false;
20613     }
20614
20615     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20616             Intent resultData) {
20617
20618         synchronized (this) {
20619             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20620             if (r != null) {
20621                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20622             }
20623             return false;
20624         }
20625     }
20626
20627     public int getLaunchedFromUid(IBinder activityToken) {
20628         ActivityRecord srec;
20629         synchronized (this) {
20630             srec = ActivityRecord.forTokenLocked(activityToken);
20631         }
20632         if (srec == null) {
20633             return -1;
20634         }
20635         return srec.launchedFromUid;
20636     }
20637
20638     public String getLaunchedFromPackage(IBinder activityToken) {
20639         ActivityRecord srec;
20640         synchronized (this) {
20641             srec = ActivityRecord.forTokenLocked(activityToken);
20642         }
20643         if (srec == null) {
20644             return null;
20645         }
20646         return srec.launchedFromPackage;
20647     }
20648
20649     // =========================================================
20650     // LIFETIME MANAGEMENT
20651     // =========================================================
20652
20653     // Returns whether the app is receiving broadcast.
20654     // If receiving, fetch all broadcast queues which the app is
20655     // the current [or imminent] receiver on.
20656     private boolean isReceivingBroadcastLocked(ProcessRecord app,
20657             ArraySet<BroadcastQueue> receivingQueues) {
20658         if (!app.curReceivers.isEmpty()) {
20659             for (BroadcastRecord r : app.curReceivers) {
20660                 receivingQueues.add(r.queue);
20661             }
20662             return true;
20663         }
20664
20665         // It's not the current receiver, but it might be starting up to become one
20666         for (BroadcastQueue queue : mBroadcastQueues) {
20667             final BroadcastRecord r = queue.mPendingBroadcast;
20668             if (r != null && r.curApp == app) {
20669                 // found it; report which queue it's in
20670                 receivingQueues.add(queue);
20671             }
20672         }
20673
20674         return !receivingQueues.isEmpty();
20675     }
20676
20677     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20678             int targetUid, ComponentName targetComponent, String targetProcess) {
20679         if (!mTrackingAssociations) {
20680             return null;
20681         }
20682         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20683                 = mAssociations.get(targetUid);
20684         if (components == null) {
20685             components = new ArrayMap<>();
20686             mAssociations.put(targetUid, components);
20687         }
20688         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20689         if (sourceUids == null) {
20690             sourceUids = new SparseArray<>();
20691             components.put(targetComponent, sourceUids);
20692         }
20693         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20694         if (sourceProcesses == null) {
20695             sourceProcesses = new ArrayMap<>();
20696             sourceUids.put(sourceUid, sourceProcesses);
20697         }
20698         Association ass = sourceProcesses.get(sourceProcess);
20699         if (ass == null) {
20700             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20701                     targetProcess);
20702             sourceProcesses.put(sourceProcess, ass);
20703         }
20704         ass.mCount++;
20705         ass.mNesting++;
20706         if (ass.mNesting == 1) {
20707             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20708             ass.mLastState = sourceState;
20709         }
20710         return ass;
20711     }
20712
20713     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20714             ComponentName targetComponent) {
20715         if (!mTrackingAssociations) {
20716             return;
20717         }
20718         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20719                 = mAssociations.get(targetUid);
20720         if (components == null) {
20721             return;
20722         }
20723         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20724         if (sourceUids == null) {
20725             return;
20726         }
20727         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20728         if (sourceProcesses == null) {
20729             return;
20730         }
20731         Association ass = sourceProcesses.get(sourceProcess);
20732         if (ass == null || ass.mNesting <= 0) {
20733             return;
20734         }
20735         ass.mNesting--;
20736         if (ass.mNesting == 0) {
20737             long uptime = SystemClock.uptimeMillis();
20738             ass.mTime += uptime - ass.mStartTime;
20739             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20740                     += uptime - ass.mLastStateUptime;
20741             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20742         }
20743     }
20744
20745     private void noteUidProcessState(final int uid, final int state) {
20746         mBatteryStatsService.noteUidProcessState(uid, state);
20747         if (mTrackingAssociations) {
20748             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20749                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20750                         = mAssociations.valueAt(i1);
20751                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20752                     SparseArray<ArrayMap<String, Association>> sourceUids
20753                             = targetComponents.valueAt(i2);
20754                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20755                     if (sourceProcesses != null) {
20756                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20757                             Association ass = sourceProcesses.valueAt(i4);
20758                             if (ass.mNesting >= 1) {
20759                                 // currently associated
20760                                 long uptime = SystemClock.uptimeMillis();
20761                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20762                                         += uptime - ass.mLastStateUptime;
20763                                 ass.mLastState = state;
20764                                 ass.mLastStateUptime = uptime;
20765                             }
20766                         }
20767                     }
20768                 }
20769             }
20770         }
20771     }
20772
20773     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20774             boolean doingAll, long now) {
20775         if (mAdjSeq == app.adjSeq) {
20776             // This adjustment has already been computed.
20777             return app.curRawAdj;
20778         }
20779
20780         if (app.thread == null) {
20781             app.adjSeq = mAdjSeq;
20782             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20783             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20784             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20785         }
20786
20787         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20788         app.adjSource = null;
20789         app.adjTarget = null;
20790         app.empty = false;
20791         app.cached = false;
20792
20793         final int activitiesSize = app.activities.size();
20794
20795         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20796             // The max adjustment doesn't allow this app to be anything
20797             // below foreground, so it is not worth doing work for it.
20798             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20799             app.adjType = "fixed";
20800             app.adjSeq = mAdjSeq;
20801             app.curRawAdj = app.maxAdj;
20802             app.foregroundActivities = false;
20803             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20804             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20805             // System processes can do UI, and when they do we want to have
20806             // them trim their memory after the user leaves the UI.  To
20807             // facilitate this, here we need to determine whether or not it
20808             // is currently showing UI.
20809             app.systemNoUi = true;
20810             if (app == TOP_APP) {
20811                 app.systemNoUi = false;
20812                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20813                 app.adjType = "pers-top-activity";
20814             } else if (app.hasTopUi) {
20815                 app.systemNoUi = false;
20816                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20817                 app.adjType = "pers-top-ui";
20818             } else if (activitiesSize > 0) {
20819                 for (int j = 0; j < activitiesSize; j++) {
20820                     final ActivityRecord r = app.activities.get(j);
20821                     if (r.visible) {
20822                         app.systemNoUi = false;
20823                     }
20824                 }
20825             }
20826             if (!app.systemNoUi) {
20827                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20828             }
20829             return (app.curAdj=app.maxAdj);
20830         }
20831
20832         app.systemNoUi = false;
20833
20834         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20835
20836         // Determine the importance of the process, starting with most
20837         // important to least, and assign an appropriate OOM adjustment.
20838         int adj;
20839         int schedGroup;
20840         int procState;
20841         boolean foregroundActivities = false;
20842         mTmpBroadcastQueue.clear();
20843         if (app == TOP_APP) {
20844             // The last app on the list is the foreground app.
20845             adj = ProcessList.FOREGROUND_APP_ADJ;
20846             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20847             app.adjType = "top-activity";
20848             foregroundActivities = true;
20849             procState = PROCESS_STATE_CUR_TOP;
20850             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20851         } else if (app.instr != null) {
20852             // Don't want to kill running instrumentation.
20853             adj = ProcessList.FOREGROUND_APP_ADJ;
20854             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20855             app.adjType = "instrumentation";
20856             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20857             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20858         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20859             // An app that is currently receiving a broadcast also
20860             // counts as being in the foreground for OOM killer purposes.
20861             // It's placed in a sched group based on the nature of the
20862             // broadcast as reflected by which queue it's active in.
20863             adj = ProcessList.FOREGROUND_APP_ADJ;
20864             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20865                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20866             app.adjType = "broadcast";
20867             procState = ActivityManager.PROCESS_STATE_RECEIVER;
20868             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20869         } else if (app.executingServices.size() > 0) {
20870             // An app that is currently executing a service callback also
20871             // counts as being in the foreground.
20872             adj = ProcessList.FOREGROUND_APP_ADJ;
20873             schedGroup = app.execServicesFg ?
20874                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20875             app.adjType = "exec-service";
20876             procState = ActivityManager.PROCESS_STATE_SERVICE;
20877             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20878             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20879         } else {
20880             // As far as we know the process is empty.  We may change our mind later.
20881             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20882             // At this point we don't actually know the adjustment.  Use the cached adj
20883             // value that the caller wants us to.
20884             adj = cachedAdj;
20885             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20886             app.cached = true;
20887             app.empty = true;
20888             app.adjType = "cch-empty";
20889             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20890         }
20891
20892         // Examine all activities if not already foreground.
20893         if (!foregroundActivities && activitiesSize > 0) {
20894             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20895             for (int j = 0; j < activitiesSize; j++) {
20896                 final ActivityRecord r = app.activities.get(j);
20897                 if (r.app != app) {
20898                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20899                             + " instead of expected " + app);
20900                     if (r.app == null || (r.app.uid == app.uid)) {
20901                         // Only fix things up when they look sane
20902                         r.app = app;
20903                     } else {
20904                         continue;
20905                     }
20906                 }
20907                 if (r.visible) {
20908                     // App has a visible activity; only upgrade adjustment.
20909                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
20910                         adj = ProcessList.VISIBLE_APP_ADJ;
20911                         app.adjType = "vis-activity";
20912                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20913                     }
20914                     if (procState > PROCESS_STATE_CUR_TOP) {
20915                         procState = PROCESS_STATE_CUR_TOP;
20916                         app.adjType = "vis-activity";
20917                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20918                     }
20919                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20920                     app.cached = false;
20921                     app.empty = false;
20922                     foregroundActivities = true;
20923                     final TaskRecord task = r.getTask();
20924                     if (task != null && minLayer > 0) {
20925                         final int layer = task.mLayerRank;
20926                         if (layer >= 0 && minLayer > layer) {
20927                             minLayer = layer;
20928                         }
20929                     }
20930                     break;
20931                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20932                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20933                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20934                         app.adjType = "pause-activity";
20935                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20936                     }
20937                     if (procState > PROCESS_STATE_CUR_TOP) {
20938                         procState = PROCESS_STATE_CUR_TOP;
20939                         app.adjType = "pause-activity";
20940                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20941                     }
20942                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20943                     app.cached = false;
20944                     app.empty = false;
20945                     foregroundActivities = true;
20946                 } else if (r.state == ActivityState.STOPPING) {
20947                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20948                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20949                         app.adjType = "stop-activity";
20950                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20951                     }
20952                     // For the process state, we will at this point consider the
20953                     // process to be cached.  It will be cached either as an activity
20954                     // or empty depending on whether the activity is finishing.  We do
20955                     // this so that we can treat the process as cached for purposes of
20956                     // memory trimming (determing current memory level, trim command to
20957                     // send to process) since there can be an arbitrary number of stopping
20958                     // processes and they should soon all go into the cached state.
20959                     if (!r.finishing) {
20960                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20961                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20962                             app.adjType = "stop-activity";
20963                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20964                         }
20965                     }
20966                     app.cached = false;
20967                     app.empty = false;
20968                     foregroundActivities = true;
20969                 } else {
20970                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20971                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20972                         app.adjType = "cch-act";
20973                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
20974                     }
20975                 }
20976             }
20977             if (adj == ProcessList.VISIBLE_APP_ADJ) {
20978                 adj += minLayer;
20979             }
20980         }
20981
20982         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20983                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20984             if (app.foregroundServices) {
20985                 // The user is aware of this app, so make it visible.
20986                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20987                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20988                 app.cached = false;
20989                 app.adjType = "fg-service";
20990                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20991                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
20992             } else if (app.hasOverlayUi) {
20993                 // The process is display an overlay UI.
20994                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20995                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20996                 app.cached = false;
20997                 app.adjType = "has-overlay-ui";
20998                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20999                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21000             }
21001         }
21002
21003         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21004                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21005             if (app.forcingToImportant != null) {
21006                 // This is currently used for toasts...  they are not interactive, and
21007                 // we don't want them to cause the app to become fully foreground (and
21008                 // thus out of background check), so we yes the best background level we can.
21009                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21010                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21011                 app.cached = false;
21012                 app.adjType = "force-imp";
21013                 app.adjSource = app.forcingToImportant;
21014                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21015                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21016             }
21017         }
21018
21019         if (app == mHeavyWeightProcess) {
21020             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21021                 // We don't want to kill the current heavy-weight process.
21022                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21023                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21024                 app.cached = false;
21025                 app.adjType = "heavy";
21026                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21027             }
21028             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21029                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21030                 app.adjType = "heavy";
21031                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21032             }
21033         }
21034
21035         if (app == mHomeProcess) {
21036             if (adj > ProcessList.HOME_APP_ADJ) {
21037                 // This process is hosting what we currently consider to be the
21038                 // home app, so we don't want to let it go into the background.
21039                 adj = ProcessList.HOME_APP_ADJ;
21040                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21041                 app.cached = false;
21042                 app.adjType = "home";
21043                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21044             }
21045             if (procState > ActivityManager.PROCESS_STATE_HOME) {
21046                 procState = ActivityManager.PROCESS_STATE_HOME;
21047                 app.adjType = "home";
21048                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21049             }
21050         }
21051
21052         if (app == mPreviousProcess && app.activities.size() > 0) {
21053             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21054                 // This was the previous process that showed UI to the user.
21055                 // We want to try to keep it around more aggressively, to give
21056                 // a good experience around switching between two apps.
21057                 adj = ProcessList.PREVIOUS_APP_ADJ;
21058                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21059                 app.cached = false;
21060                 app.adjType = "previous";
21061                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21062             }
21063             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21064                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21065                 app.adjType = "previous";
21066                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21067             }
21068         }
21069
21070         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21071                 + " reason=" + app.adjType);
21072
21073         // By default, we use the computed adjustment.  It may be changed if
21074         // there are applications dependent on our services or providers, but
21075         // this gives us a baseline and makes sure we don't get into an
21076         // infinite recursion.
21077         app.adjSeq = mAdjSeq;
21078         app.curRawAdj = adj;
21079         app.hasStartedServices = false;
21080
21081         if (mBackupTarget != null && app == mBackupTarget.app) {
21082             // If possible we want to avoid killing apps while they're being backed up
21083             if (adj > ProcessList.BACKUP_APP_ADJ) {
21084                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21085                 adj = ProcessList.BACKUP_APP_ADJ;
21086                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21087                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21088                 }
21089                 app.adjType = "backup";
21090                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21091                 app.cached = false;
21092             }
21093             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21094                 procState = ActivityManager.PROCESS_STATE_BACKUP;
21095                 app.adjType = "backup";
21096                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21097             }
21098         }
21099
21100         boolean mayBeTop = false;
21101         String mayBeTopType = null;
21102         Object mayBeTopSource = null;
21103         Object mayBeTopTarget = null;
21104
21105         for (int is = app.services.size()-1;
21106                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21107                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21108                         || procState > ActivityManager.PROCESS_STATE_TOP);
21109                 is--) {
21110             ServiceRecord s = app.services.valueAt(is);
21111             if (s.startRequested) {
21112                 app.hasStartedServices = true;
21113                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21114                     procState = ActivityManager.PROCESS_STATE_SERVICE;
21115                     app.adjType = "started-services";
21116                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21117                 }
21118                 if (app.hasShownUi && app != mHomeProcess) {
21119                     // If this process has shown some UI, let it immediately
21120                     // go to the LRU list because it may be pretty heavy with
21121                     // UI stuff.  We'll tag it with a label just to help
21122                     // debug and understand what is going on.
21123                     if (adj > ProcessList.SERVICE_ADJ) {
21124                         app.adjType = "cch-started-ui-services";
21125                     }
21126                 } else {
21127                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21128                         // This service has seen some activity within
21129                         // recent memory, so we will keep its process ahead
21130                         // of the background processes.
21131                         if (adj > ProcessList.SERVICE_ADJ) {
21132                             adj = ProcessList.SERVICE_ADJ;
21133                             app.adjType = "started-services";
21134                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21135                             app.cached = false;
21136                         }
21137                     }
21138                     // If we have let the service slide into the background
21139                     // state, still have some text describing what it is doing
21140                     // even though the service no longer has an impact.
21141                     if (adj > ProcessList.SERVICE_ADJ) {
21142                         app.adjType = "cch-started-services";
21143                     }
21144                 }
21145             }
21146
21147             for (int conni = s.connections.size()-1;
21148                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21149                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21150                             || procState > ActivityManager.PROCESS_STATE_TOP);
21151                     conni--) {
21152                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21153                 for (int i = 0;
21154                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21155                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21156                                 || procState > ActivityManager.PROCESS_STATE_TOP);
21157                         i++) {
21158                     // XXX should compute this based on the max of
21159                     // all connected clients.
21160                     ConnectionRecord cr = clist.get(i);
21161                     if (cr.binding.client == app) {
21162                         // Binding to ourself is not interesting.
21163                         continue;
21164                     }
21165
21166                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21167                         ProcessRecord client = cr.binding.client;
21168                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
21169                                 TOP_APP, doingAll, now);
21170                         int clientProcState = client.curProcState;
21171                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21172                             // If the other app is cached for any reason, for purposes here
21173                             // we are going to consider it empty.  The specific cached state
21174                             // doesn't propagate except under certain conditions.
21175                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21176                         }
21177                         String adjType = null;
21178                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21179                             // Not doing bind OOM management, so treat
21180                             // this guy more like a started service.
21181                             if (app.hasShownUi && app != mHomeProcess) {
21182                                 // If this process has shown some UI, let it immediately
21183                                 // go to the LRU list because it may be pretty heavy with
21184                                 // UI stuff.  We'll tag it with a label just to help
21185                                 // debug and understand what is going on.
21186                                 if (adj > clientAdj) {
21187                                     adjType = "cch-bound-ui-services";
21188                                 }
21189                                 app.cached = false;
21190                                 clientAdj = adj;
21191                                 clientProcState = procState;
21192                             } else {
21193                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21194                                     // This service has not seen activity within
21195                                     // recent memory, so allow it to drop to the
21196                                     // LRU list if there is no other reason to keep
21197                                     // it around.  We'll also tag it with a label just
21198                                     // to help debug and undertand what is going on.
21199                                     if (adj > clientAdj) {
21200                                         adjType = "cch-bound-services";
21201                                     }
21202                                     clientAdj = adj;
21203                                 }
21204                             }
21205                         }
21206                         if (adj > clientAdj) {
21207                             // If this process has recently shown UI, and
21208                             // the process that is binding to it is less
21209                             // important than being visible, then we don't
21210                             // care about the binding as much as we care
21211                             // about letting this process get into the LRU
21212                             // list to be killed and restarted if needed for
21213                             // memory.
21214                             if (app.hasShownUi && app != mHomeProcess
21215                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21216                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21217                                     adjType = "cch-bound-ui-services";
21218                                 }
21219                             } else {
21220                                 int newAdj;
21221                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21222                                         |Context.BIND_IMPORTANT)) != 0) {
21223                                     newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21224                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21225                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21226                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21227                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21228                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21229                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21230                                     newAdj = clientAdj;
21231                                 } else {
21232                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
21233                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21234                                     } else {
21235                                         newAdj = adj;
21236                                     }
21237                                 }
21238                                 if (!client.cached) {
21239                                     app.cached = false;
21240                                 }
21241                                 if (adj >  newAdj) {
21242                                     adj = newAdj;
21243                                     adjType = "service";
21244                                 }
21245                             }
21246                         }
21247                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21248                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21249                             // This will treat important bound services identically to
21250                             // the top app, which may behave differently than generic
21251                             // foreground work.
21252                             if (client.curSchedGroup > schedGroup) {
21253                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21254                                     schedGroup = client.curSchedGroup;
21255                                 } else {
21256                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21257                                 }
21258                             }
21259                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21260                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21261                                     // Special handling of clients who are in the top state.
21262                                     // We *may* want to consider this process to be in the
21263                                     // top state as well, but only if there is not another
21264                                     // reason for it to be running.  Being on the top is a
21265                                     // special state, meaning you are specifically running
21266                                     // for the current top app.  If the process is already
21267                                     // running in the background for some other reason, it
21268                                     // is more important to continue considering it to be
21269                                     // in the background state.
21270                                     mayBeTop = true;
21271                                     mayBeTopType = "service";
21272                                     mayBeTopSource = cr.binding.client;
21273                                     mayBeTopTarget = s.name;
21274                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21275                                 } else {
21276                                     // Special handling for above-top states (persistent
21277                                     // processes).  These should not bring the current process
21278                                     // into the top state, since they are not on top.  Instead
21279                                     // give them the best state after that.
21280                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21281                                         clientProcState =
21282                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21283                                     } else if (mWakefulness
21284                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21285                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21286                                                     != 0) {
21287                                         clientProcState =
21288                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21289                                     } else {
21290                                         clientProcState =
21291                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21292                                     }
21293                                 }
21294                             }
21295                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21296                             if (clientProcState <
21297                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21298                                 clientProcState =
21299                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21300                             }
21301                         } else {
21302                             if (clientProcState <
21303                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21304                                 clientProcState =
21305                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21306                             }
21307                         }
21308                         if (procState > clientProcState) {
21309                             procState = clientProcState;
21310                             if (adjType == null) {
21311                                 adjType = "service";
21312                             }
21313                         }
21314                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21315                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21316                             app.pendingUiClean = true;
21317                         }
21318                         if (adjType != null) {
21319                             app.adjType = adjType;
21320                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21321                                     .REASON_SERVICE_IN_USE;
21322                             app.adjSource = cr.binding.client;
21323                             app.adjSourceProcState = clientProcState;
21324                             app.adjTarget = s.name;
21325                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21326                                     + ": " + app + ", due to " + cr.binding.client
21327                                     + " adj=" + adj + " procState=" + procState);
21328                         }
21329                     }
21330                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21331                         app.treatLikeActivity = true;
21332                     }
21333                     final ActivityRecord a = cr.activity;
21334                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21335                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21336                             (a.visible || a.state == ActivityState.RESUMED ||
21337                              a.state == ActivityState.PAUSING)) {
21338                             adj = ProcessList.FOREGROUND_APP_ADJ;
21339                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21340                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21341                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21342                                 } else {
21343                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21344                                 }
21345                             }
21346                             app.cached = false;
21347                             app.adjType = "service";
21348                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21349                                     .REASON_SERVICE_IN_USE;
21350                             app.adjSource = a;
21351                             app.adjSourceProcState = procState;
21352                             app.adjTarget = s.name;
21353                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21354                                     + app);
21355                         }
21356                     }
21357                 }
21358             }
21359         }
21360
21361         for (int provi = app.pubProviders.size()-1;
21362                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21363                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21364                         || procState > ActivityManager.PROCESS_STATE_TOP);
21365                 provi--) {
21366             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21367             for (int i = cpr.connections.size()-1;
21368                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21369                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21370                             || procState > ActivityManager.PROCESS_STATE_TOP);
21371                     i--) {
21372                 ContentProviderConnection conn = cpr.connections.get(i);
21373                 ProcessRecord client = conn.client;
21374                 if (client == app) {
21375                     // Being our own client is not interesting.
21376                     continue;
21377                 }
21378                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21379                 int clientProcState = client.curProcState;
21380                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21381                     // If the other app is cached for any reason, for purposes here
21382                     // we are going to consider it empty.
21383                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21384                 }
21385                 String adjType = null;
21386                 if (adj > clientAdj) {
21387                     if (app.hasShownUi && app != mHomeProcess
21388                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21389                         adjType = "cch-ui-provider";
21390                     } else {
21391                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21392                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21393                         adjType = "provider";
21394                     }
21395                     app.cached &= client.cached;
21396                 }
21397                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21398                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21399                         // Special handling of clients who are in the top state.
21400                         // We *may* want to consider this process to be in the
21401                         // top state as well, but only if there is not another
21402                         // reason for it to be running.  Being on the top is a
21403                         // special state, meaning you are specifically running
21404                         // for the current top app.  If the process is already
21405                         // running in the background for some other reason, it
21406                         // is more important to continue considering it to be
21407                         // in the background state.
21408                         mayBeTop = true;
21409                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21410                         mayBeTopType = adjType = "provider-top";
21411                         mayBeTopSource = client;
21412                         mayBeTopTarget = cpr.name;
21413                     } else {
21414                         // Special handling for above-top states (persistent
21415                         // processes).  These should not bring the current process
21416                         // into the top state, since they are not on top.  Instead
21417                         // give them the best state after that.
21418                         clientProcState =
21419                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21420                         if (adjType == null) {
21421                             adjType = "provider";
21422                         }
21423                     }
21424                 }
21425                 if (procState > clientProcState) {
21426                     procState = clientProcState;
21427                 }
21428                 if (client.curSchedGroup > schedGroup) {
21429                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21430                 }
21431                 if (adjType != null) {
21432                     app.adjType = adjType;
21433                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21434                             .REASON_PROVIDER_IN_USE;
21435                     app.adjSource = client;
21436                     app.adjSourceProcState = clientProcState;
21437                     app.adjTarget = cpr.name;
21438                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21439                             + ": " + app + ", due to " + client
21440                             + " adj=" + adj + " procState=" + procState);
21441                 }
21442             }
21443             // If the provider has external (non-framework) process
21444             // dependencies, ensure that its adjustment is at least
21445             // FOREGROUND_APP_ADJ.
21446             if (cpr.hasExternalProcessHandles()) {
21447                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21448                     adj = ProcessList.FOREGROUND_APP_ADJ;
21449                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21450                     app.cached = false;
21451                     app.adjType = "ext-provider";
21452                     app.adjTarget = cpr.name;
21453                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21454                 }
21455                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21456                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21457                 }
21458             }
21459         }
21460
21461         if (app.lastProviderTime > 0 &&
21462                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21463             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21464                 adj = ProcessList.PREVIOUS_APP_ADJ;
21465                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21466                 app.cached = false;
21467                 app.adjType = "recent-provider";
21468                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21469             }
21470             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21471                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21472                 app.adjType = "recent-provider";
21473                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21474             }
21475         }
21476
21477         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21478             // A client of one of our services or providers is in the top state.  We
21479             // *may* want to be in the top state, but not if we are already running in
21480             // the background for some other reason.  For the decision here, we are going
21481             // to pick out a few specific states that we want to remain in when a client
21482             // is top (states that tend to be longer-term) and otherwise allow it to go
21483             // to the top state.
21484             switch (procState) {
21485                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21486                     // Something else is keeping it at this level, just leave it.
21487                     break;
21488                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21489                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21490                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21491                 case ActivityManager.PROCESS_STATE_SERVICE:
21492                     // These all are longer-term states, so pull them up to the top
21493                     // of the background states, but not all the way to the top state.
21494                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21495                     app.adjType = mayBeTopType;
21496                     app.adjSource = mayBeTopSource;
21497                     app.adjTarget = mayBeTopTarget;
21498                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21499                             + ": " + app + ", due to " + mayBeTopSource
21500                             + " adj=" + adj + " procState=" + procState);
21501                     break;
21502                 default:
21503                     // Otherwise, top is a better choice, so take it.
21504                     procState = ActivityManager.PROCESS_STATE_TOP;
21505                     app.adjType = mayBeTopType;
21506                     app.adjSource = mayBeTopSource;
21507                     app.adjTarget = mayBeTopTarget;
21508                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21509                             + ": " + app + ", due to " + mayBeTopSource
21510                             + " adj=" + adj + " procState=" + procState);
21511                     break;
21512             }
21513         }
21514
21515         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21516             if (app.hasClientActivities) {
21517                 // This is a cached process, but with client activities.  Mark it so.
21518                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21519                 app.adjType = "cch-client-act";
21520             } else if (app.treatLikeActivity) {
21521                 // This is a cached process, but somebody wants us to treat it like it has
21522                 // an activity, okay!
21523                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21524                 app.adjType = "cch-as-act";
21525             }
21526         }
21527
21528         if (adj == ProcessList.SERVICE_ADJ) {
21529             if (doingAll) {
21530                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21531                 mNewNumServiceProcs++;
21532                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21533                 if (!app.serviceb) {
21534                     // This service isn't far enough down on the LRU list to
21535                     // normally be a B service, but if we are low on RAM and it
21536                     // is large we want to force it down since we would prefer to
21537                     // keep launcher over it.
21538                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21539                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21540                         app.serviceHighRam = true;
21541                         app.serviceb = true;
21542                         //Slog.i(TAG, "ADJ " + app + " high ram!");
21543                     } else {
21544                         mNewNumAServiceProcs++;
21545                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
21546                     }
21547                 } else {
21548                     app.serviceHighRam = false;
21549                 }
21550             }
21551             if (app.serviceb) {
21552                 adj = ProcessList.SERVICE_B_ADJ;
21553             }
21554         }
21555
21556         app.curRawAdj = adj;
21557
21558         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21559         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21560         if (adj > app.maxAdj) {
21561             adj = app.maxAdj;
21562             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21563                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21564             }
21565         }
21566
21567         // Do final modification to adj.  Everything we do between here and applying
21568         // the final setAdj must be done in this function, because we will also use
21569         // it when computing the final cached adj later.  Note that we don't need to
21570         // worry about this for max adj above, since max adj will always be used to
21571         // keep it out of the cached vaues.
21572         app.curAdj = app.modifyRawOomAdj(adj);
21573         app.curSchedGroup = schedGroup;
21574         app.curProcState = procState;
21575         app.foregroundActivities = foregroundActivities;
21576
21577         return app.curRawAdj;
21578     }
21579
21580     /**
21581      * Record new PSS sample for a process.
21582      */
21583     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21584             long now) {
21585         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21586                 swapPss * 1024);
21587         proc.lastPssTime = now;
21588         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21589         if (DEBUG_PSS) Slog.d(TAG_PSS,
21590                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21591                 + " state=" + ProcessList.makeProcStateString(procState));
21592         if (proc.initialIdlePss == 0) {
21593             proc.initialIdlePss = pss;
21594         }
21595         proc.lastPss = pss;
21596         proc.lastSwapPss = swapPss;
21597         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21598             proc.lastCachedPss = pss;
21599             proc.lastCachedSwapPss = swapPss;
21600         }
21601
21602         final SparseArray<Pair<Long, String>> watchUids
21603                 = mMemWatchProcesses.getMap().get(proc.processName);
21604         Long check = null;
21605         if (watchUids != null) {
21606             Pair<Long, String> val = watchUids.get(proc.uid);
21607             if (val == null) {
21608                 val = watchUids.get(0);
21609             }
21610             if (val != null) {
21611                 check = val.first;
21612             }
21613         }
21614         if (check != null) {
21615             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21616                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21617                 if (!isDebuggable) {
21618                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21619                         isDebuggable = true;
21620                     }
21621                 }
21622                 if (isDebuggable) {
21623                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21624                     final ProcessRecord myProc = proc;
21625                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
21626                     mMemWatchDumpProcName = proc.processName;
21627                     mMemWatchDumpFile = heapdumpFile.toString();
21628                     mMemWatchDumpPid = proc.pid;
21629                     mMemWatchDumpUid = proc.uid;
21630                     BackgroundThread.getHandler().post(new Runnable() {
21631                         @Override
21632                         public void run() {
21633                             revokeUriPermission(ActivityThread.currentActivityThread()
21634                                             .getApplicationThread(),
21635                                     null, DumpHeapActivity.JAVA_URI,
21636                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
21637                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21638                                     UserHandle.myUserId());
21639                             ParcelFileDescriptor fd = null;
21640                             try {
21641                                 heapdumpFile.delete();
21642                                 fd = ParcelFileDescriptor.open(heapdumpFile,
21643                                         ParcelFileDescriptor.MODE_CREATE |
21644                                                 ParcelFileDescriptor.MODE_TRUNCATE |
21645                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
21646                                                 ParcelFileDescriptor.MODE_APPEND);
21647                                 IApplicationThread thread = myProc.thread;
21648                                 if (thread != null) {
21649                                     try {
21650                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
21651                                                 "Requesting dump heap from "
21652                                                 + myProc + " to " + heapdumpFile);
21653                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
21654                                     } catch (RemoteException e) {
21655                                     }
21656                                 }
21657                             } catch (FileNotFoundException e) {
21658                                 e.printStackTrace();
21659                             } finally {
21660                                 if (fd != null) {
21661                                     try {
21662                                         fd.close();
21663                                     } catch (IOException e) {
21664                                     }
21665                                 }
21666                             }
21667                         }
21668                     });
21669                 } else {
21670                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21671                             + ", but debugging not enabled");
21672                 }
21673             }
21674         }
21675     }
21676
21677     /**
21678      * Schedule PSS collection of a process.
21679      */
21680     void requestPssLocked(ProcessRecord proc, int procState) {
21681         if (mPendingPssProcesses.contains(proc)) {
21682             return;
21683         }
21684         if (mPendingPssProcesses.size() == 0) {
21685             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21686         }
21687         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21688         proc.pssProcState = procState;
21689         mPendingPssProcesses.add(proc);
21690     }
21691
21692     /**
21693      * Schedule PSS collection of all processes.
21694      */
21695     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21696         if (!always) {
21697             if (now < (mLastFullPssTime +
21698                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21699                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
21700                 return;
21701             }
21702         }
21703         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21704         mLastFullPssTime = now;
21705         mFullPssPending = true;
21706         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21707         mPendingPssProcesses.clear();
21708         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21709             ProcessRecord app = mLruProcesses.get(i);
21710             if (app.thread == null
21711                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21712                 continue;
21713             }
21714             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21715                 app.pssProcState = app.setProcState;
21716                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21717                         mTestPssMode, isSleepingLocked(), now);
21718                 mPendingPssProcesses.add(app);
21719             }
21720         }
21721         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21722     }
21723
21724     public void setTestPssMode(boolean enabled) {
21725         synchronized (this) {
21726             mTestPssMode = enabled;
21727             if (enabled) {
21728                 // Whenever we enable the mode, we want to take a snapshot all of current
21729                 // process mem use.
21730                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21731             }
21732         }
21733     }
21734
21735     /**
21736      * Ask a given process to GC right now.
21737      */
21738     final void performAppGcLocked(ProcessRecord app) {
21739         try {
21740             app.lastRequestedGc = SystemClock.uptimeMillis();
21741             if (app.thread != null) {
21742                 if (app.reportLowMemory) {
21743                     app.reportLowMemory = false;
21744                     app.thread.scheduleLowMemory();
21745                 } else {
21746                     app.thread.processInBackground();
21747                 }
21748             }
21749         } catch (Exception e) {
21750             // whatever.
21751         }
21752     }
21753
21754     /**
21755      * Returns true if things are idle enough to perform GCs.
21756      */
21757     private final boolean canGcNowLocked() {
21758         boolean processingBroadcasts = false;
21759         for (BroadcastQueue q : mBroadcastQueues) {
21760             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21761                 processingBroadcasts = true;
21762             }
21763         }
21764         return !processingBroadcasts
21765                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21766     }
21767
21768     /**
21769      * Perform GCs on all processes that are waiting for it, but only
21770      * if things are idle.
21771      */
21772     final void performAppGcsLocked() {
21773         final int N = mProcessesToGc.size();
21774         if (N <= 0) {
21775             return;
21776         }
21777         if (canGcNowLocked()) {
21778             while (mProcessesToGc.size() > 0) {
21779                 ProcessRecord proc = mProcessesToGc.remove(0);
21780                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21781                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21782                             <= SystemClock.uptimeMillis()) {
21783                         // To avoid spamming the system, we will GC processes one
21784                         // at a time, waiting a few seconds between each.
21785                         performAppGcLocked(proc);
21786                         scheduleAppGcsLocked();
21787                         return;
21788                     } else {
21789                         // It hasn't been long enough since we last GCed this
21790                         // process...  put it in the list to wait for its time.
21791                         addProcessToGcListLocked(proc);
21792                         break;
21793                     }
21794                 }
21795             }
21796
21797             scheduleAppGcsLocked();
21798         }
21799     }
21800
21801     /**
21802      * If all looks good, perform GCs on all processes waiting for them.
21803      */
21804     final void performAppGcsIfAppropriateLocked() {
21805         if (canGcNowLocked()) {
21806             performAppGcsLocked();
21807             return;
21808         }
21809         // Still not idle, wait some more.
21810         scheduleAppGcsLocked();
21811     }
21812
21813     /**
21814      * Schedule the execution of all pending app GCs.
21815      */
21816     final void scheduleAppGcsLocked() {
21817         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21818
21819         if (mProcessesToGc.size() > 0) {
21820             // Schedule a GC for the time to the next process.
21821             ProcessRecord proc = mProcessesToGc.get(0);
21822             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21823
21824             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21825             long now = SystemClock.uptimeMillis();
21826             if (when < (now+mConstants.GC_TIMEOUT)) {
21827                 when = now + mConstants.GC_TIMEOUT;
21828             }
21829             mHandler.sendMessageAtTime(msg, when);
21830         }
21831     }
21832
21833     /**
21834      * Add a process to the array of processes waiting to be GCed.  Keeps the
21835      * list in sorted order by the last GC time.  The process can't already be
21836      * on the list.
21837      */
21838     final void addProcessToGcListLocked(ProcessRecord proc) {
21839         boolean added = false;
21840         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21841             if (mProcessesToGc.get(i).lastRequestedGc <
21842                     proc.lastRequestedGc) {
21843                 added = true;
21844                 mProcessesToGc.add(i+1, proc);
21845                 break;
21846             }
21847         }
21848         if (!added) {
21849             mProcessesToGc.add(0, proc);
21850         }
21851     }
21852
21853     /**
21854      * Set up to ask a process to GC itself.  This will either do it
21855      * immediately, or put it on the list of processes to gc the next
21856      * time things are idle.
21857      */
21858     final void scheduleAppGcLocked(ProcessRecord app) {
21859         long now = SystemClock.uptimeMillis();
21860         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21861             return;
21862         }
21863         if (!mProcessesToGc.contains(app)) {
21864             addProcessToGcListLocked(app);
21865             scheduleAppGcsLocked();
21866         }
21867     }
21868
21869     final void checkExcessivePowerUsageLocked(boolean doKills) {
21870         updateCpuStatsNow();
21871
21872         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21873         boolean doWakeKills = doKills;
21874         boolean doCpuKills = doKills;
21875         if (mLastPowerCheckRealtime == 0) {
21876             doWakeKills = false;
21877         }
21878         if (mLastPowerCheckUptime == 0) {
21879             doCpuKills = false;
21880         }
21881         if (stats.isScreenOn()) {
21882             doWakeKills = false;
21883         }
21884         final long curRealtime = SystemClock.elapsedRealtime();
21885         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21886         final long curUptime = SystemClock.uptimeMillis();
21887         final long uptimeSince = curUptime - mLastPowerCheckUptime;
21888         mLastPowerCheckRealtime = curRealtime;
21889         mLastPowerCheckUptime = curUptime;
21890         if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
21891             doWakeKills = false;
21892         }
21893         if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
21894             doCpuKills = false;
21895         }
21896         int i = mLruProcesses.size();
21897         while (i > 0) {
21898             i--;
21899             ProcessRecord app = mLruProcesses.get(i);
21900             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21901                 long wtime;
21902                 synchronized (stats) {
21903                     wtime = stats.getProcessWakeTime(app.info.uid,
21904                             app.pid, curRealtime);
21905                 }
21906                 long wtimeUsed = wtime - app.lastWakeTime;
21907                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21908                 if (DEBUG_POWER) {
21909                     StringBuilder sb = new StringBuilder(128);
21910                     sb.append("Wake for ");
21911                     app.toShortString(sb);
21912                     sb.append(": over ");
21913                     TimeUtils.formatDuration(realtimeSince, sb);
21914                     sb.append(" used ");
21915                     TimeUtils.formatDuration(wtimeUsed, sb);
21916                     sb.append(" (");
21917                     sb.append((wtimeUsed*100)/realtimeSince);
21918                     sb.append("%)");
21919                     Slog.i(TAG_POWER, sb.toString());
21920                     sb.setLength(0);
21921                     sb.append("CPU for ");
21922                     app.toShortString(sb);
21923                     sb.append(": over ");
21924                     TimeUtils.formatDuration(uptimeSince, sb);
21925                     sb.append(" used ");
21926                     TimeUtils.formatDuration(cputimeUsed, sb);
21927                     sb.append(" (");
21928                     sb.append((cputimeUsed*100)/uptimeSince);
21929                     sb.append("%)");
21930                     Slog.i(TAG_POWER, sb.toString());
21931                 }
21932                 // If a process has held a wake lock for more
21933                 // than 50% of the time during this period,
21934                 // that sounds bad.  Kill!
21935                 if (doWakeKills && realtimeSince > 0
21936                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
21937                     synchronized (stats) {
21938                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21939                                 realtimeSince, wtimeUsed);
21940                     }
21941                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21942                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21943                 } else if (doCpuKills && uptimeSince > 0
21944                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
21945                     synchronized (stats) {
21946                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21947                                 uptimeSince, cputimeUsed);
21948                     }
21949                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21950                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21951                 } else {
21952                     app.lastWakeTime = wtime;
21953                     app.lastCpuTime = app.curCpuTime;
21954                 }
21955             }
21956         }
21957     }
21958
21959     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21960             long nowElapsed) {
21961         boolean success = true;
21962
21963         if (app.curRawAdj != app.setRawAdj) {
21964             app.setRawAdj = app.curRawAdj;
21965         }
21966
21967         int changes = 0;
21968
21969         if (app.curAdj != app.setAdj) {
21970             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21971             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21972                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21973                     + app.adjType);
21974             app.setAdj = app.curAdj;
21975             app.verifiedAdj = ProcessList.INVALID_ADJ;
21976         }
21977
21978         if (app.setSchedGroup != app.curSchedGroup) {
21979             int oldSchedGroup = app.setSchedGroup;
21980             app.setSchedGroup = app.curSchedGroup;
21981             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21982                     "Setting sched group of " + app.processName
21983                     + " to " + app.curSchedGroup);
21984             if (app.waitingToKill != null && app.curReceivers.isEmpty()
21985                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21986                 app.kill(app.waitingToKill, true);
21987                 success = false;
21988             } else {
21989                 int processGroup;
21990                 switch (app.curSchedGroup) {
21991                     case ProcessList.SCHED_GROUP_BACKGROUND:
21992                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21993                         break;
21994                     case ProcessList.SCHED_GROUP_TOP_APP:
21995                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21996                         processGroup = THREAD_GROUP_TOP_APP;
21997                         break;
21998                     default:
21999                         processGroup = THREAD_GROUP_DEFAULT;
22000                         break;
22001                 }
22002                 long oldId = Binder.clearCallingIdentity();
22003                 try {
22004                     setProcessGroup(app.pid, processGroup);
22005                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22006                         // do nothing if we already switched to RT
22007                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22008                             mVrController.onTopProcChangedLocked(app);
22009                             if (mUseFifoUiScheduling) {
22010                                 // Switch UI pipeline for app to SCHED_FIFO
22011                                 app.savedPriority = Process.getThreadPriority(app.pid);
22012                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22013                                 if (app.renderThreadTid != 0) {
22014                                     scheduleAsFifoPriority(app.renderThreadTid,
22015                                         /* suppressLogs */true);
22016                                     if (DEBUG_OOM_ADJ) {
22017                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
22018                                             app.renderThreadTid + ") to FIFO");
22019                                     }
22020                                 } else {
22021                                     if (DEBUG_OOM_ADJ) {
22022                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
22023                                     }
22024                                 }
22025                             } else {
22026                                 // Boost priority for top app UI and render threads
22027                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22028                                 if (app.renderThreadTid != 0) {
22029                                     try {
22030                                         setThreadPriority(app.renderThreadTid,
22031                                                 TOP_APP_PRIORITY_BOOST);
22032                                     } catch (IllegalArgumentException e) {
22033                                         // thread died, ignore
22034                                     }
22035                                 }
22036                             }
22037                         }
22038                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22039                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22040                         mVrController.onTopProcChangedLocked(app);
22041                         if (mUseFifoUiScheduling) {
22042                             // Reset UI pipeline to SCHED_OTHER
22043                             setThreadScheduler(app.pid, SCHED_OTHER, 0);
22044                             setThreadPriority(app.pid, app.savedPriority);
22045                             if (app.renderThreadTid != 0) {
22046                                 setThreadScheduler(app.renderThreadTid,
22047                                     SCHED_OTHER, 0);
22048                                 setThreadPriority(app.renderThreadTid, -4);
22049                             }
22050                         } else {
22051                             // Reset priority for top app UI and render threads
22052                             setThreadPriority(app.pid, 0);
22053                             if (app.renderThreadTid != 0) {
22054                                 setThreadPriority(app.renderThreadTid, 0);
22055                             }
22056                         }
22057                     }
22058                 } catch (Exception e) {
22059                     if (false) {
22060                         Slog.w(TAG, "Failed setting process group of " + app.pid
22061                                 + " to " + app.curSchedGroup);
22062                         Slog.w(TAG, "at location", e);
22063                     }
22064                 } finally {
22065                     Binder.restoreCallingIdentity(oldId);
22066                 }
22067             }
22068         }
22069         if (app.repForegroundActivities != app.foregroundActivities) {
22070             app.repForegroundActivities = app.foregroundActivities;
22071             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22072         }
22073         if (app.repProcState != app.curProcState) {
22074             app.repProcState = app.curProcState;
22075             if (app.thread != null) {
22076                 try {
22077                     if (false) {
22078                         //RuntimeException h = new RuntimeException("here");
22079                         Slog.i(TAG, "Sending new process state " + app.repProcState
22080                                 + " to " + app /*, h*/);
22081                     }
22082                     app.thread.setProcessState(app.repProcState);
22083                 } catch (RemoteException e) {
22084                 }
22085             }
22086         }
22087         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22088                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22089             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22090                 // Experimental code to more aggressively collect pss while
22091                 // running test...  the problem is that this tends to collect
22092                 // the data right when a process is transitioning between process
22093                 // states, which well tend to give noisy data.
22094                 long start = SystemClock.uptimeMillis();
22095                 long pss = Debug.getPss(app.pid, mTmpLong, null);
22096                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22097                 mPendingPssProcesses.remove(app);
22098                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22099                         + " to " + app.curProcState + ": "
22100                         + (SystemClock.uptimeMillis()-start) + "ms");
22101             }
22102             app.lastStateTime = now;
22103             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22104                     mTestPssMode, isSleepingLocked(), now);
22105             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22106                     + ProcessList.makeProcStateString(app.setProcState) + " to "
22107                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22108                     + (app.nextPssTime-now) + ": " + app);
22109         } else {
22110             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22111                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22112                     mTestPssMode)))) {
22113                 requestPssLocked(app, app.setProcState);
22114                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22115                         mTestPssMode, isSleepingLocked(), now);
22116             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22117                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22118         }
22119         if (app.setProcState != app.curProcState) {
22120             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22121                     "Proc state change of " + app.processName
22122                             + " to " + app.curProcState);
22123             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22124             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22125             if (setImportant && !curImportant) {
22126                 // This app is no longer something we consider important enough to allow to
22127                 // use arbitrary amounts of battery power.  Note
22128                 // its current wake lock time to later know to kill it if
22129                 // it is not behaving well.
22130                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22131                 synchronized (stats) {
22132                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
22133                             app.pid, nowElapsed);
22134                 }
22135                 app.lastCpuTime = app.curCpuTime;
22136
22137             }
22138             // Inform UsageStats of important process state change
22139             // Must be called before updating setProcState
22140             maybeUpdateUsageStatsLocked(app, nowElapsed);
22141
22142             app.setProcState = app.curProcState;
22143             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22144                 app.notCachedSinceIdle = false;
22145             }
22146             if (!doingAll) {
22147                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22148             } else {
22149                 app.procStateChanged = true;
22150             }
22151         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22152                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22153             // For apps that sit around for a long time in the interactive state, we need
22154             // to report this at least once a day so they don't go idle.
22155             maybeUpdateUsageStatsLocked(app, nowElapsed);
22156         }
22157
22158         if (changes != 0) {
22159             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22160                     "Changes in " + app + ": " + changes);
22161             int i = mPendingProcessChanges.size()-1;
22162             ProcessChangeItem item = null;
22163             while (i >= 0) {
22164                 item = mPendingProcessChanges.get(i);
22165                 if (item.pid == app.pid) {
22166                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22167                             "Re-using existing item: " + item);
22168                     break;
22169                 }
22170                 i--;
22171             }
22172             if (i < 0) {
22173                 // No existing item in pending changes; need a new one.
22174                 final int NA = mAvailProcessChanges.size();
22175                 if (NA > 0) {
22176                     item = mAvailProcessChanges.remove(NA-1);
22177                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22178                             "Retrieving available item: " + item);
22179                 } else {
22180                     item = new ProcessChangeItem();
22181                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22182                             "Allocating new item: " + item);
22183                 }
22184                 item.changes = 0;
22185                 item.pid = app.pid;
22186                 item.uid = app.info.uid;
22187                 if (mPendingProcessChanges.size() == 0) {
22188                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22189                             "*** Enqueueing dispatch processes changed!");
22190                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22191                 }
22192                 mPendingProcessChanges.add(item);
22193             }
22194             item.changes |= changes;
22195             item.foregroundActivities = app.repForegroundActivities;
22196             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22197                     "Item " + Integer.toHexString(System.identityHashCode(item))
22198                     + " " + app.toShortString() + ": changes=" + item.changes
22199                     + " foreground=" + item.foregroundActivities
22200                     + " type=" + app.adjType + " source=" + app.adjSource
22201                     + " target=" + app.adjTarget);
22202         }
22203
22204         return success;
22205     }
22206
22207     private boolean isEphemeralLocked(int uid) {
22208         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22209         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22210             return false;
22211         }
22212         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22213                 packages[0]);
22214     }
22215
22216     @VisibleForTesting
22217     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22218         final UidRecord.ChangeItem pendingChange;
22219         if (uidRec == null || uidRec.pendingChange == null) {
22220             if (mPendingUidChanges.size() == 0) {
22221                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22222                         "*** Enqueueing dispatch uid changed!");
22223                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22224             }
22225             final int NA = mAvailUidChanges.size();
22226             if (NA > 0) {
22227                 pendingChange = mAvailUidChanges.remove(NA-1);
22228                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22229                         "Retrieving available item: " + pendingChange);
22230             } else {
22231                 pendingChange = new UidRecord.ChangeItem();
22232                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22233                         "Allocating new item: " + pendingChange);
22234             }
22235             if (uidRec != null) {
22236                 uidRec.pendingChange = pendingChange;
22237                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
22238                     // If this uid is going away, and we haven't yet reported it is gone,
22239                     // then do so now.
22240                     change = UidRecord.CHANGE_GONE_IDLE;
22241                 }
22242             } else if (uid < 0) {
22243                 throw new IllegalArgumentException("No UidRecord or uid");
22244             }
22245             pendingChange.uidRecord = uidRec;
22246             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22247             mPendingUidChanges.add(pendingChange);
22248         } else {
22249             pendingChange = uidRec.pendingChange;
22250             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
22251                 change = UidRecord.CHANGE_GONE_IDLE;
22252             }
22253         }
22254         pendingChange.change = change;
22255         pendingChange.processState = uidRec != null
22256                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22257         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22258         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22259         if (uidRec != null) {
22260             uidRec.updateLastDispatchedProcStateSeq(change);
22261         }
22262
22263         // Directly update the power manager, since we sit on top of it and it is critical
22264         // it be kept in sync (so wake locks will be held as soon as appropriate).
22265         if (mLocalPowerManager != null) {
22266             switch (change) {
22267                 case UidRecord.CHANGE_GONE:
22268                 case UidRecord.CHANGE_GONE_IDLE:
22269                     mLocalPowerManager.uidGone(pendingChange.uid);
22270                     break;
22271                 case UidRecord.CHANGE_IDLE:
22272                     mLocalPowerManager.uidIdle(pendingChange.uid);
22273                     break;
22274                 case UidRecord.CHANGE_ACTIVE:
22275                     mLocalPowerManager.uidActive(pendingChange.uid);
22276                     break;
22277                 default:
22278                     mLocalPowerManager.updateUidProcState(pendingChange.uid,
22279                             pendingChange.processState);
22280                     break;
22281             }
22282         }
22283     }
22284
22285     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22286             String authority) {
22287         if (app == null) return;
22288         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22289             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22290             if (userState == null) return;
22291             final long now = SystemClock.elapsedRealtime();
22292             Long lastReported = userState.mProviderLastReportedFg.get(authority);
22293             if (lastReported == null || lastReported < now - 60 * 1000L) {
22294                 if (mSystemReady) {
22295                     // Cannot touch the user stats if not system ready
22296                     mUsageStatsService.reportContentProviderUsage(
22297                             authority, providerPkgName, app.userId);
22298                 }
22299                 userState.mProviderLastReportedFg.put(authority, now);
22300             }
22301         }
22302     }
22303
22304     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22305         if (DEBUG_USAGE_STATS) {
22306             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22307                     + "] state changes: old = " + app.setProcState + ", new = "
22308                     + app.curProcState);
22309         }
22310         if (mUsageStatsService == null) {
22311             return;
22312         }
22313         boolean isInteraction;
22314         // To avoid some abuse patterns, we are going to be careful about what we consider
22315         // to be an app interaction.  Being the top activity doesn't count while the display
22316         // is sleeping, nor do short foreground services.
22317         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22318             isInteraction = true;
22319             app.fgInteractionTime = 0;
22320         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22321             if (app.fgInteractionTime == 0) {
22322                 app.fgInteractionTime = nowElapsed;
22323                 isInteraction = false;
22324             } else {
22325                 isInteraction = nowElapsed > app.fgInteractionTime
22326                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22327             }
22328         } else {
22329             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22330             app.fgInteractionTime = 0;
22331         }
22332         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22333                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22334             app.interactionEventTime = nowElapsed;
22335             String[] packages = app.getPackageList();
22336             if (packages != null) {
22337                 for (int i = 0; i < packages.length; i++) {
22338                     mUsageStatsService.reportEvent(packages[i], app.userId,
22339                             UsageEvents.Event.SYSTEM_INTERACTION);
22340                 }
22341             }
22342         }
22343         app.reportedInteraction = isInteraction;
22344         if (!isInteraction) {
22345             app.interactionEventTime = 0;
22346         }
22347     }
22348
22349     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22350         if (proc.thread != null) {
22351             if (proc.baseProcessTracker != null) {
22352                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22353             }
22354         }
22355     }
22356
22357     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22358             ProcessRecord TOP_APP, boolean doingAll, long now) {
22359         if (app.thread == null) {
22360             return false;
22361         }
22362
22363         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22364
22365         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22366     }
22367
22368     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22369             boolean oomAdj) {
22370         if (isForeground != proc.foregroundServices) {
22371             proc.foregroundServices = isForeground;
22372             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22373                     proc.info.uid);
22374             if (isForeground) {
22375                 if (curProcs == null) {
22376                     curProcs = new ArrayList<ProcessRecord>();
22377                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22378                 }
22379                 if (!curProcs.contains(proc)) {
22380                     curProcs.add(proc);
22381                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22382                             proc.info.packageName, proc.info.uid);
22383                 }
22384             } else {
22385                 if (curProcs != null) {
22386                     if (curProcs.remove(proc)) {
22387                         mBatteryStatsService.noteEvent(
22388                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22389                                 proc.info.packageName, proc.info.uid);
22390                         if (curProcs.size() <= 0) {
22391                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22392                         }
22393                     }
22394                 }
22395             }
22396             if (oomAdj) {
22397                 updateOomAdjLocked();
22398             }
22399         }
22400     }
22401
22402     private final ActivityRecord resumedAppLocked() {
22403         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22404         String pkg;
22405         int uid;
22406         if (act != null) {
22407             pkg = act.packageName;
22408             uid = act.info.applicationInfo.uid;
22409         } else {
22410             pkg = null;
22411             uid = -1;
22412         }
22413         // Has the UID or resumed package name changed?
22414         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22415                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22416             if (mCurResumedPackage != null) {
22417                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22418                         mCurResumedPackage, mCurResumedUid);
22419             }
22420             mCurResumedPackage = pkg;
22421             mCurResumedUid = uid;
22422             if (mCurResumedPackage != null) {
22423                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22424                         mCurResumedPackage, mCurResumedUid);
22425             }
22426         }
22427         return act;
22428     }
22429
22430     /**
22431      * Update OomAdj for a specific process.
22432      * @param app The process to update
22433      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22434      *                  if necessary, or skip.
22435      * @return whether updateOomAdjLocked(app) was successful.
22436      */
22437     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22438         final ActivityRecord TOP_ACT = resumedAppLocked();
22439         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22440         final boolean wasCached = app.cached;
22441
22442         mAdjSeq++;
22443
22444         // This is the desired cached adjusment we want to tell it to use.
22445         // If our app is currently cached, we know it, and that is it.  Otherwise,
22446         // we don't know it yet, and it needs to now be cached we will then
22447         // need to do a complete oom adj.
22448         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22449                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22450         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22451                 SystemClock.uptimeMillis());
22452         if (oomAdjAll
22453                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22454             // Changed to/from cached state, so apps after it in the LRU
22455             // list may also be changed.
22456             updateOomAdjLocked();
22457         }
22458         return success;
22459     }
22460
22461     final void updateOomAdjLocked() {
22462         final ActivityRecord TOP_ACT = resumedAppLocked();
22463         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22464         final long now = SystemClock.uptimeMillis();
22465         final long nowElapsed = SystemClock.elapsedRealtime();
22466         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22467         final int N = mLruProcesses.size();
22468
22469         if (false) {
22470             RuntimeException e = new RuntimeException();
22471             e.fillInStackTrace();
22472             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22473         }
22474
22475         // Reset state in all uid records.
22476         for (int i=mActiveUids.size()-1; i>=0; i--) {
22477             final UidRecord uidRec = mActiveUids.valueAt(i);
22478             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22479                     "Starting update of " + uidRec);
22480             uidRec.reset();
22481         }
22482
22483         mStackSupervisor.rankTaskLayersIfNeeded();
22484
22485         mAdjSeq++;
22486         mNewNumServiceProcs = 0;
22487         mNewNumAServiceProcs = 0;
22488
22489         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22490         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22491
22492         // Let's determine how many processes we have running vs.
22493         // how many slots we have for background processes; we may want
22494         // to put multiple processes in a slot of there are enough of
22495         // them.
22496         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22497                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22498         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22499         if (numEmptyProcs > cachedProcessLimit) {
22500             // If there are more empty processes than our limit on cached
22501             // processes, then use the cached process limit for the factor.
22502             // This ensures that the really old empty processes get pushed
22503             // down to the bottom, so if we are running low on memory we will
22504             // have a better chance at keeping around more cached processes
22505             // instead of a gazillion empty processes.
22506             numEmptyProcs = cachedProcessLimit;
22507         }
22508         int emptyFactor = numEmptyProcs/numSlots;
22509         if (emptyFactor < 1) emptyFactor = 1;
22510         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22511         if (cachedFactor < 1) cachedFactor = 1;
22512         int stepCached = 0;
22513         int stepEmpty = 0;
22514         int numCached = 0;
22515         int numEmpty = 0;
22516         int numTrimming = 0;
22517
22518         mNumNonCachedProcs = 0;
22519         mNumCachedHiddenProcs = 0;
22520
22521         // First update the OOM adjustment for each of the
22522         // application processes based on their current state.
22523         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22524         int nextCachedAdj = curCachedAdj+1;
22525         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22526         int nextEmptyAdj = curEmptyAdj+2;
22527         for (int i=N-1; i>=0; i--) {
22528             ProcessRecord app = mLruProcesses.get(i);
22529             if (!app.killedByAm && app.thread != null) {
22530                 app.procStateChanged = false;
22531                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22532
22533                 // If we haven't yet assigned the final cached adj
22534                 // to the process, do that now.
22535                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22536                     switch (app.curProcState) {
22537                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22538                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22539                             // This process is a cached process holding activities...
22540                             // assign it the next cached value for that type, and then
22541                             // step that cached level.
22542                             app.curRawAdj = curCachedAdj;
22543                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22544                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22545                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22546                                     + ")");
22547                             if (curCachedAdj != nextCachedAdj) {
22548                                 stepCached++;
22549                                 if (stepCached >= cachedFactor) {
22550                                     stepCached = 0;
22551                                     curCachedAdj = nextCachedAdj;
22552                                     nextCachedAdj += 2;
22553                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22554                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22555                                     }
22556                                 }
22557                             }
22558                             break;
22559                         default:
22560                             // For everything else, assign next empty cached process
22561                             // level and bump that up.  Note that this means that
22562                             // long-running services that have dropped down to the
22563                             // cached level will be treated as empty (since their process
22564                             // state is still as a service), which is what we want.
22565                             app.curRawAdj = curEmptyAdj;
22566                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22567                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22568                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22569                                     + ")");
22570                             if (curEmptyAdj != nextEmptyAdj) {
22571                                 stepEmpty++;
22572                                 if (stepEmpty >= emptyFactor) {
22573                                     stepEmpty = 0;
22574                                     curEmptyAdj = nextEmptyAdj;
22575                                     nextEmptyAdj += 2;
22576                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22577                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22578                                     }
22579                                 }
22580                             }
22581                             break;
22582                     }
22583                 }
22584
22585                 applyOomAdjLocked(app, true, now, nowElapsed);
22586
22587                 // Count the number of process types.
22588                 switch (app.curProcState) {
22589                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22590                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22591                         mNumCachedHiddenProcs++;
22592                         numCached++;
22593                         if (numCached > cachedProcessLimit) {
22594                             app.kill("cached #" + numCached, true);
22595                         }
22596                         break;
22597                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22598                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22599                                 && app.lastActivityTime < oldTime) {
22600                             app.kill("empty for "
22601                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22602                                     / 1000) + "s", true);
22603                         } else {
22604                             numEmpty++;
22605                             if (numEmpty > emptyProcessLimit) {
22606                                 app.kill("empty #" + numEmpty, true);
22607                             }
22608                         }
22609                         break;
22610                     default:
22611                         mNumNonCachedProcs++;
22612                         break;
22613                 }
22614
22615                 if (app.isolated && app.services.size() <= 0) {
22616                     // If this is an isolated process, and there are no
22617                     // services running in it, then the process is no longer
22618                     // needed.  We agressively kill these because we can by
22619                     // definition not re-use the same process again, and it is
22620                     // good to avoid having whatever code was running in them
22621                     // left sitting around after no longer needed.
22622                     app.kill("isolated not needed", true);
22623                 } else {
22624                     // Keeping this process, update its uid.
22625                     final UidRecord uidRec = app.uidRecord;
22626                     if (uidRec != null) {
22627                         uidRec.ephemeral = app.info.isInstantApp();
22628                         if (uidRec.curProcState > app.curProcState) {
22629                             uidRec.curProcState = app.curProcState;
22630                         }
22631                         if (app.foregroundServices) {
22632                             uidRec.foregroundServices = true;
22633                         }
22634                     }
22635                 }
22636
22637                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22638                         && !app.killedByAm) {
22639                     numTrimming++;
22640                 }
22641             }
22642         }
22643
22644         incrementProcStateSeqAndNotifyAppsLocked();
22645
22646         mNumServiceProcs = mNewNumServiceProcs;
22647
22648         // Now determine the memory trimming level of background processes.
22649         // Unfortunately we need to start at the back of the list to do this
22650         // properly.  We only do this if the number of background apps we
22651         // are managing to keep around is less than half the maximum we desire;
22652         // if we are keeping a good number around, we'll let them use whatever
22653         // memory they want.
22654         final int numCachedAndEmpty = numCached + numEmpty;
22655         int memFactor;
22656         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22657                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22658             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22659                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22660             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22661                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22662             } else {
22663                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22664             }
22665         } else {
22666             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22667         }
22668         // We always allow the memory level to go up (better).  We only allow it to go
22669         // down if we are in a state where that is allowed, *and* the total number of processes
22670         // has gone down since last time.
22671         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22672                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22673                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22674         if (memFactor > mLastMemoryLevel) {
22675             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22676                 memFactor = mLastMemoryLevel;
22677                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22678             }
22679         }
22680         if (memFactor != mLastMemoryLevel) {
22681             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22682         }
22683         mLastMemoryLevel = memFactor;
22684         mLastNumProcesses = mLruProcesses.size();
22685         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22686         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22687         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22688             if (mLowRamStartTime == 0) {
22689                 mLowRamStartTime = now;
22690             }
22691             int step = 0;
22692             int fgTrimLevel;
22693             switch (memFactor) {
22694                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22695                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22696                     break;
22697                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22698                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22699                     break;
22700                 default:
22701                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22702                     break;
22703             }
22704             int factor = numTrimming/3;
22705             int minFactor = 2;
22706             if (mHomeProcess != null) minFactor++;
22707             if (mPreviousProcess != null) minFactor++;
22708             if (factor < minFactor) factor = minFactor;
22709             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22710             for (int i=N-1; i>=0; i--) {
22711                 ProcessRecord app = mLruProcesses.get(i);
22712                 if (allChanged || app.procStateChanged) {
22713                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22714                     app.procStateChanged = false;
22715                 }
22716                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22717                         && !app.killedByAm) {
22718                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
22719                         try {
22720                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22721                                     "Trimming memory of " + app.processName + " to " + curLevel);
22722                             app.thread.scheduleTrimMemory(curLevel);
22723                         } catch (RemoteException e) {
22724                         }
22725                         if (false) {
22726                             // For now we won't do this; our memory trimming seems
22727                             // to be good enough at this point that destroying
22728                             // activities causes more harm than good.
22729                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22730                                     && app != mHomeProcess && app != mPreviousProcess) {
22731                                 // Need to do this on its own message because the stack may not
22732                                 // be in a consistent state at this point.
22733                                 // For these apps we will also finish their activities
22734                                 // to help them free memory.
22735                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22736                             }
22737                         }
22738                     }
22739                     app.trimMemoryLevel = curLevel;
22740                     step++;
22741                     if (step >= factor) {
22742                         step = 0;
22743                         switch (curLevel) {
22744                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22745                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22746                                 break;
22747                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22748                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22749                                 break;
22750                         }
22751                     }
22752                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22753                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22754                             && app.thread != null) {
22755                         try {
22756                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22757                                     "Trimming memory of heavy-weight " + app.processName
22758                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22759                             app.thread.scheduleTrimMemory(
22760                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22761                         } catch (RemoteException e) {
22762                         }
22763                     }
22764                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22765                 } else {
22766                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22767                             || app.systemNoUi) && app.pendingUiClean) {
22768                         // If this application is now in the background and it
22769                         // had done UI, then give it the special trim level to
22770                         // have it free UI resources.
22771                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22772                         if (app.trimMemoryLevel < level && app.thread != null) {
22773                             try {
22774                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22775                                         "Trimming memory of bg-ui " + app.processName
22776                                         + " to " + level);
22777                                 app.thread.scheduleTrimMemory(level);
22778                             } catch (RemoteException e) {
22779                             }
22780                         }
22781                         app.pendingUiClean = false;
22782                     }
22783                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22784                         try {
22785                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22786                                     "Trimming memory of fg " + app.processName
22787                                     + " to " + fgTrimLevel);
22788                             app.thread.scheduleTrimMemory(fgTrimLevel);
22789                         } catch (RemoteException e) {
22790                         }
22791                     }
22792                     app.trimMemoryLevel = fgTrimLevel;
22793                 }
22794             }
22795         } else {
22796             if (mLowRamStartTime != 0) {
22797                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22798                 mLowRamStartTime = 0;
22799             }
22800             for (int i=N-1; i>=0; i--) {
22801                 ProcessRecord app = mLruProcesses.get(i);
22802                 if (allChanged || app.procStateChanged) {
22803                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22804                     app.procStateChanged = false;
22805                 }
22806                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22807                         || app.systemNoUi) && app.pendingUiClean) {
22808                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22809                             && app.thread != null) {
22810                         try {
22811                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22812                                     "Trimming memory of ui hidden " + app.processName
22813                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22814                             app.thread.scheduleTrimMemory(
22815                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22816                         } catch (RemoteException e) {
22817                         }
22818                     }
22819                     app.pendingUiClean = false;
22820                 }
22821                 app.trimMemoryLevel = 0;
22822             }
22823         }
22824
22825         if (mAlwaysFinishActivities) {
22826             // Need to do this on its own message because the stack may not
22827             // be in a consistent state at this point.
22828             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22829         }
22830
22831         if (allChanged) {
22832             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22833         }
22834
22835         // Update from any uid changes.
22836         if (mLocalPowerManager != null) {
22837             mLocalPowerManager.startUidChanges();
22838         }
22839         for (int i=mActiveUids.size()-1; i>=0; i--) {
22840             final UidRecord uidRec = mActiveUids.valueAt(i);
22841             int uidChange = UidRecord.CHANGE_PROCSTATE;
22842             if (uidRec.setProcState != uidRec.curProcState
22843                     || uidRec.setWhitelist != uidRec.curWhitelist) {
22844                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22845                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22846                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22847                         + " to " + uidRec.curWhitelist);
22848                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22849                         && !uidRec.curWhitelist) {
22850                     // UID is now in the background (and not on the temp whitelist).  Was it
22851                     // previously in the foreground (or on the temp whitelist)?
22852                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22853                             || uidRec.setWhitelist) {
22854                         uidRec.lastBackgroundTime = nowElapsed;
22855                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22856                             // Note: the background settle time is in elapsed realtime, while
22857                             // the handler time base is uptime.  All this means is that we may
22858                             // stop background uids later than we had intended, but that only
22859                             // happens because the device was sleeping so we are okay anyway.
22860                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22861                                     mConstants.BACKGROUND_SETTLE_TIME);
22862                         }
22863                     }
22864                 } else {
22865                     if (uidRec.idle) {
22866                         uidChange = UidRecord.CHANGE_ACTIVE;
22867                         EventLogTags.writeAmUidActive(uidRec.uid);
22868                         uidRec.idle = false;
22869                     }
22870                     uidRec.lastBackgroundTime = 0;
22871                 }
22872                 uidRec.setProcState = uidRec.curProcState;
22873                 uidRec.setWhitelist = uidRec.curWhitelist;
22874                 enqueueUidChangeLocked(uidRec, -1, uidChange);
22875                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22876                 if (uidRec.foregroundServices) {
22877                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
22878                 }
22879             }
22880         }
22881         if (mLocalPowerManager != null) {
22882             mLocalPowerManager.finishUidChanges();
22883         }
22884
22885         if (mProcessStats.shouldWriteNowLocked(now)) {
22886             mHandler.post(new Runnable() {
22887                 @Override public void run() {
22888                     synchronized (ActivityManagerService.this) {
22889                         mProcessStats.writeStateAsyncLocked();
22890                     }
22891                 }
22892             });
22893         }
22894
22895         if (DEBUG_OOM_ADJ) {
22896             final long duration = SystemClock.uptimeMillis() - now;
22897             if (false) {
22898                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22899                         new RuntimeException("here").fillInStackTrace());
22900             } else {
22901                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22902             }
22903         }
22904     }
22905
22906     @Override
22907     public void makePackageIdle(String packageName, int userId) {
22908         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22909                 != PackageManager.PERMISSION_GRANTED) {
22910             String msg = "Permission Denial: makePackageIdle() from pid="
22911                     + Binder.getCallingPid()
22912                     + ", uid=" + Binder.getCallingUid()
22913                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22914             Slog.w(TAG, msg);
22915             throw new SecurityException(msg);
22916         }
22917         final int callingPid = Binder.getCallingPid();
22918         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22919                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22920         long callingId = Binder.clearCallingIdentity();
22921         synchronized(this) {
22922             try {
22923                 IPackageManager pm = AppGlobals.getPackageManager();
22924                 int pkgUid = -1;
22925                 try {
22926                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22927                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22928                 } catch (RemoteException e) {
22929                 }
22930                 if (pkgUid == -1) {
22931                     throw new IllegalArgumentException("Unknown package name " + packageName);
22932                 }
22933
22934                 if (mLocalPowerManager != null) {
22935                     mLocalPowerManager.startUidChanges();
22936                 }
22937                 final int appId = UserHandle.getAppId(pkgUid);
22938                 final int N = mActiveUids.size();
22939                 for (int i=N-1; i>=0; i--) {
22940                     final UidRecord uidRec = mActiveUids.valueAt(i);
22941                     final long bgTime = uidRec.lastBackgroundTime;
22942                     if (bgTime > 0 && !uidRec.idle) {
22943                         if (UserHandle.getAppId(uidRec.uid) == appId) {
22944                             if (userId == UserHandle.USER_ALL ||
22945                                     userId == UserHandle.getUserId(uidRec.uid)) {
22946                                 EventLogTags.writeAmUidIdle(uidRec.uid);
22947                                 uidRec.idle = true;
22948                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22949                                         + " from package " + packageName + " user " + userId);
22950                                 doStopUidLocked(uidRec.uid, uidRec);
22951                             }
22952                         }
22953                     }
22954                 }
22955             } finally {
22956                 if (mLocalPowerManager != null) {
22957                     mLocalPowerManager.finishUidChanges();
22958                 }
22959                 Binder.restoreCallingIdentity(callingId);
22960             }
22961         }
22962     }
22963
22964     final void idleUids() {
22965         synchronized (this) {
22966             final int N = mActiveUids.size();
22967             if (N <= 0) {
22968                 return;
22969             }
22970             final long nowElapsed = SystemClock.elapsedRealtime();
22971             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22972             long nextTime = 0;
22973             if (mLocalPowerManager != null) {
22974                 mLocalPowerManager.startUidChanges();
22975             }
22976             for (int i=N-1; i>=0; i--) {
22977                 final UidRecord uidRec = mActiveUids.valueAt(i);
22978                 final long bgTime = uidRec.lastBackgroundTime;
22979                 if (bgTime > 0 && !uidRec.idle) {
22980                     if (bgTime <= maxBgTime) {
22981                         EventLogTags.writeAmUidIdle(uidRec.uid);
22982                         uidRec.idle = true;
22983                         doStopUidLocked(uidRec.uid, uidRec);
22984                     } else {
22985                         if (nextTime == 0 || nextTime > bgTime) {
22986                             nextTime = bgTime;
22987                         }
22988                     }
22989                 }
22990             }
22991             if (mLocalPowerManager != null) {
22992                 mLocalPowerManager.finishUidChanges();
22993             }
22994             if (nextTime > 0) {
22995                 mHandler.removeMessages(IDLE_UIDS_MSG);
22996                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22997                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
22998             }
22999         }
23000     }
23001
23002     /**
23003      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23004      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23005      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23006      */
23007     @VisibleForTesting
23008     @GuardedBy("this")
23009     void incrementProcStateSeqAndNotifyAppsLocked() {
23010         if (mWaitForNetworkTimeoutMs <= 0) {
23011             return;
23012         }
23013         // Used for identifying which uids need to block for network.
23014         ArrayList<Integer> blockingUids = null;
23015         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23016             final UidRecord uidRec = mActiveUids.valueAt(i);
23017             // If the network is not restricted for uid, then nothing to do here.
23018             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23019                 continue;
23020             }
23021             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23022                 continue;
23023             }
23024             // If process state is not changed, then there's nothing to do.
23025             if (uidRec.setProcState == uidRec.curProcState) {
23026                 continue;
23027             }
23028             final int blockState = getBlockStateForUid(uidRec);
23029             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23030             // there's nothing the app needs to do in this scenario.
23031             if (blockState == NETWORK_STATE_NO_CHANGE) {
23032                 continue;
23033             }
23034             synchronized (uidRec.networkStateLock) {
23035                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23036                 if (blockState == NETWORK_STATE_BLOCK) {
23037                     if (blockingUids == null) {
23038                         blockingUids = new ArrayList<>();
23039                     }
23040                     blockingUids.add(uidRec.uid);
23041                 } else {
23042                     if (DEBUG_NETWORK) {
23043                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23044                                 + " threads for uid: " + uidRec);
23045                     }
23046                     if (uidRec.waitingForNetwork) {
23047                         uidRec.networkStateLock.notifyAll();
23048                     }
23049                 }
23050             }
23051         }
23052
23053         // There are no uids that need to block, so nothing more to do.
23054         if (blockingUids == null) {
23055             return;
23056         }
23057
23058         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23059             final ProcessRecord app = mLruProcesses.get(i);
23060             if (!blockingUids.contains(app.uid)) {
23061                 continue;
23062             }
23063             if (!app.killedByAm && app.thread != null) {
23064                 final UidRecord uidRec = mActiveUids.get(app.uid);
23065                 try {
23066                     if (DEBUG_NETWORK) {
23067                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23068                                 + uidRec);
23069                     }
23070                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23071                 } catch (RemoteException ignored) {
23072                 }
23073             }
23074         }
23075     }
23076
23077     /**
23078      * Checks if the uid is coming from background to foreground or vice versa and returns
23079      * appropriate block state based on this.
23080      *
23081      * @return blockState based on whether the uid is coming from background to foreground or
23082      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23083      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23084      *         {@link #NETWORK_STATE_NO_CHANGE}.
23085      */
23086     @VisibleForTesting
23087     int getBlockStateForUid(UidRecord uidRec) {
23088         // Denotes whether uid's process state is currently allowed network access.
23089         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23090                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23091         // Denotes whether uid's process state was previously allowed network access.
23092         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23093                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23094
23095         // When the uid is coming to foreground, AMS should inform the app thread that it should
23096         // block for the network rules to get updated before launching an activity.
23097         if (!wasAllowed && isAllowed) {
23098             return NETWORK_STATE_BLOCK;
23099         }
23100         // When the uid is going to background, AMS should inform the app thread that if an
23101         // activity launch is blocked for the network rules to get updated, it should be unblocked.
23102         if (wasAllowed && !isAllowed) {
23103             return NETWORK_STATE_UNBLOCK;
23104         }
23105         return NETWORK_STATE_NO_CHANGE;
23106     }
23107
23108     final void runInBackgroundDisabled(int uid) {
23109         synchronized (this) {
23110             UidRecord uidRec = mActiveUids.get(uid);
23111             if (uidRec != null) {
23112                 // This uid is actually running...  should it be considered background now?
23113                 if (uidRec.idle) {
23114                     doStopUidLocked(uidRec.uid, uidRec);
23115                 }
23116             } else {
23117                 // This uid isn't actually running...  still send a report about it being "stopped".
23118                 doStopUidLocked(uid, null);
23119             }
23120         }
23121     }
23122
23123     final void doStopUidLocked(int uid, final UidRecord uidRec) {
23124         mServices.stopInBackgroundLocked(uid);
23125         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23126     }
23127
23128     /**
23129      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23130      */
23131     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23132             long duration, String tag) {
23133         if (DEBUG_WHITELISTS) {
23134             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23135                     + targetUid + ", " + duration + ")");
23136         }
23137
23138         synchronized (mPidsSelfLocked) {
23139             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23140             if (pr == null) {
23141                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23142                         + callerPid);
23143                 return;
23144             }
23145             if (!pr.whitelistManager) {
23146                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23147                         != PackageManager.PERMISSION_GRANTED) {
23148                     if (DEBUG_WHITELISTS) {
23149                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23150                                 + ": pid " + callerPid + " is not allowed");
23151                     }
23152                     return;
23153                 }
23154             }
23155         }
23156
23157         tempWhitelistUidLocked(targetUid, duration, tag);
23158     }
23159
23160     /**
23161      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23162      */
23163     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23164         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23165         setUidTempWhitelistStateLocked(targetUid, true);
23166         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23167     }
23168
23169     void pushTempWhitelist() {
23170         final int N;
23171         final PendingTempWhitelist[] list;
23172
23173         // First copy out the pending changes...  we need to leave them in the map for now,
23174         // in case someone needs to check what is coming up while we don't have the lock held.
23175         synchronized(this) {
23176             N = mPendingTempWhitelist.size();
23177             list = new PendingTempWhitelist[N];
23178             for (int i = 0; i < N; i++) {
23179                 list[i] = mPendingTempWhitelist.valueAt(i);
23180             }
23181         }
23182
23183         // Now safely dispatch changes to device idle controller.
23184         for (int i = 0; i < N; i++) {
23185             PendingTempWhitelist ptw = list[i];
23186             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23187                     ptw.duration, true, ptw.tag);
23188         }
23189
23190         // And now we can safely remove them from the map.
23191         synchronized(this) {
23192             for (int i = 0; i < N; i++) {
23193                 PendingTempWhitelist ptw = list[i];
23194                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23195                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23196                     mPendingTempWhitelist.removeAt(index);
23197                 }
23198             }
23199         }
23200     }
23201
23202     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23203         boolean changed = false;
23204         for (int i=mActiveUids.size()-1; i>=0; i--) {
23205             final UidRecord uidRec = mActiveUids.valueAt(i);
23206             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23207                 uidRec.curWhitelist = onWhitelist;
23208                 changed = true;
23209             }
23210         }
23211         if (changed) {
23212             updateOomAdjLocked();
23213         }
23214     }
23215
23216     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23217         boolean changed = false;
23218         final UidRecord uidRec = mActiveUids.get(uid);
23219         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23220             uidRec.curWhitelist = onWhitelist;
23221             updateOomAdjLocked();
23222         }
23223     }
23224
23225     final void trimApplications() {
23226         synchronized (this) {
23227             int i;
23228
23229             // First remove any unused application processes whose package
23230             // has been removed.
23231             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23232                 final ProcessRecord app = mRemovedProcesses.get(i);
23233                 if (app.activities.size() == 0
23234                         && app.curReceivers.isEmpty() && app.services.size() == 0) {
23235                     Slog.i(
23236                         TAG, "Exiting empty application process "
23237                         + app.toShortString() + " ("
23238                         + (app.thread != null ? app.thread.asBinder() : null)
23239                         + ")\n");
23240                     if (app.pid > 0 && app.pid != MY_PID) {
23241                         app.kill("empty", false);
23242                     } else {
23243                         try {
23244                             app.thread.scheduleExit();
23245                         } catch (Exception e) {
23246                             // Ignore exceptions.
23247                         }
23248                     }
23249                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23250                     mRemovedProcesses.remove(i);
23251
23252                     if (app.persistent) {
23253                         addAppLocked(app.info, null, false, null /* ABI override */);
23254                     }
23255                 }
23256             }
23257
23258             // Now update the oom adj for all processes.
23259             updateOomAdjLocked();
23260         }
23261     }
23262
23263     /** This method sends the specified signal to each of the persistent apps */
23264     public void signalPersistentProcesses(int sig) throws RemoteException {
23265         if (sig != SIGNAL_USR1) {
23266             throw new SecurityException("Only SIGNAL_USR1 is allowed");
23267         }
23268
23269         synchronized (this) {
23270             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23271                     != PackageManager.PERMISSION_GRANTED) {
23272                 throw new SecurityException("Requires permission "
23273                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23274             }
23275
23276             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23277                 ProcessRecord r = mLruProcesses.get(i);
23278                 if (r.thread != null && r.persistent) {
23279                     sendSignal(r.pid, sig);
23280                 }
23281             }
23282         }
23283     }
23284
23285     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23286         if (proc == null || proc == mProfileProc) {
23287             proc = mProfileProc;
23288             profileType = mProfileType;
23289             clearProfilerLocked();
23290         }
23291         if (proc == null) {
23292             return;
23293         }
23294         try {
23295             proc.thread.profilerControl(false, null, profileType);
23296         } catch (RemoteException e) {
23297             throw new IllegalStateException("Process disappeared");
23298         }
23299     }
23300
23301     private void clearProfilerLocked() {
23302         if (mProfileFd != null) {
23303             try {
23304                 mProfileFd.close();
23305             } catch (IOException e) {
23306             }
23307         }
23308         mProfileApp = null;
23309         mProfileProc = null;
23310         mProfileFile = null;
23311         mProfileType = 0;
23312         mAutoStopProfiler = false;
23313         mStreamingOutput = false;
23314         mSamplingInterval = 0;
23315     }
23316
23317     public boolean profileControl(String process, int userId, boolean start,
23318             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23319
23320         try {
23321             synchronized (this) {
23322                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23323                 // its own permission.
23324                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23325                         != PackageManager.PERMISSION_GRANTED) {
23326                     throw new SecurityException("Requires permission "
23327                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23328                 }
23329
23330                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23331                     throw new IllegalArgumentException("null profile info or fd");
23332                 }
23333
23334                 ProcessRecord proc = null;
23335                 if (process != null) {
23336                     proc = findProcessLocked(process, userId, "profileControl");
23337                 }
23338
23339                 if (start && (proc == null || proc.thread == null)) {
23340                     throw new IllegalArgumentException("Unknown process: " + process);
23341                 }
23342
23343                 if (start) {
23344                     stopProfilerLocked(null, 0);
23345                     setProfileApp(proc.info, proc.processName, profilerInfo);
23346                     mProfileProc = proc;
23347                     mProfileType = profileType;
23348                     ParcelFileDescriptor fd = profilerInfo.profileFd;
23349                     try {
23350                         fd = fd.dup();
23351                     } catch (IOException e) {
23352                         fd = null;
23353                     }
23354                     profilerInfo.profileFd = fd;
23355                     proc.thread.profilerControl(start, profilerInfo, profileType);
23356                     fd = null;
23357                     try {
23358                         mProfileFd.close();
23359                     } catch (IOException e) {
23360                     }
23361                     mProfileFd = null;
23362                 } else {
23363                     stopProfilerLocked(proc, profileType);
23364                     if (profilerInfo != null && profilerInfo.profileFd != null) {
23365                         try {
23366                             profilerInfo.profileFd.close();
23367                         } catch (IOException e) {
23368                         }
23369                     }
23370                 }
23371
23372                 return true;
23373             }
23374         } catch (RemoteException e) {
23375             throw new IllegalStateException("Process disappeared");
23376         } finally {
23377             if (profilerInfo != null && profilerInfo.profileFd != null) {
23378                 try {
23379                     profilerInfo.profileFd.close();
23380                 } catch (IOException e) {
23381                 }
23382             }
23383         }
23384     }
23385
23386     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23387         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23388                 userId, true, ALLOW_FULL_ONLY, callName, null);
23389         ProcessRecord proc = null;
23390         try {
23391             int pid = Integer.parseInt(process);
23392             synchronized (mPidsSelfLocked) {
23393                 proc = mPidsSelfLocked.get(pid);
23394             }
23395         } catch (NumberFormatException e) {
23396         }
23397
23398         if (proc == null) {
23399             ArrayMap<String, SparseArray<ProcessRecord>> all
23400                     = mProcessNames.getMap();
23401             SparseArray<ProcessRecord> procs = all.get(process);
23402             if (procs != null && procs.size() > 0) {
23403                 proc = procs.valueAt(0);
23404                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23405                     for (int i=1; i<procs.size(); i++) {
23406                         ProcessRecord thisProc = procs.valueAt(i);
23407                         if (thisProc.userId == userId) {
23408                             proc = thisProc;
23409                             break;
23410                         }
23411                     }
23412                 }
23413             }
23414         }
23415
23416         return proc;
23417     }
23418
23419     public boolean dumpHeap(String process, int userId, boolean managed,
23420             String path, ParcelFileDescriptor fd) throws RemoteException {
23421
23422         try {
23423             synchronized (this) {
23424                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23425                 // its own permission (same as profileControl).
23426                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23427                         != PackageManager.PERMISSION_GRANTED) {
23428                     throw new SecurityException("Requires permission "
23429                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23430                 }
23431
23432                 if (fd == null) {
23433                     throw new IllegalArgumentException("null fd");
23434                 }
23435
23436                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23437                 if (proc == null || proc.thread == null) {
23438                     throw new IllegalArgumentException("Unknown process: " + process);
23439                 }
23440
23441                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23442                 if (!isDebuggable) {
23443                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23444                         throw new SecurityException("Process not debuggable: " + proc);
23445                     }
23446                 }
23447
23448                 proc.thread.dumpHeap(managed, path, fd);
23449                 fd = null;
23450                 return true;
23451             }
23452         } catch (RemoteException e) {
23453             throw new IllegalStateException("Process disappeared");
23454         } finally {
23455             if (fd != null) {
23456                 try {
23457                     fd.close();
23458                 } catch (IOException e) {
23459                 }
23460             }
23461         }
23462     }
23463
23464     @Override
23465     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23466             String reportPackage) {
23467         if (processName != null) {
23468             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23469                     "setDumpHeapDebugLimit()");
23470         } else {
23471             synchronized (mPidsSelfLocked) {
23472                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23473                 if (proc == null) {
23474                     throw new SecurityException("No process found for calling pid "
23475                             + Binder.getCallingPid());
23476                 }
23477                 if (!Build.IS_DEBUGGABLE
23478                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23479                     throw new SecurityException("Not running a debuggable build");
23480                 }
23481                 processName = proc.processName;
23482                 uid = proc.uid;
23483                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23484                     throw new SecurityException("Package " + reportPackage + " is not running in "
23485                             + proc);
23486                 }
23487             }
23488         }
23489         synchronized (this) {
23490             if (maxMemSize > 0) {
23491                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23492             } else {
23493                 if (uid != 0) {
23494                     mMemWatchProcesses.remove(processName, uid);
23495                 } else {
23496                     mMemWatchProcesses.getMap().remove(processName);
23497                 }
23498             }
23499         }
23500     }
23501
23502     @Override
23503     public void dumpHeapFinished(String path) {
23504         synchronized (this) {
23505             if (Binder.getCallingPid() != mMemWatchDumpPid) {
23506                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23507                         + " does not match last pid " + mMemWatchDumpPid);
23508                 return;
23509             }
23510             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23511                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23512                         + " does not match last path " + mMemWatchDumpFile);
23513                 return;
23514             }
23515             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23516             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23517         }
23518     }
23519
23520     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23521     public void monitor() {
23522         synchronized (this) { }
23523     }
23524
23525     void onCoreSettingsChange(Bundle settings) {
23526         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23527             ProcessRecord processRecord = mLruProcesses.get(i);
23528             try {
23529                 if (processRecord.thread != null) {
23530                     processRecord.thread.setCoreSettings(settings);
23531                 }
23532             } catch (RemoteException re) {
23533                 /* ignore */
23534             }
23535         }
23536     }
23537
23538     // Multi-user methods
23539
23540     /**
23541      * Start user, if its not already running, but don't bring it to foreground.
23542      */
23543     @Override
23544     public boolean startUserInBackground(final int userId) {
23545         return mUserController.startUser(userId, /* foreground */ false);
23546     }
23547
23548     @Override
23549     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23550         return mUserController.unlockUser(userId, token, secret, listener);
23551     }
23552
23553     @Override
23554     public boolean switchUser(final int targetUserId) {
23555         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23556         int currentUserId;
23557         UserInfo targetUserInfo;
23558         synchronized (this) {
23559             currentUserId = mUserController.getCurrentUserIdLocked();
23560             targetUserInfo = mUserController.getUserInfo(targetUserId);
23561             if (targetUserId == currentUserId) {
23562                 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23563                 return true;
23564             }
23565             if (targetUserInfo == null) {
23566                 Slog.w(TAG, "No user info for user #" + targetUserId);
23567                 return false;
23568             }
23569             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23570                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23571                         + " when device is in demo mode");
23572                 return false;
23573             }
23574             if (!targetUserInfo.supportsSwitchTo()) {
23575                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23576                 return false;
23577             }
23578             if (targetUserInfo.isManagedProfile()) {
23579                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23580                 return false;
23581             }
23582             mUserController.setTargetUserIdLocked(targetUserId);
23583         }
23584         if (mUserController.mUserSwitchUiEnabled) {
23585             UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23586             Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23587             mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23588             mUiHandler.sendMessage(mHandler.obtainMessage(
23589                     START_USER_SWITCH_UI_MSG, userNames));
23590         } else {
23591             mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23592             mHandler.sendMessage(mHandler.obtainMessage(
23593                     START_USER_SWITCH_FG_MSG, targetUserId, 0));
23594         }
23595         return true;
23596     }
23597
23598     void scheduleStartProfilesLocked() {
23599         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23600             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23601                     DateUtils.SECOND_IN_MILLIS);
23602         }
23603     }
23604
23605     @Override
23606     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23607         return mUserController.stopUser(userId, force, callback);
23608     }
23609
23610     @Override
23611     public UserInfo getCurrentUser() {
23612         return mUserController.getCurrentUser();
23613     }
23614
23615     String getStartedUserState(int userId) {
23616         synchronized (this) {
23617             final UserState userState = mUserController.getStartedUserStateLocked(userId);
23618             return UserState.stateToString(userState.state);
23619         }
23620     }
23621
23622     @Override
23623     public boolean isUserRunning(int userId, int flags) {
23624         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23625                 && checkCallingPermission(INTERACT_ACROSS_USERS)
23626                     != PackageManager.PERMISSION_GRANTED) {
23627             String msg = "Permission Denial: isUserRunning() from pid="
23628                     + Binder.getCallingPid()
23629                     + ", uid=" + Binder.getCallingUid()
23630                     + " requires " + INTERACT_ACROSS_USERS;
23631             Slog.w(TAG, msg);
23632             throw new SecurityException(msg);
23633         }
23634         synchronized (this) {
23635             return mUserController.isUserRunningLocked(userId, flags);
23636         }
23637     }
23638
23639     @Override
23640     public int[] getRunningUserIds() {
23641         if (checkCallingPermission(INTERACT_ACROSS_USERS)
23642                 != PackageManager.PERMISSION_GRANTED) {
23643             String msg = "Permission Denial: isUserRunning() from pid="
23644                     + Binder.getCallingPid()
23645                     + ", uid=" + Binder.getCallingUid()
23646                     + " requires " + INTERACT_ACROSS_USERS;
23647             Slog.w(TAG, msg);
23648             throw new SecurityException(msg);
23649         }
23650         synchronized (this) {
23651             return mUserController.getStartedUserArrayLocked();
23652         }
23653     }
23654
23655     @Override
23656     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23657         mUserController.registerUserSwitchObserver(observer, name);
23658     }
23659
23660     @Override
23661     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23662         mUserController.unregisterUserSwitchObserver(observer);
23663     }
23664
23665     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23666         if (info == null) return null;
23667         ApplicationInfo newInfo = new ApplicationInfo(info);
23668         newInfo.initForUser(userId);
23669         return newInfo;
23670     }
23671
23672     public boolean isUserStopped(int userId) {
23673         synchronized (this) {
23674             return mUserController.getStartedUserStateLocked(userId) == null;
23675         }
23676     }
23677
23678     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23679         if (aInfo == null
23680                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23681             return aInfo;
23682         }
23683
23684         ActivityInfo info = new ActivityInfo(aInfo);
23685         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23686         return info;
23687     }
23688
23689     private boolean processSanityChecksLocked(ProcessRecord process) {
23690         if (process == null || process.thread == null) {
23691             return false;
23692         }
23693
23694         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23695         if (!isDebuggable) {
23696             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23697                 return false;
23698             }
23699         }
23700
23701         return true;
23702     }
23703
23704     public boolean startBinderTracking() throws RemoteException {
23705         synchronized (this) {
23706             mBinderTransactionTrackingEnabled = true;
23707             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23708             // permission (same as profileControl).
23709             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23710                     != PackageManager.PERMISSION_GRANTED) {
23711                 throw new SecurityException("Requires permission "
23712                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23713             }
23714
23715             for (int i = 0; i < mLruProcesses.size(); i++) {
23716                 ProcessRecord process = mLruProcesses.get(i);
23717                 if (!processSanityChecksLocked(process)) {
23718                     continue;
23719                 }
23720                 try {
23721                     process.thread.startBinderTracking();
23722                 } catch (RemoteException e) {
23723                     Log.v(TAG, "Process disappared");
23724                 }
23725             }
23726             return true;
23727         }
23728     }
23729
23730     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23731         try {
23732             synchronized (this) {
23733                 mBinderTransactionTrackingEnabled = false;
23734                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23735                 // permission (same as profileControl).
23736                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23737                         != PackageManager.PERMISSION_GRANTED) {
23738                     throw new SecurityException("Requires permission "
23739                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23740                 }
23741
23742                 if (fd == null) {
23743                     throw new IllegalArgumentException("null fd");
23744                 }
23745
23746                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23747                 pw.println("Binder transaction traces for all processes.\n");
23748                 for (ProcessRecord process : mLruProcesses) {
23749                     if (!processSanityChecksLocked(process)) {
23750                         continue;
23751                     }
23752
23753                     pw.println("Traces for process: " + process.processName);
23754                     pw.flush();
23755                     try {
23756                         TransferPipe tp = new TransferPipe();
23757                         try {
23758                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23759                             tp.go(fd.getFileDescriptor());
23760                         } finally {
23761                             tp.kill();
23762                         }
23763                     } catch (IOException e) {
23764                         pw.println("Failure while dumping IPC traces from " + process +
23765                                 ".  Exception: " + e);
23766                         pw.flush();
23767                     } catch (RemoteException e) {
23768                         pw.println("Got a RemoteException while dumping IPC traces from " +
23769                                 process + ".  Exception: " + e);
23770                         pw.flush();
23771                     }
23772                 }
23773                 fd = null;
23774                 return true;
23775             }
23776         } finally {
23777             if (fd != null) {
23778                 try {
23779                     fd.close();
23780                 } catch (IOException e) {
23781                 }
23782             }
23783         }
23784     }
23785
23786     @VisibleForTesting
23787     final class LocalService extends ActivityManagerInternal {
23788         @Override
23789         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23790                 int targetUserId) {
23791             synchronized (ActivityManagerService.this) {
23792                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23793                         targetPkg, intent, null, targetUserId);
23794             }
23795         }
23796
23797         @Override
23798         public String checkContentProviderAccess(String authority, int userId) {
23799             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23800         }
23801
23802         @Override
23803         public void onWakefulnessChanged(int wakefulness) {
23804             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23805         }
23806
23807         @Override
23808         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23809                 String processName, String abiOverride, int uid, Runnable crashHandler) {
23810             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23811                     processName, abiOverride, uid, crashHandler);
23812         }
23813
23814         @Override
23815         public SleepToken acquireSleepToken(String tag) {
23816             Preconditions.checkNotNull(tag);
23817
23818             synchronized (ActivityManagerService.this) {
23819                 SleepTokenImpl token = new SleepTokenImpl(tag);
23820                 mSleepTokens.add(token);
23821                 updateSleepIfNeededLocked();
23822                 return token;
23823             }
23824         }
23825
23826         @Override
23827         public ComponentName getHomeActivityForUser(int userId) {
23828             synchronized (ActivityManagerService.this) {
23829                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23830                 return homeActivity == null ? null : homeActivity.realActivity;
23831             }
23832         }
23833
23834         @Override
23835         public void onUserRemoved(int userId) {
23836             synchronized (ActivityManagerService.this) {
23837                 ActivityManagerService.this.onUserStoppedLocked(userId);
23838             }
23839         }
23840
23841         @Override
23842         public void onLocalVoiceInteractionStarted(IBinder activity,
23843                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23844             synchronized (ActivityManagerService.this) {
23845                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23846                         voiceSession, voiceInteractor);
23847             }
23848         }
23849
23850         @Override
23851         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23852             synchronized (ActivityManagerService.this) {
23853                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23854                         reasons, timestamp);
23855             }
23856         }
23857
23858         @Override
23859         public void notifyAppTransitionFinished() {
23860             synchronized (ActivityManagerService.this) {
23861                 mStackSupervisor.notifyAppTransitionDone();
23862             }
23863         }
23864
23865         @Override
23866         public void notifyAppTransitionCancelled() {
23867             synchronized (ActivityManagerService.this) {
23868                 mStackSupervisor.notifyAppTransitionDone();
23869             }
23870         }
23871
23872         @Override
23873         public List<IBinder> getTopVisibleActivities() {
23874             synchronized (ActivityManagerService.this) {
23875                 return mStackSupervisor.getTopVisibleActivities();
23876             }
23877         }
23878
23879         @Override
23880         public void notifyDockedStackMinimizedChanged(boolean minimized) {
23881             synchronized (ActivityManagerService.this) {
23882                 mStackSupervisor.setDockedStackMinimized(minimized);
23883             }
23884         }
23885
23886         @Override
23887         public void killForegroundAppsForUser(int userHandle) {
23888             synchronized (ActivityManagerService.this) {
23889                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23890                 final int NP = mProcessNames.getMap().size();
23891                 for (int ip = 0; ip < NP; ip++) {
23892                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23893                     final int NA = apps.size();
23894                     for (int ia = 0; ia < NA; ia++) {
23895                         final ProcessRecord app = apps.valueAt(ia);
23896                         if (app.persistent) {
23897                             // We don't kill persistent processes.
23898                             continue;
23899                         }
23900                         if (app.removed) {
23901                             procs.add(app);
23902                         } else if (app.userId == userHandle && app.foregroundActivities) {
23903                             app.removed = true;
23904                             procs.add(app);
23905                         }
23906                     }
23907                 }
23908
23909                 final int N = procs.size();
23910                 for (int i = 0; i < N; i++) {
23911                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
23912                 }
23913             }
23914         }
23915
23916         @Override
23917         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23918                 long duration) {
23919             if (!(target instanceof PendingIntentRecord)) {
23920                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23921                 return;
23922             }
23923             synchronized (ActivityManagerService.this) {
23924                 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23925             }
23926         }
23927
23928         @Override
23929         public void setDeviceIdleWhitelist(int[] appids) {
23930             synchronized (ActivityManagerService.this) {
23931                 mDeviceIdleWhitelist = appids;
23932             }
23933         }
23934
23935         @Override
23936         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23937             synchronized (ActivityManagerService.this) {
23938                 mDeviceIdleTempWhitelist = appids;
23939                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
23940             }
23941         }
23942
23943         @Override
23944         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23945                 int userId) {
23946             Preconditions.checkNotNull(values, "Configuration must not be null");
23947             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23948             synchronized (ActivityManagerService.this) {
23949                 updateConfigurationLocked(values, null, false, true, userId,
23950                         false /* deferResume */);
23951             }
23952         }
23953
23954         @Override
23955         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23956                 Bundle bOptions) {
23957             Preconditions.checkNotNull(intents, "intents");
23958             final String[] resolvedTypes = new String[intents.length];
23959             for (int i = 0; i < intents.length; i++) {
23960                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23961             }
23962
23963             // UID of the package on user userId.
23964             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23965             // packageUid may not be initialized.
23966             int packageUid = 0;
23967             try {
23968                 packageUid = AppGlobals.getPackageManager().getPackageUid(
23969                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23970             } catch (RemoteException e) {
23971                 // Shouldn't happen.
23972             }
23973
23974             synchronized (ActivityManagerService.this) {
23975                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23976                         /*resultTo*/ null, bOptions, userId);
23977             }
23978         }
23979
23980         @Override
23981         public int getUidProcessState(int uid) {
23982             return getUidState(uid);
23983         }
23984
23985         @Override
23986         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23987             synchronized (ActivityManagerService.this) {
23988
23989                 // We might change the visibilities here, so prepare an empty app transition which
23990                 // might be overridden later if we actually change visibilities.
23991                 final boolean wasTransitionSet =
23992                         mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
23993                 if (!wasTransitionSet) {
23994                     mWindowManager.prepareAppTransition(TRANSIT_NONE,
23995                             false /* alwaysKeepCurrent */);
23996                 }
23997                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23998
23999                 // If there was a transition set already we don't want to interfere with it as we
24000                 // might be starting it too early.
24001                 if (!wasTransitionSet) {
24002                     mWindowManager.executeAppTransition();
24003                 }
24004             }
24005             if (callback != null) {
24006                 callback.run();
24007             }
24008         }
24009
24010         @Override
24011         public boolean isSystemReady() {
24012             // no need to synchronize(this) just to read & return the value
24013             return mSystemReady;
24014         }
24015
24016         @Override
24017         public void notifyKeyguardTrustedChanged() {
24018             synchronized (ActivityManagerService.this) {
24019                 if (mKeyguardController.isKeyguardShowing()) {
24020                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24021                 }
24022             }
24023         }
24024
24025         /**
24026          * Sets if the given pid has an overlay UI or not.
24027          *
24028          * @param pid The pid we are setting overlay UI for.
24029          * @param hasOverlayUi True if the process has overlay UI.
24030          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24031          */
24032         @Override
24033         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24034             synchronized (ActivityManagerService.this) {
24035                 final ProcessRecord pr;
24036                 synchronized (mPidsSelfLocked) {
24037                     pr = mPidsSelfLocked.get(pid);
24038                     if (pr == null) {
24039                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24040                         return;
24041                     }
24042                 }
24043                 if (pr.hasOverlayUi == hasOverlayUi) {
24044                     return;
24045                 }
24046                 pr.hasOverlayUi = hasOverlayUi;
24047                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24048                 updateOomAdjLocked(pr, true);
24049             }
24050         }
24051
24052         /**
24053          * Called after the network policy rules are updated by
24054          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24055          * and {@param procStateSeq}.
24056          */
24057         @Override
24058         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24059             if (DEBUG_NETWORK) {
24060                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24061                         + uid + " seq: " + procStateSeq);
24062             }
24063             UidRecord record;
24064             synchronized (ActivityManagerService.this) {
24065                 record = mActiveUids.get(uid);
24066                 if (record == null) {
24067                     if (DEBUG_NETWORK) {
24068                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24069                                 + " procStateSeq: " + procStateSeq);
24070                     }
24071                     return;
24072                 }
24073             }
24074             synchronized (record.networkStateLock) {
24075                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24076                     if (DEBUG_NETWORK) {
24077                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24078                                 + " been handled for uid: " + uid);
24079                     }
24080                     return;
24081                 }
24082                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24083                 if (record.curProcStateSeq > procStateSeq) {
24084                     if (DEBUG_NETWORK) {
24085                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24086                                 + ", curProcstateSeq: " + record.curProcStateSeq
24087                                 + ", procStateSeq: " + procStateSeq);
24088                     }
24089                     return;
24090                 }
24091                 if (record.waitingForNetwork) {
24092                     if (DEBUG_NETWORK) {
24093                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24094                                 + ", procStateSeq: " + procStateSeq);
24095                     }
24096                     record.networkStateLock.notifyAll();
24097                 }
24098             }
24099         }
24100
24101         /**
24102          * Called after virtual display Id is updated by
24103          * {@link com.android.server.vr.Vr2dDisplay} with a specific
24104          * {@param vrVr2dDisplayId}.
24105          */
24106         @Override
24107         public void setVr2dDisplayId(int vr2dDisplayId) {
24108             if (DEBUG_STACK) {
24109                 Slog.d(TAG, "setVr2dDisplayId called for: " +
24110                         vr2dDisplayId);
24111             }
24112             synchronized (ActivityManagerService.this) {
24113                 mVr2dDisplayId = vr2dDisplayId;
24114             }
24115         }
24116
24117         @Override
24118         public void saveANRState(String reason) {
24119             synchronized (ActivityManagerService.this) {
24120                 final StringWriter sw = new StringWriter();
24121                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24122                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24123                 if (reason != null) {
24124                     pw.println("  Reason: " + reason);
24125                 }
24126                 pw.println();
24127                 mActivityStarter.dump(pw, "  ");
24128                 pw.println();
24129                 pw.println("-------------------------------------------------------------------------------");
24130                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24131                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24132                         "" /* header */);
24133                 pw.println();
24134                 pw.close();
24135
24136                 mLastANRState = sw.toString();
24137             }
24138         }
24139
24140         @Override
24141         public void clearSavedANRState() {
24142             synchronized (ActivityManagerService.this) {
24143                 mLastANRState = null;
24144             }
24145         }
24146     }
24147
24148     /**
24149      * Called by app main thread to wait for the network policy rules to get updated.
24150      *
24151      * @param procStateSeq The sequence number indicating the process state change that the main
24152      *                     thread is interested in.
24153      */
24154     @Override
24155     public void waitForNetworkStateUpdate(long procStateSeq) {
24156         final int callingUid = Binder.getCallingUid();
24157         if (DEBUG_NETWORK) {
24158             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24159         }
24160         UidRecord record;
24161         synchronized (this) {
24162             record = mActiveUids.get(callingUid);
24163             if (record == null) {
24164                 return;
24165             }
24166         }
24167         synchronized (record.networkStateLock) {
24168             if (record.lastDispatchedProcStateSeq < procStateSeq) {
24169                 if (DEBUG_NETWORK) {
24170                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24171                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24172                             + " lastProcStateSeqDispatchedToObservers: "
24173                             + record.lastDispatchedProcStateSeq);
24174                 }
24175                 return;
24176             }
24177             if (record.curProcStateSeq > procStateSeq) {
24178                 if (DEBUG_NETWORK) {
24179                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24180                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24181                             + ", procStateSeq: " + procStateSeq);
24182                 }
24183                 return;
24184             }
24185             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24186                 if (DEBUG_NETWORK) {
24187                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24188                             + procStateSeq + ", so no need to wait. Uid: "
24189                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24190                             + record.lastNetworkUpdatedProcStateSeq);
24191                 }
24192                 return;
24193             }
24194             try {
24195                 if (DEBUG_NETWORK) {
24196                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24197                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24198                 }
24199                 final long startTime = SystemClock.uptimeMillis();
24200                 record.waitingForNetwork = true;
24201                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24202                 record.waitingForNetwork = false;
24203                 final long totalTime = SystemClock.uptimeMillis() - startTime;
24204                 if (totalTime >= mWaitForNetworkTimeoutMs) {
24205                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24206                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24207                             + procStateSeq + " UidRec: " + record
24208                             + " validateUidRec: " + mValidateUids.get(callingUid));
24209                 }
24210             } catch (InterruptedException e) {
24211                 Thread.currentThread().interrupt();
24212             }
24213         }
24214     }
24215
24216     public void waitForBroadcastIdle(PrintWriter pw) {
24217         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24218         while (true) {
24219             boolean idle = true;
24220             synchronized (this) {
24221                 for (BroadcastQueue queue : mBroadcastQueues) {
24222                     if (!queue.isIdle()) {
24223                         final String msg = "Waiting for queue " + queue + " to become idle...";
24224                         pw.println(msg);
24225                         pw.flush();
24226                         Slog.v(TAG, msg);
24227                         idle = false;
24228                     }
24229                 }
24230             }
24231
24232             if (idle) {
24233                 final String msg = "All broadcast queues are idle!";
24234                 pw.println(msg);
24235                 pw.flush();
24236                 Slog.v(TAG, msg);
24237                 return;
24238             } else {
24239                 SystemClock.sleep(1000);
24240             }
24241         }
24242     }
24243
24244     /**
24245      * Return the user id of the last resumed activity.
24246      */
24247     @Override
24248     public @UserIdInt int getLastResumedActivityUserId() {
24249         enforceCallingPermission(
24250                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24251         synchronized (this) {
24252             if (mLastResumedActivity == null) {
24253                 return mUserController.getCurrentUserIdLocked();
24254             }
24255             return mLastResumedActivity.userId;
24256         }
24257     }
24258
24259     private final class SleepTokenImpl extends SleepToken {
24260         private final String mTag;
24261         private final long mAcquireTime;
24262
24263         public SleepTokenImpl(String tag) {
24264             mTag = tag;
24265             mAcquireTime = SystemClock.uptimeMillis();
24266         }
24267
24268         @Override
24269         public void release() {
24270             synchronized (ActivityManagerService.this) {
24271                 if (mSleepTokens.remove(this)) {
24272                     updateSleepIfNeededLocked();
24273                 }
24274             }
24275         }
24276
24277         @Override
24278         public String toString() {
24279             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
24280         }
24281     }
24282
24283     /**
24284      * An implementation of IAppTask, that allows an app to manage its own tasks via
24285      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24286      * only the process that calls getAppTasks() can call the AppTask methods.
24287      */
24288     class AppTaskImpl extends IAppTask.Stub {
24289         private int mTaskId;
24290         private int mCallingUid;
24291
24292         public AppTaskImpl(int taskId, int callingUid) {
24293             mTaskId = taskId;
24294             mCallingUid = callingUid;
24295         }
24296
24297         private void checkCaller() {
24298             if (mCallingUid != Binder.getCallingUid()) {
24299                 throw new SecurityException("Caller " + mCallingUid
24300                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24301             }
24302         }
24303
24304         @Override
24305         public void finishAndRemoveTask() {
24306             checkCaller();
24307
24308             synchronized (ActivityManagerService.this) {
24309                 long origId = Binder.clearCallingIdentity();
24310                 try {
24311                     // We remove the task from recents to preserve backwards
24312                     if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24313                             REMOVE_FROM_RECENTS)) {
24314                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24315                     }
24316                 } finally {
24317                     Binder.restoreCallingIdentity(origId);
24318                 }
24319             }
24320         }
24321
24322         @Override
24323         public ActivityManager.RecentTaskInfo getTaskInfo() {
24324             checkCaller();
24325
24326             synchronized (ActivityManagerService.this) {
24327                 long origId = Binder.clearCallingIdentity();
24328                 try {
24329                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24330                     if (tr == null) {
24331                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24332                     }
24333                     return createRecentTaskInfoFromTaskRecord(tr);
24334                 } finally {
24335                     Binder.restoreCallingIdentity(origId);
24336                 }
24337             }
24338         }
24339
24340         @Override
24341         public void moveToFront() {
24342             checkCaller();
24343             // Will bring task to front if it already has a root activity.
24344             final long origId = Binder.clearCallingIdentity();
24345             try {
24346                 synchronized (this) {
24347                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24348                 }
24349             } finally {
24350                 Binder.restoreCallingIdentity(origId);
24351             }
24352         }
24353
24354         @Override
24355         public int startActivity(IBinder whoThread, String callingPackage,
24356                 Intent intent, String resolvedType, Bundle bOptions) {
24357             checkCaller();
24358
24359             int callingUser = UserHandle.getCallingUserId();
24360             TaskRecord tr;
24361             IApplicationThread appThread;
24362             synchronized (ActivityManagerService.this) {
24363                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24364                 if (tr == null) {
24365                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24366                 }
24367                 appThread = IApplicationThread.Stub.asInterface(whoThread);
24368                 if (appThread == null) {
24369                     throw new IllegalArgumentException("Bad app thread " + appThread);
24370                 }
24371             }
24372             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24373                     resolvedType, null, null, null, null, 0, 0, null, null,
24374                     null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
24375         }
24376
24377         @Override
24378         public void setExcludeFromRecents(boolean exclude) {
24379             checkCaller();
24380
24381             synchronized (ActivityManagerService.this) {
24382                 long origId = Binder.clearCallingIdentity();
24383                 try {
24384                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24385                     if (tr == null) {
24386                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24387                     }
24388                     Intent intent = tr.getBaseIntent();
24389                     if (exclude) {
24390                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24391                     } else {
24392                         intent.setFlags(intent.getFlags()
24393                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24394                     }
24395                 } finally {
24396                     Binder.restoreCallingIdentity(origId);
24397                 }
24398             }
24399         }
24400     }
24401
24402     /**
24403      * Kill processes for the user with id userId and that depend on the package named packageName
24404      */
24405     @Override
24406     public void killPackageDependents(String packageName, int userId) {
24407         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24408         if (packageName == null) {
24409             throw new NullPointerException(
24410                     "Cannot kill the dependents of a package without its name.");
24411         }
24412
24413         long callingId = Binder.clearCallingIdentity();
24414         IPackageManager pm = AppGlobals.getPackageManager();
24415         int pkgUid = -1;
24416         try {
24417             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24418         } catch (RemoteException e) {
24419         }
24420         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24421             throw new IllegalArgumentException(
24422                     "Cannot kill dependents of non-existing package " + packageName);
24423         }
24424         try {
24425             synchronized(this) {
24426                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24427                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24428                         "dep: " + packageName);
24429             }
24430         } finally {
24431             Binder.restoreCallingIdentity(callingId);
24432         }
24433     }
24434
24435     @Override
24436     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24437             throws RemoteException {
24438         final long callingId = Binder.clearCallingIdentity();
24439         try {
24440             mKeyguardController.dismissKeyguard(token, callback);
24441         } finally {
24442             Binder.restoreCallingIdentity(callingId);
24443         }
24444     }
24445
24446     @Override
24447     public int restartUserInBackground(final int userId) {
24448         return mUserController.restartUser(userId, /* foreground */ false);
24449     }
24450
24451     @Override
24452     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24453         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24454                 "scheduleApplicationInfoChanged()");
24455
24456         synchronized (this) {
24457             final long origId = Binder.clearCallingIdentity();
24458             try {
24459                 updateApplicationInfoLocked(packageNames, userId);
24460             } finally {
24461                 Binder.restoreCallingIdentity(origId);
24462             }
24463         }
24464     }
24465
24466     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24467         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24468         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24469             final ProcessRecord app = mLruProcesses.get(i);
24470             if (app.thread == null) {
24471                 continue;
24472             }
24473
24474             if (userId != UserHandle.USER_ALL && app.userId != userId) {
24475                 continue;
24476             }
24477
24478             final int packageCount = app.pkgList.size();
24479             for (int j = 0; j < packageCount; j++) {
24480                 final String packageName = app.pkgList.keyAt(j);
24481                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24482                     try {
24483                         final ApplicationInfo ai = AppGlobals.getPackageManager()
24484                                 .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
24485                         if (ai != null) {
24486                             app.thread.scheduleApplicationInfoChanged(ai);
24487                         }
24488                     } catch (RemoteException e) {
24489                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24490                                     packageName, app));
24491                     }
24492                 }
24493             }
24494         }
24495     }
24496
24497     /**
24498      * Attach an agent to the specified process (proces name or PID)
24499      */
24500     public void attachAgent(String process, String path) {
24501         try {
24502             synchronized (this) {
24503                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24504                 if (proc == null || proc.thread == null) {
24505                     throw new IllegalArgumentException("Unknown process: " + process);
24506                 }
24507
24508                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24509                 if (!isDebuggable) {
24510                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24511                         throw new SecurityException("Process not debuggable: " + proc);
24512                     }
24513                 }
24514
24515                 proc.thread.attachAgent(path);
24516             }
24517         } catch (RemoteException e) {
24518             throw new IllegalStateException("Process disappeared");
24519         }
24520     }
24521
24522     @VisibleForTesting
24523     public static class Injector {
24524         private NetworkManagementInternal mNmi;
24525
24526         public Context getContext() {
24527             return null;
24528         }
24529
24530         public AppOpsService getAppOpsService(File file, Handler handler) {
24531             return new AppOpsService(file, handler);
24532         }
24533
24534         public Handler getUiHandler(ActivityManagerService service) {
24535             return service.new UiHandler();
24536         }
24537
24538         public boolean isNetworkRestrictedForUid(int uid) {
24539             if (ensureHasNetworkManagementInternal()) {
24540                 return mNmi.isNetworkRestrictedForUid(uid);
24541             }
24542             return false;
24543         }
24544
24545         private boolean ensureHasNetworkManagementInternal() {
24546             if (mNmi == null) {
24547                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24548             }
24549             return mNmi != null;
24550         }
24551     }
24552 }