OSDN Git Service

RESTRICT AUTOMERGE: Added an app id security check in isAppForeground.
[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     /** All system services */
611     SystemServiceManager mSystemServiceManager;
612     AssistUtils mAssistUtils;
613
614     private Installer mInstaller;
615
616     /** Run all ActivityStacks through this */
617     final ActivityStackSupervisor mStackSupervisor;
618     private final KeyguardController mKeyguardController;
619
620     final ActivityStarter mActivityStarter;
621
622     final TaskChangeNotificationController mTaskChangeNotificationController;
623
624     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
625
626     final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
627
628     public final IntentFirewall mIntentFirewall;
629
630     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
631     // default action automatically.  Important for devices without direct input
632     // devices.
633     private boolean mShowDialogs = true;
634
635     private final VrController mVrController;
636
637     // VR Vr2d Display Id.
638     int mVr2dDisplayId = INVALID_DISPLAY;
639
640     // Whether we should use SCHED_FIFO for UI and RenderThreads.
641     private boolean mUseFifoUiScheduling = false;
642
643     BroadcastQueue mFgBroadcastQueue;
644     BroadcastQueue mBgBroadcastQueue;
645     // Convenient for easy iteration over the queues. Foreground is first
646     // so that dispatch of foreground broadcasts gets precedence.
647     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
648
649     BroadcastStats mLastBroadcastStats;
650     BroadcastStats mCurBroadcastStats;
651
652     BroadcastQueue broadcastQueueForIntent(Intent intent) {
653         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
654         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
655                 "Broadcast intent " + intent + " on "
656                 + (isFg ? "foreground" : "background") + " queue");
657         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
658     }
659
660     /**
661      * The last resumed activity. This is identical to the current resumed activity most
662      * of the time but could be different when we're pausing one activity before we resume
663      * another activity.
664      */
665     private ActivityRecord mLastResumedActivity;
666
667     /**
668      * If non-null, we are tracking the time the user spends in the currently focused app.
669      */
670     private AppTimeTracker mCurAppTimeTracker;
671
672     /**
673      * List of intents that were used to start the most recent tasks.
674      */
675     final RecentTasks mRecentTasks;
676
677     /**
678      * For addAppTask: cached of the last activity component that was added.
679      */
680     ComponentName mLastAddedTaskComponent;
681
682     /**
683      * For addAppTask: cached of the last activity uid that was added.
684      */
685     int mLastAddedTaskUid;
686
687     /**
688      * For addAppTask: cached of the last ActivityInfo that was added.
689      */
690     ActivityInfo mLastAddedTaskActivity;
691
692     /**
693      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
694      */
695     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
696
697     /**
698      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
699      */
700     String mDeviceOwnerName;
701
702     final UserController mUserController;
703
704     final AppErrors mAppErrors;
705
706     /**
707      * Dump of the activity state at the time of the last ANR. Cleared after
708      * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
709      */
710     String mLastANRState;
711
712     /**
713      * Indicates the maximum time spent waiting for the network rules to get updated.
714      */
715     @VisibleForTesting
716     long mWaitForNetworkTimeoutMs;
717
718     public boolean canShowErrorDialogs() {
719         return mShowDialogs && !mSleeping && !mShuttingDown
720                 && !mKeyguardController.isKeyguardShowing();
721     }
722
723     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
724             THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
725
726     static void boostPriorityForLockedSection() {
727         sThreadPriorityBooster.boost();
728     }
729
730     static void resetPriorityAfterLockedSection() {
731         sThreadPriorityBooster.reset();
732     }
733
734     public class PendingAssistExtras extends Binder implements Runnable {
735         public final ActivityRecord activity;
736         public boolean isHome;
737         public final Bundle extras;
738         public final Intent intent;
739         public final String hint;
740         public final IResultReceiver receiver;
741         public final int userHandle;
742         public boolean haveResult = false;
743         public Bundle result = null;
744         public AssistStructure structure = null;
745         public AssistContent content = null;
746         public Bundle receiverExtras;
747
748         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
749                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
750             activity = _activity;
751             extras = _extras;
752             intent = _intent;
753             hint = _hint;
754             receiver = _receiver;
755             receiverExtras = _receiverExtras;
756             userHandle = _userHandle;
757         }
758
759         @Override
760         public void run() {
761             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
762             synchronized (this) {
763                 haveResult = true;
764                 notifyAll();
765             }
766             pendingAssistExtrasTimedOut(this);
767         }
768     }
769
770     final ArrayList<PendingAssistExtras> mPendingAssistExtras
771             = new ArrayList<PendingAssistExtras>();
772
773     /**
774      * Process management.
775      */
776     final ProcessList mProcessList = new ProcessList();
777
778     /**
779      * All of the applications we currently have running organized by name.
780      * The keys are strings of the application package name (as
781      * returned by the package manager), and the keys are ApplicationRecord
782      * objects.
783      */
784     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
785
786     /**
787      * Tracking long-term execution of processes to look for abuse and other
788      * bad app behavior.
789      */
790     final ProcessStatsService mProcessStats;
791
792     /**
793      * The currently running isolated processes.
794      */
795     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
796
797     /**
798      * Counter for assigning isolated process uids, to avoid frequently reusing the
799      * same ones.
800      */
801     int mNextIsolatedProcessUid = 0;
802
803     /**
804      * The currently running heavy-weight process, if any.
805      */
806     ProcessRecord mHeavyWeightProcess = null;
807
808     /**
809      * Non-persistent appId whitelist for background restrictions
810      */
811     int[] mBackgroundAppIdWhitelist = new int[] {
812             BLUETOOTH_UID
813     };
814
815     /**
816      * Broadcast actions that will always be deliverable to unlaunched/background apps
817      */
818     ArraySet<String> mBackgroundLaunchBroadcasts;
819
820     /**
821      * All of the processes we currently have running organized by pid.
822      * The keys are the pid running the application.
823      *
824      * <p>NOTE: This object is protected by its own lock, NOT the global
825      * activity manager lock!
826      */
827     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
828
829     /**
830      * All of the processes that have been forced to be important.  The key
831      * is the pid of the caller who requested it (we hold a death
832      * link on it).
833      */
834     abstract class ImportanceToken implements IBinder.DeathRecipient {
835         final int pid;
836         final IBinder token;
837         final String reason;
838
839         ImportanceToken(int _pid, IBinder _token, String _reason) {
840             pid = _pid;
841             token = _token;
842             reason = _reason;
843         }
844
845         @Override
846         public String toString() {
847             return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
848                     + " " + reason + " " + pid + " " + token + " }";
849         }
850     }
851     final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
852
853     /**
854      * List of records for processes that someone had tried to start before the
855      * system was ready.  We don't start them at that point, but ensure they
856      * are started by the time booting is complete.
857      */
858     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
859
860     /**
861      * List of persistent applications that are in the process
862      * of being started.
863      */
864     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
865
866     /**
867      * Processes that are being forcibly torn down.
868      */
869     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
870
871     /**
872      * List of running applications, sorted by recent usage.
873      * The first entry in the list is the least recently used.
874      */
875     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
876
877     /**
878      * Where in mLruProcesses that the processes hosting activities start.
879      */
880     int mLruProcessActivityStart = 0;
881
882     /**
883      * Where in mLruProcesses that the processes hosting services start.
884      * This is after (lower index) than mLruProcessesActivityStart.
885      */
886     int mLruProcessServiceStart = 0;
887
888     /**
889      * List of processes that should gc as soon as things are idle.
890      */
891     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
892
893     /**
894      * Processes we want to collect PSS data from.
895      */
896     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
897
898     private boolean mBinderTransactionTrackingEnabled = false;
899
900     /**
901      * Last time we requested PSS data of all processes.
902      */
903     long mLastFullPssTime = SystemClock.uptimeMillis();
904
905     /**
906      * If set, the next time we collect PSS data we should do a full collection
907      * with data from native processes and the kernel.
908      */
909     boolean mFullPssPending = false;
910
911     /**
912      * This is the process holding what we currently consider to be
913      * the "home" activity.
914      */
915     ProcessRecord mHomeProcess;
916
917     /**
918      * This is the process holding the activity the user last visited that
919      * is in a different process from the one they are currently in.
920      */
921     ProcessRecord mPreviousProcess;
922
923     /**
924      * The time at which the previous process was last visible.
925      */
926     long mPreviousProcessVisibleTime;
927
928     /**
929      * Track all uids that have actively running processes.
930      */
931     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
932
933     /**
934      * This is for verifying the UID report flow.
935      */
936     static final boolean VALIDATE_UID_STATES = true;
937     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
938
939     /**
940      * Packages that the user has asked to have run in screen size
941      * compatibility mode instead of filling the screen.
942      */
943     final CompatModePackages mCompatModePackages;
944
945     /**
946      * Set of IntentSenderRecord objects that are currently active.
947      */
948     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
949             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
950
951     /**
952      * Fingerprints (hashCode()) of stack traces that we've
953      * already logged DropBox entries for.  Guarded by itself.  If
954      * something (rogue user app) forces this over
955      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
956      */
957     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
958     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
959
960     /**
961      * Strict Mode background batched logging state.
962      *
963      * The string buffer is guarded by itself, and its lock is also
964      * used to determine if another batched write is already
965      * in-flight.
966      */
967     private final StringBuilder mStrictModeBuffer = new StringBuilder();
968
969     /**
970      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
971      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
972      */
973     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
974
975     /**
976      * Resolver for broadcast intents to registered receivers.
977      * Holds BroadcastFilter (subclass of IntentFilter).
978      */
979     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
980             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
981         @Override
982         protected boolean allowFilterResult(
983                 BroadcastFilter filter, List<BroadcastFilter> dest) {
984             IBinder target = filter.receiverList.receiver.asBinder();
985             for (int i = dest.size() - 1; i >= 0; i--) {
986                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
987                     return false;
988                 }
989             }
990             return true;
991         }
992
993         @Override
994         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
995             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
996                     || userId == filter.owningUserId) {
997                 return super.newResult(filter, match, userId);
998             }
999             return null;
1000         }
1001
1002         @Override
1003         protected BroadcastFilter[] newArray(int size) {
1004             return new BroadcastFilter[size];
1005         }
1006
1007         @Override
1008         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1009             return packageName.equals(filter.packageName);
1010         }
1011     };
1012
1013     /**
1014      * State of all active sticky broadcasts per user.  Keys are the action of the
1015      * sticky Intent, values are an ArrayList of all broadcasted intents with
1016      * that action (which should usually be one).  The SparseArray is keyed
1017      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1018      * for stickies that are sent to all users.
1019      */
1020     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1021             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1022
1023     final ActiveServices mServices;
1024
1025     final static class Association {
1026         final int mSourceUid;
1027         final String mSourceProcess;
1028         final int mTargetUid;
1029         final ComponentName mTargetComponent;
1030         final String mTargetProcess;
1031
1032         int mCount;
1033         long mTime;
1034
1035         int mNesting;
1036         long mStartTime;
1037
1038         // states of the source process when the bind occurred.
1039         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1040         long mLastStateUptime;
1041         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1042                 - ActivityManager.MIN_PROCESS_STATE+1];
1043
1044         Association(int sourceUid, String sourceProcess, int targetUid,
1045                 ComponentName targetComponent, String targetProcess) {
1046             mSourceUid = sourceUid;
1047             mSourceProcess = sourceProcess;
1048             mTargetUid = targetUid;
1049             mTargetComponent = targetComponent;
1050             mTargetProcess = targetProcess;
1051         }
1052     }
1053
1054     /**
1055      * When service association tracking is enabled, this is all of the associations we
1056      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1057      * -> association data.
1058      */
1059     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1060             mAssociations = new SparseArray<>();
1061     boolean mTrackingAssociations;
1062
1063     /**
1064      * Backup/restore process management
1065      */
1066     String mBackupAppName = null;
1067     BackupRecord mBackupTarget = null;
1068
1069     final ProviderMap mProviderMap;
1070
1071     /**
1072      * List of content providers who have clients waiting for them.  The
1073      * application is currently being launched and the provider will be
1074      * removed from this list once it is published.
1075      */
1076     final ArrayList<ContentProviderRecord> mLaunchingProviders
1077             = new ArrayList<ContentProviderRecord>();
1078
1079     /**
1080      * File storing persisted {@link #mGrantedUriPermissions}.
1081      */
1082     private final AtomicFile mGrantFile;
1083
1084     /** XML constants used in {@link #mGrantFile} */
1085     private static final String TAG_URI_GRANTS = "uri-grants";
1086     private static final String TAG_URI_GRANT = "uri-grant";
1087     private static final String ATTR_USER_HANDLE = "userHandle";
1088     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1089     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1090     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1091     private static final String ATTR_TARGET_PKG = "targetPkg";
1092     private static final String ATTR_URI = "uri";
1093     private static final String ATTR_MODE_FLAGS = "modeFlags";
1094     private static final String ATTR_CREATED_TIME = "createdTime";
1095     private static final String ATTR_PREFIX = "prefix";
1096
1097     /**
1098      * Global set of specific {@link Uri} permissions that have been granted.
1099      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1100      * to {@link UriPermission#uri} to {@link UriPermission}.
1101      */
1102     @GuardedBy("this")
1103     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1104             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1105
1106     public static class GrantUri {
1107         public final int sourceUserId;
1108         public final Uri uri;
1109         public boolean prefix;
1110
1111         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1112             this.sourceUserId = sourceUserId;
1113             this.uri = uri;
1114             this.prefix = prefix;
1115         }
1116
1117         @Override
1118         public int hashCode() {
1119             int hashCode = 1;
1120             hashCode = 31 * hashCode + sourceUserId;
1121             hashCode = 31 * hashCode + uri.hashCode();
1122             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1123             return hashCode;
1124         }
1125
1126         @Override
1127         public boolean equals(Object o) {
1128             if (o instanceof GrantUri) {
1129                 GrantUri other = (GrantUri) o;
1130                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1131                         && prefix == other.prefix;
1132             }
1133             return false;
1134         }
1135
1136         @Override
1137         public String toString() {
1138             String result = uri.toString() + " [user " + sourceUserId + "]";
1139             if (prefix) result += " [prefix]";
1140             return result;
1141         }
1142
1143         public String toSafeString() {
1144             String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1145             if (prefix) result += " [prefix]";
1146             return result;
1147         }
1148
1149         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1150             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1151                     ContentProvider.getUriWithoutUserId(uri), false);
1152         }
1153     }
1154
1155     CoreSettingsObserver mCoreSettingsObserver;
1156
1157     FontScaleSettingObserver mFontScaleSettingObserver;
1158
1159     private final class FontScaleSettingObserver extends ContentObserver {
1160         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1161
1162         public FontScaleSettingObserver() {
1163             super(mHandler);
1164             ContentResolver resolver = mContext.getContentResolver();
1165             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1166         }
1167
1168         @Override
1169         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1170             if (mFontScaleUri.equals(uri)) {
1171                 updateFontScaleIfNeeded(userId);
1172             }
1173         }
1174     }
1175
1176     /**
1177      * Thread-local storage used to carry caller permissions over through
1178      * indirect content-provider access.
1179      */
1180     private class Identity {
1181         public final IBinder token;
1182         public final int pid;
1183         public final int uid;
1184
1185         Identity(IBinder _token, int _pid, int _uid) {
1186             token = _token;
1187             pid = _pid;
1188             uid = _uid;
1189         }
1190     }
1191
1192     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1193
1194     /**
1195      * All information we have collected about the runtime performance of
1196      * any user id that can impact battery performance.
1197      */
1198     final BatteryStatsService mBatteryStatsService;
1199
1200     /**
1201      * Information about component usage
1202      */
1203     UsageStatsManagerInternal mUsageStatsService;
1204
1205     /**
1206      * Access to DeviceIdleController service.
1207      */
1208     DeviceIdleController.LocalService mLocalDeviceIdleController;
1209
1210     /**
1211      * Set of app ids that are whitelisted for device idle and thus background check.
1212      */
1213     int[] mDeviceIdleWhitelist = new int[0];
1214
1215     /**
1216      * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1217      */
1218     int[] mDeviceIdleTempWhitelist = new int[0];
1219
1220     static final class PendingTempWhitelist {
1221         final int targetUid;
1222         final long duration;
1223         final String tag;
1224
1225         PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1226             targetUid = _targetUid;
1227             duration = _duration;
1228             tag = _tag;
1229         }
1230     }
1231
1232     final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1233
1234     /**
1235      * Information about and control over application operations
1236      */
1237     final AppOpsService mAppOpsService;
1238
1239     /** Current sequencing integer of the configuration, for skipping old configurations. */
1240     private int mConfigurationSeq;
1241
1242     /**
1243      * Temp object used when global and/or display override configuration is updated. It is also
1244      * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1245      * anyone...
1246      */
1247     private Configuration mTempConfig = new Configuration();
1248
1249     private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1250             new UpdateConfigurationResult();
1251     private static final class UpdateConfigurationResult {
1252         // Configuration changes that were updated.
1253         int changes;
1254         // If the activity was relaunched to match the new configuration.
1255         boolean activityRelaunched;
1256
1257         void reset() {
1258             changes = 0;
1259             activityRelaunched = false;
1260         }
1261     }
1262
1263     boolean mSuppressResizeConfigChanges;
1264
1265     /**
1266      * Hardware-reported OpenGLES version.
1267      */
1268     final int GL_ES_VERSION;
1269
1270     /**
1271      * List of initialization arguments to pass to all processes when binding applications to them.
1272      * For example, references to the commonly used services.
1273      */
1274     HashMap<String, IBinder> mAppBindArgs;
1275     HashMap<String, IBinder> mIsolatedAppBindArgs;
1276
1277     /**
1278      * Temporary to avoid allocations.  Protected by main lock.
1279      */
1280     final StringBuilder mStringBuilder = new StringBuilder(256);
1281
1282     /**
1283      * Used to control how we initialize the service.
1284      */
1285     ComponentName mTopComponent;
1286     String mTopAction = Intent.ACTION_MAIN;
1287     String mTopData;
1288
1289     volatile boolean mProcessesReady = false;
1290     volatile boolean mSystemReady = false;
1291     volatile boolean mOnBattery = false;
1292     volatile int mFactoryTest;
1293
1294     @GuardedBy("this") boolean mBooting = false;
1295     @GuardedBy("this") boolean mCallFinishBooting = false;
1296     @GuardedBy("this") boolean mBootAnimationComplete = false;
1297     @GuardedBy("this") boolean mLaunchWarningShown = false;
1298     @GuardedBy("this") boolean mCheckedForSetup = false;
1299
1300     final Context mContext;
1301
1302     /**
1303      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1304      * change at runtime. Use mContext for non-UI purposes.
1305      */
1306     final Context mUiContext;
1307
1308     /**
1309      * The time at which we will allow normal application switches again,
1310      * after a call to {@link #stopAppSwitches()}.
1311      */
1312     long mAppSwitchesAllowedTime;
1313
1314     /**
1315      * This is set to true after the first switch after mAppSwitchesAllowedTime
1316      * is set; any switches after that will clear the time.
1317      */
1318     boolean mDidAppSwitch;
1319
1320     /**
1321      * Last time (in realtime) at which we checked for power usage.
1322      */
1323     long mLastPowerCheckRealtime;
1324
1325     /**
1326      * Last time (in uptime) at which we checked for power usage.
1327      */
1328     long mLastPowerCheckUptime;
1329
1330     /**
1331      * Set while we are wanting to sleep, to prevent any
1332      * activities from being started/resumed.
1333      *
1334      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1335      *
1336      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1337      * while in the sleep state until there is a pending transition out of sleep, in which case
1338      * mSleeping is set to false, and remains false while awake.
1339      *
1340      * Whether mSleeping can quickly toggled between true/false without the device actually
1341      * display changing states is undefined.
1342      */
1343     private boolean mSleeping = false;
1344
1345     /**
1346      * The process state used for processes that are running the top activities.
1347      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1348      */
1349     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1350
1351     /**
1352      * Set while we are running a voice interaction.  This overrides
1353      * sleeping while it is active.
1354      */
1355     private IVoiceInteractionSession mRunningVoice;
1356
1357     /**
1358      * For some direct access we need to power manager.
1359      */
1360     PowerManagerInternal mLocalPowerManager;
1361
1362     /**
1363      * We want to hold a wake lock while running a voice interaction session, since
1364      * this may happen with the screen off and we need to keep the CPU running to
1365      * be able to continue to interact with the user.
1366      */
1367     PowerManager.WakeLock mVoiceWakeLock;
1368
1369     /**
1370      * State of external calls telling us if the device is awake or asleep.
1371      */
1372     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1373
1374     /**
1375      * A list of tokens that cause the top activity to be put to sleep.
1376      * They are used by components that may hide and block interaction with underlying
1377      * activities.
1378      */
1379     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1380
1381     /**
1382      * Set if we are shutting down the system, similar to sleeping.
1383      */
1384     boolean mShuttingDown = false;
1385
1386     /**
1387      * Current sequence id for oom_adj computation traversal.
1388      */
1389     int mAdjSeq = 0;
1390
1391     /**
1392      * Current sequence id for process LRU updating.
1393      */
1394     int mLruSeq = 0;
1395
1396     /**
1397      * Keep track of the non-cached/empty process we last found, to help
1398      * determine how to distribute cached/empty processes next time.
1399      */
1400     int mNumNonCachedProcs = 0;
1401
1402     /**
1403      * Keep track of the number of cached hidden procs, to balance oom adj
1404      * distribution between those and empty procs.
1405      */
1406     int mNumCachedHiddenProcs = 0;
1407
1408     /**
1409      * Keep track of the number of service processes we last found, to
1410      * determine on the next iteration which should be B services.
1411      */
1412     int mNumServiceProcs = 0;
1413     int mNewNumAServiceProcs = 0;
1414     int mNewNumServiceProcs = 0;
1415
1416     /**
1417      * Allow the current computed overall memory level of the system to go down?
1418      * This is set to false when we are killing processes for reasons other than
1419      * memory management, so that the now smaller process list will not be taken as
1420      * an indication that memory is tighter.
1421      */
1422     boolean mAllowLowerMemLevel = false;
1423
1424     /**
1425      * The last computed memory level, for holding when we are in a state that
1426      * processes are going away for other reasons.
1427      */
1428     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1429
1430     /**
1431      * The last total number of process we have, to determine if changes actually look
1432      * like a shrinking number of process due to lower RAM.
1433      */
1434     int mLastNumProcesses;
1435
1436     /**
1437      * The uptime of the last time we performed idle maintenance.
1438      */
1439     long mLastIdleTime = SystemClock.uptimeMillis();
1440
1441     /**
1442      * Total time spent with RAM that has been added in the past since the last idle time.
1443      */
1444     long mLowRamTimeSinceLastIdle = 0;
1445
1446     /**
1447      * If RAM is currently low, when that horrible situation started.
1448      */
1449     long mLowRamStartTime = 0;
1450
1451     /**
1452      * For reporting to battery stats the current top application.
1453      */
1454     private String mCurResumedPackage = null;
1455     private int mCurResumedUid = -1;
1456
1457     /**
1458      * For reporting to battery stats the apps currently running foreground
1459      * service.  The ProcessMap is package/uid tuples; each of these contain
1460      * an array of the currently foreground processes.
1461      */
1462     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1463             = new ProcessMap<ArrayList<ProcessRecord>>();
1464
1465     /**
1466      * This is set if we had to do a delayed dexopt of an app before launching
1467      * it, to increase the ANR timeouts in that case.
1468      */
1469     boolean mDidDexOpt;
1470
1471     /**
1472      * Set if the systemServer made a call to enterSafeMode.
1473      */
1474     boolean mSafeMode;
1475
1476     /**
1477      * If true, we are running under a test environment so will sample PSS from processes
1478      * much more rapidly to try to collect better data when the tests are rapidly
1479      * running through apps.
1480      */
1481     boolean mTestPssMode = false;
1482
1483     String mDebugApp = null;
1484     boolean mWaitForDebugger = false;
1485     boolean mDebugTransient = false;
1486     String mOrigDebugApp = null;
1487     boolean mOrigWaitForDebugger = false;
1488     boolean mAlwaysFinishActivities = false;
1489     boolean mForceResizableActivities;
1490     /**
1491      * Flag that indicates if multi-window is enabled.
1492      *
1493      * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1494      * in {@link com.android.internal.R.bool.config_supportsMultiWindow} config or
1495      * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1496      * At least one of the forms of multi-window must be enabled in order for this flag to be
1497      * initialized to 'true'.
1498      *
1499      * @see #mSupportsSplitScreenMultiWindow
1500      * @see #mSupportsFreeformWindowManagement
1501      * @see #mSupportsPictureInPicture
1502      * @see #mSupportsMultiDisplay
1503      */
1504     boolean mSupportsMultiWindow;
1505     boolean mSupportsSplitScreenMultiWindow;
1506     boolean mSupportsFreeformWindowManagement;
1507     boolean mSupportsPictureInPicture;
1508     boolean mSupportsMultiDisplay;
1509     boolean mSupportsLeanbackOnly;
1510     IActivityController mController = null;
1511     boolean mControllerIsAMonkey = false;
1512     String mProfileApp = null;
1513     ProcessRecord mProfileProc = null;
1514     String mProfileFile;
1515     ParcelFileDescriptor mProfileFd;
1516     int mSamplingInterval = 0;
1517     boolean mAutoStopProfiler = false;
1518     boolean mStreamingOutput = false;
1519     int mProfileType = 0;
1520     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1521     String mMemWatchDumpProcName;
1522     String mMemWatchDumpFile;
1523     int mMemWatchDumpPid;
1524     int mMemWatchDumpUid;
1525     String mTrackAllocationApp = null;
1526     String mNativeDebuggingApp = null;
1527
1528     final long[] mTmpLong = new long[2];
1529
1530     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1531
1532     /**
1533      * A global counter for generating sequence numbers.
1534      * This value will be used when incrementing sequence numbers in individual uidRecords.
1535      *
1536      * Having a global counter ensures that seq numbers are monotonically increasing for a
1537      * particular uid even when the uidRecord is re-created.
1538      */
1539     @GuardedBy("this")
1540     @VisibleForTesting
1541     long mProcStateSeqCounter = 0;
1542
1543     private final Injector mInjector;
1544
1545     static final class ProcessChangeItem {
1546         static final int CHANGE_ACTIVITIES = 1<<0;
1547         int changes;
1548         int uid;
1549         int pid;
1550         int processState;
1551         boolean foregroundActivities;
1552     }
1553
1554     static final class UidObserverRegistration {
1555         final int uid;
1556         final String pkg;
1557         final int which;
1558         final int cutpoint;
1559
1560         final SparseIntArray lastProcStates;
1561
1562         UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1563             uid = _uid;
1564             pkg = _pkg;
1565             which = _which;
1566             cutpoint = _cutpoint;
1567             if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1568                 lastProcStates = new SparseIntArray();
1569             } else {
1570                 lastProcStates = null;
1571             }
1572         }
1573     }
1574
1575     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1576     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1577
1578     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1579     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1580
1581     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1582     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1583
1584     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1585     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1586
1587     /**
1588      * Runtime CPU use collection thread.  This object's lock is used to
1589      * perform synchronization with the thread (notifying it to run).
1590      */
1591     final Thread mProcessCpuThread;
1592
1593     /**
1594      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1595      * Must acquire this object's lock when accessing it.
1596      * NOTE: this lock will be held while doing long operations (trawling
1597      * through all processes in /proc), so it should never be acquired by
1598      * any critical paths such as when holding the main activity manager lock.
1599      */
1600     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1601             MONITOR_THREAD_CPU_USAGE);
1602     final AtomicLong mLastCpuTime = new AtomicLong(0);
1603     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1604     final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1605
1606     long mLastWriteTime = 0;
1607
1608     /**
1609      * Used to retain an update lock when the foreground activity is in
1610      * immersive mode.
1611      */
1612     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1613
1614     /**
1615      * Set to true after the system has finished booting.
1616      */
1617     boolean mBooted = false;
1618
1619     WindowManagerService mWindowManager;
1620     final ActivityThread mSystemThread;
1621
1622     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1623         final ProcessRecord mApp;
1624         final int mPid;
1625         final IApplicationThread mAppThread;
1626
1627         AppDeathRecipient(ProcessRecord app, int pid,
1628                 IApplicationThread thread) {
1629             if (DEBUG_ALL) Slog.v(
1630                 TAG, "New death recipient " + this
1631                 + " for thread " + thread.asBinder());
1632             mApp = app;
1633             mPid = pid;
1634             mAppThread = thread;
1635         }
1636
1637         @Override
1638         public void binderDied() {
1639             if (DEBUG_ALL) Slog.v(
1640                 TAG, "Death received in " + this
1641                 + " for thread " + mAppThread.asBinder());
1642             synchronized(ActivityManagerService.this) {
1643                 appDiedLocked(mApp, mPid, mAppThread, true);
1644             }
1645         }
1646     }
1647
1648     static final int SHOW_ERROR_UI_MSG = 1;
1649     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1650     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1651     static final int UPDATE_CONFIGURATION_MSG = 4;
1652     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1653     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1654     static final int SERVICE_TIMEOUT_MSG = 12;
1655     static final int UPDATE_TIME_ZONE = 13;
1656     static final int SHOW_UID_ERROR_UI_MSG = 14;
1657     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1658     static final int PROC_START_TIMEOUT_MSG = 20;
1659     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1660     static final int KILL_APPLICATION_MSG = 22;
1661     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1662     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1663     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1664     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1665     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1666     static final int CLEAR_DNS_CACHE_MSG = 28;
1667     static final int UPDATE_HTTP_PROXY_MSG = 29;
1668     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1669     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1670     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1671     static final int REPORT_MEM_USAGE_MSG = 33;
1672     static final int REPORT_USER_SWITCH_MSG = 34;
1673     static final int CONTINUE_USER_SWITCH_MSG = 35;
1674     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1675     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1676     static final int PERSIST_URI_GRANTS_MSG = 38;
1677     static final int REQUEST_ALL_PSS_MSG = 39;
1678     static final int START_PROFILES_MSG = 40;
1679     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1680     static final int SYSTEM_USER_START_MSG = 42;
1681     static final int SYSTEM_USER_CURRENT_MSG = 43;
1682     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1683     static final int FINISH_BOOTING_MSG = 45;
1684     static final int START_USER_SWITCH_UI_MSG = 46;
1685     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1686     static final int DISMISS_DIALOG_UI_MSG = 48;
1687     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1688     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1689     static final int DELETE_DUMPHEAP_MSG = 51;
1690     static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1691     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1692     static final int REPORT_TIME_TRACKER_MSG = 54;
1693     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1694     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1695     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1696     static final int IDLE_UIDS_MSG = 58;
1697     static final int SYSTEM_USER_UNLOCK_MSG = 59;
1698     static final int LOG_STACK_STATE = 60;
1699     static final int VR_MODE_CHANGE_MSG = 61;
1700     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1701     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1702     static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1703     static final int NOTIFY_VR_SLEEPING_MSG = 65;
1704     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1705     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1706     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1707     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1708     static final int START_USER_SWITCH_FG_MSG = 712;
1709
1710     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1711     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1712     static final int FIRST_COMPAT_MODE_MSG = 300;
1713     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1714
1715     static ServiceThread sKillThread = null;
1716     static KillHandler sKillHandler = null;
1717
1718     CompatModeDialog mCompatModeDialog;
1719     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1720     long mLastMemUsageReportTime = 0;
1721
1722     /**
1723      * Flag whether the current user is a "monkey", i.e. whether
1724      * the UI is driven by a UI automation tool.
1725      */
1726     private boolean mUserIsMonkey;
1727
1728     /** Flag whether the device has a Recents UI */
1729     boolean mHasRecents;
1730
1731     /** The dimensions of the thumbnails in the Recents UI. */
1732     int mThumbnailWidth;
1733     int mThumbnailHeight;
1734     float mFullscreenThumbnailScale;
1735
1736     final ServiceThread mHandlerThread;
1737     final MainHandler mHandler;
1738     final Handler mUiHandler;
1739
1740     final ActivityManagerConstants mConstants;
1741
1742     PackageManagerInternal mPackageManagerInt;
1743
1744     // VoiceInteraction session ID that changes for each new request except when
1745     // being called for multiwindow assist in a single session.
1746     private int mViSessionId = 1000;
1747
1748     final boolean mPermissionReviewRequired;
1749
1750     /**
1751      * Current global configuration information. Contains general settings for the entire system,
1752      * also corresponds to the merged configuration of the default display.
1753      */
1754     Configuration getGlobalConfiguration() {
1755         return mStackSupervisor.getConfiguration();
1756     }
1757
1758     final class KillHandler extends Handler {
1759         static final int KILL_PROCESS_GROUP_MSG = 4000;
1760
1761         public KillHandler(Looper looper) {
1762             super(looper, null, true);
1763         }
1764
1765         @Override
1766         public void handleMessage(Message msg) {
1767             switch (msg.what) {
1768                 case KILL_PROCESS_GROUP_MSG:
1769                 {
1770                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1771                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1772                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1773                 }
1774                 break;
1775
1776                 default:
1777                     super.handleMessage(msg);
1778             }
1779         }
1780     }
1781
1782     final class UiHandler extends Handler {
1783         public UiHandler() {
1784             super(com.android.server.UiThread.get().getLooper(), null, true);
1785         }
1786
1787         @Override
1788         public void handleMessage(Message msg) {
1789             switch (msg.what) {
1790             case SHOW_ERROR_UI_MSG: {
1791                 mAppErrors.handleShowAppErrorUi(msg);
1792                 ensureBootCompleted();
1793             } break;
1794             case SHOW_NOT_RESPONDING_UI_MSG: {
1795                 mAppErrors.handleShowAnrUi(msg);
1796                 ensureBootCompleted();
1797             } break;
1798             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1799                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1800                 synchronized (ActivityManagerService.this) {
1801                     ProcessRecord proc = (ProcessRecord) data.get("app");
1802                     if (proc == null) {
1803                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1804                         break;
1805                     }
1806                     if (proc.crashDialog != null) {
1807                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1808                         return;
1809                     }
1810                     AppErrorResult res = (AppErrorResult) data.get("result");
1811                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1812                         Dialog d = new StrictModeViolationDialog(mUiContext,
1813                                 ActivityManagerService.this, res, proc);
1814                         d.show();
1815                         proc.crashDialog = d;
1816                     } else {
1817                         // The device is asleep, so just pretend that the user
1818                         // saw a crash dialog and hit "force quit".
1819                         res.set(0);
1820                     }
1821                 }
1822                 ensureBootCompleted();
1823             } break;
1824             case SHOW_FACTORY_ERROR_UI_MSG: {
1825                 Dialog d = new FactoryErrorDialog(
1826                         mUiContext, msg.getData().getCharSequence("msg"));
1827                 d.show();
1828                 ensureBootCompleted();
1829             } break;
1830             case WAIT_FOR_DEBUGGER_UI_MSG: {
1831                 synchronized (ActivityManagerService.this) {
1832                     ProcessRecord app = (ProcessRecord)msg.obj;
1833                     if (msg.arg1 != 0) {
1834                         if (!app.waitedForDebugger) {
1835                             Dialog d = new AppWaitingForDebuggerDialog(
1836                                     ActivityManagerService.this,
1837                                     mUiContext, app);
1838                             app.waitDialog = d;
1839                             app.waitedForDebugger = true;
1840                             d.show();
1841                         }
1842                     } else {
1843                         if (app.waitDialog != null) {
1844                             app.waitDialog.dismiss();
1845                             app.waitDialog = null;
1846                         }
1847                     }
1848                 }
1849             } break;
1850             case SHOW_UID_ERROR_UI_MSG: {
1851                 if (mShowDialogs) {
1852                     AlertDialog d = new BaseErrorDialog(mUiContext);
1853                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1854                     d.setCancelable(false);
1855                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1856                     d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1857                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1858                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1859                     d.show();
1860                 }
1861             } break;
1862             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1863                 if (mShowDialogs) {
1864                     AlertDialog d = new BaseErrorDialog(mUiContext);
1865                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1866                     d.setCancelable(false);
1867                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1868                     d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1869                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1870                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1871                     d.show();
1872                 }
1873             } break;
1874             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1875                 synchronized (ActivityManagerService.this) {
1876                     ActivityRecord ar = (ActivityRecord) msg.obj;
1877                     if (mCompatModeDialog != null) {
1878                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1879                                 ar.info.applicationInfo.packageName)) {
1880                             return;
1881                         }
1882                         mCompatModeDialog.dismiss();
1883                         mCompatModeDialog = null;
1884                     }
1885                     if (ar != null && false) {
1886                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1887                                 ar.packageName)) {
1888                             int mode = mCompatModePackages.computeCompatModeLocked(
1889                                     ar.info.applicationInfo);
1890                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1891                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1892                                 mCompatModeDialog = new CompatModeDialog(
1893                                         ActivityManagerService.this, mUiContext,
1894                                         ar.info.applicationInfo);
1895                                 mCompatModeDialog.show();
1896                             }
1897                         }
1898                     }
1899                 }
1900                 break;
1901             }
1902             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1903                 synchronized (ActivityManagerService.this) {
1904                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1905                     if (mUnsupportedDisplaySizeDialog != null) {
1906                         mUnsupportedDisplaySizeDialog.dismiss();
1907                         mUnsupportedDisplaySizeDialog = null;
1908                     }
1909                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1910                             ar.packageName)) {
1911                         // TODO(multi-display): Show dialog on appropriate display.
1912                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1913                                 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1914                         mUnsupportedDisplaySizeDialog.show();
1915                     }
1916                 }
1917                 break;
1918             }
1919             case START_USER_SWITCH_UI_MSG: {
1920                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1921                 break;
1922             }
1923             case DISMISS_DIALOG_UI_MSG: {
1924                 final Dialog d = (Dialog) msg.obj;
1925                 d.dismiss();
1926                 break;
1927             }
1928             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1929                 dispatchProcessesChanged();
1930                 break;
1931             }
1932             case DISPATCH_PROCESS_DIED_UI_MSG: {
1933                 final int pid = msg.arg1;
1934                 final int uid = msg.arg2;
1935                 dispatchProcessDied(pid, uid);
1936                 break;
1937             }
1938             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1939                 dispatchUidsChanged();
1940             } break;
1941             case PUSH_TEMP_WHITELIST_UI_MSG: {
1942                 pushTempWhitelist();
1943             } break;
1944             }
1945         }
1946     }
1947
1948     final class MainHandler extends Handler {
1949         public MainHandler(Looper looper) {
1950             super(looper, null, true);
1951         }
1952
1953         @Override
1954         public void handleMessage(Message msg) {
1955             switch (msg.what) {
1956             case UPDATE_CONFIGURATION_MSG: {
1957                 final ContentResolver resolver = mContext.getContentResolver();
1958                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1959                         msg.arg1);
1960             } break;
1961             case GC_BACKGROUND_PROCESSES_MSG: {
1962                 synchronized (ActivityManagerService.this) {
1963                     performAppGcsIfAppropriateLocked();
1964                 }
1965             } break;
1966             case SERVICE_TIMEOUT_MSG: {
1967                 if (mDidDexOpt) {
1968                     mDidDexOpt = false;
1969                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1970                     nmsg.obj = msg.obj;
1971                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1972                     return;
1973                 }
1974                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1975             } break;
1976             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1977                 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1978             } break;
1979             case SERVICE_FOREGROUND_CRASH_MSG: {
1980                 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1981             } break;
1982             case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1983                 RemoteCallbackList<IResultReceiver> callbacks
1984                         = (RemoteCallbackList<IResultReceiver>)msg.obj;
1985                 int N = callbacks.beginBroadcast();
1986                 for (int i = 0; i < N; i++) {
1987                     try {
1988                         callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1989                     } catch (RemoteException e) {
1990                     }
1991                 }
1992                 callbacks.finishBroadcast();
1993             } break;
1994             case UPDATE_TIME_ZONE: {
1995                 synchronized (ActivityManagerService.this) {
1996                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1997                         ProcessRecord r = mLruProcesses.get(i);
1998                         if (r.thread != null) {
1999                             try {
2000                                 r.thread.updateTimeZone();
2001                             } catch (RemoteException ex) {
2002                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2003                             }
2004                         }
2005                     }
2006                 }
2007             } break;
2008             case CLEAR_DNS_CACHE_MSG: {
2009                 synchronized (ActivityManagerService.this) {
2010                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2011                         ProcessRecord r = mLruProcesses.get(i);
2012                         if (r.thread != null) {
2013                             try {
2014                                 r.thread.clearDnsCache();
2015                             } catch (RemoteException ex) {
2016                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2017                             }
2018                         }
2019                     }
2020                 }
2021             } break;
2022             case UPDATE_HTTP_PROXY_MSG: {
2023                 ProxyInfo proxy = (ProxyInfo)msg.obj;
2024                 String host = "";
2025                 String port = "";
2026                 String exclList = "";
2027                 Uri pacFileUrl = Uri.EMPTY;
2028                 if (proxy != null) {
2029                     host = proxy.getHost();
2030                     port = Integer.toString(proxy.getPort());
2031                     exclList = proxy.getExclusionListAsString();
2032                     pacFileUrl = proxy.getPacFileUrl();
2033                 }
2034                 synchronized (ActivityManagerService.this) {
2035                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2036                         ProcessRecord r = mLruProcesses.get(i);
2037                         if (r.thread != null) {
2038                             try {
2039                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2040                             } catch (RemoteException ex) {
2041                                 Slog.w(TAG, "Failed to update http proxy for: " +
2042                                         r.info.processName);
2043                             }
2044                         }
2045                     }
2046                 }
2047             } break;
2048             case PROC_START_TIMEOUT_MSG: {
2049                 if (mDidDexOpt) {
2050                     mDidDexOpt = false;
2051                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2052                     nmsg.obj = msg.obj;
2053                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
2054                     return;
2055                 }
2056                 ProcessRecord app = (ProcessRecord)msg.obj;
2057                 synchronized (ActivityManagerService.this) {
2058                     processStartTimedOutLocked(app);
2059                 }
2060             } break;
2061             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2062                 ProcessRecord app = (ProcessRecord)msg.obj;
2063                 synchronized (ActivityManagerService.this) {
2064                     processContentProviderPublishTimedOutLocked(app);
2065                 }
2066             } break;
2067             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2068                 synchronized (ActivityManagerService.this) {
2069                     mActivityStarter.doPendingActivityLaunchesLocked(true);
2070                 }
2071             } break;
2072             case KILL_APPLICATION_MSG: {
2073                 synchronized (ActivityManagerService.this) {
2074                     final int appId = msg.arg1;
2075                     final int userId = msg.arg2;
2076                     Bundle bundle = (Bundle)msg.obj;
2077                     String pkg = bundle.getString("pkg");
2078                     String reason = bundle.getString("reason");
2079                     forceStopPackageLocked(pkg, appId, false, false, true, false,
2080                             false, userId, reason);
2081                 }
2082             } break;
2083             case FINALIZE_PENDING_INTENT_MSG: {
2084                 ((PendingIntentRecord)msg.obj).completeFinalize();
2085             } break;
2086             case POST_HEAVY_NOTIFICATION_MSG: {
2087                 INotificationManager inm = NotificationManager.getService();
2088                 if (inm == null) {
2089                     return;
2090                 }
2091
2092                 ActivityRecord root = (ActivityRecord)msg.obj;
2093                 ProcessRecord process = root.app;
2094                 if (process == null) {
2095                     return;
2096                 }
2097
2098                 try {
2099                     Context context = mContext.createPackageContext(process.info.packageName, 0);
2100                     String text = mContext.getString(R.string.heavy_weight_notification,
2101                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
2102                     Notification notification =
2103                             new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2104                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2105                             .setWhen(0)
2106                             .setOngoing(true)
2107                             .setTicker(text)
2108                             .setColor(mContext.getColor(
2109                                     com.android.internal.R.color.system_notification_accent_color))
2110                             .setContentTitle(text)
2111                             .setContentText(
2112                                     mContext.getText(R.string.heavy_weight_notification_detail))
2113                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2114                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2115                                     new UserHandle(root.userId)))
2116                             .build();
2117                     try {
2118                         inm.enqueueNotificationWithTag("android", "android", null,
2119                                 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2120                                 notification, root.userId);
2121                     } catch (RuntimeException e) {
2122                         Slog.w(ActivityManagerService.TAG,
2123                                 "Error showing notification for heavy-weight app", e);
2124                     } catch (RemoteException e) {
2125                     }
2126                 } catch (NameNotFoundException e) {
2127                     Slog.w(TAG, "Unable to create context for heavy notification", e);
2128                 }
2129             } break;
2130             case CANCEL_HEAVY_NOTIFICATION_MSG: {
2131                 INotificationManager inm = NotificationManager.getService();
2132                 if (inm == null) {
2133                     return;
2134                 }
2135                 try {
2136                     inm.cancelNotificationWithTag("android", null,
2137                             SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2138                 } catch (RuntimeException e) {
2139                     Slog.w(ActivityManagerService.TAG,
2140                             "Error canceling notification for service", e);
2141                 } catch (RemoteException e) {
2142                 }
2143             } break;
2144             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2145                 synchronized (ActivityManagerService.this) {
2146                     checkExcessivePowerUsageLocked(true);
2147                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2148                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2149                     sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
2150                 }
2151             } break;
2152             case REPORT_MEM_USAGE_MSG: {
2153                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2154                 Thread thread = new Thread() {
2155                     @Override public void run() {
2156                         reportMemUsage(memInfos);
2157                     }
2158                 };
2159                 thread.start();
2160                 break;
2161             }
2162             case START_USER_SWITCH_FG_MSG: {
2163                 mUserController.startUserInForeground(msg.arg1);
2164                 break;
2165             }
2166             case REPORT_USER_SWITCH_MSG: {
2167                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2168                 break;
2169             }
2170             case CONTINUE_USER_SWITCH_MSG: {
2171                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2172                 break;
2173             }
2174             case USER_SWITCH_TIMEOUT_MSG: {
2175                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2176                 break;
2177             }
2178             case IMMERSIVE_MODE_LOCK_MSG: {
2179                 final boolean nextState = (msg.arg1 != 0);
2180                 if (mUpdateLock.isHeld() != nextState) {
2181                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2182                             "Applying new update lock state '" + nextState
2183                             + "' for " + (ActivityRecord)msg.obj);
2184                     if (nextState) {
2185                         mUpdateLock.acquire();
2186                     } else {
2187                         mUpdateLock.release();
2188                     }
2189                 }
2190                 break;
2191             }
2192             case PERSIST_URI_GRANTS_MSG: {
2193                 writeGrantedUriPermissions();
2194                 break;
2195             }
2196             case REQUEST_ALL_PSS_MSG: {
2197                 synchronized (ActivityManagerService.this) {
2198                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2199                 }
2200                 break;
2201             }
2202             case START_PROFILES_MSG: {
2203                 synchronized (ActivityManagerService.this) {
2204                     mUserController.startProfilesLocked();
2205                 }
2206                 break;
2207             }
2208             case UPDATE_TIME_PREFERENCE_MSG: {
2209                 // The user's time format preference might have changed.
2210                 // For convenience we re-use the Intent extra values.
2211                 synchronized (ActivityManagerService.this) {
2212                     for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2213                         ProcessRecord r = mLruProcesses.get(i);
2214                         if (r.thread != null) {
2215                             try {
2216                                 r.thread.updateTimePrefs(msg.arg1);
2217                             } catch (RemoteException ex) {
2218                                 Slog.w(TAG, "Failed to update preferences for: "
2219                                         + r.info.processName);
2220                             }
2221                         }
2222                     }
2223                 }
2224                 break;
2225             }
2226             case SYSTEM_USER_START_MSG: {
2227                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2228                         Integer.toString(msg.arg1), msg.arg1);
2229                 mSystemServiceManager.startUser(msg.arg1);
2230                 break;
2231             }
2232             case SYSTEM_USER_UNLOCK_MSG: {
2233                 final int userId = msg.arg1;
2234                 mSystemServiceManager.unlockUser(userId);
2235                 synchronized (ActivityManagerService.this) {
2236                     mRecentTasks.loadUserRecentsLocked(userId);
2237                 }
2238                 if (userId == UserHandle.USER_SYSTEM) {
2239                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2240                 }
2241                 installEncryptionUnawareProviders(userId);
2242                 mUserController.finishUserUnlocked((UserState) msg.obj);
2243                 break;
2244             }
2245             case SYSTEM_USER_CURRENT_MSG: {
2246                 mBatteryStatsService.noteEvent(
2247                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2248                         Integer.toString(msg.arg2), msg.arg2);
2249                 mBatteryStatsService.noteEvent(
2250                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2251                         Integer.toString(msg.arg1), msg.arg1);
2252                 mSystemServiceManager.switchUser(msg.arg1);
2253                 break;
2254             }
2255             case ENTER_ANIMATION_COMPLETE_MSG: {
2256                 synchronized (ActivityManagerService.this) {
2257                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2258                     if (r != null && r.app != null && r.app.thread != null) {
2259                         try {
2260                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2261                         } catch (RemoteException e) {
2262                         }
2263                     }
2264                 }
2265                 break;
2266             }
2267             case FINISH_BOOTING_MSG: {
2268                 if (msg.arg1 != 0) {
2269                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2270                     finishBooting();
2271                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2272                 }
2273                 if (msg.arg2 != 0) {
2274                     enableScreenAfterBoot();
2275                 }
2276                 break;
2277             }
2278             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2279                 try {
2280                     Locale l = (Locale) msg.obj;
2281                     IBinder service = ServiceManager.getService("mount");
2282                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2283                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2284                     storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2285                 } catch (RemoteException e) {
2286                     Log.e(TAG, "Error storing locale for decryption UI", e);
2287                 }
2288                 break;
2289             }
2290             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2291                 final int uid = msg.arg1;
2292                 final byte[] firstPacket = (byte[]) msg.obj;
2293
2294                 synchronized (mPidsSelfLocked) {
2295                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2296                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2297                         if (p.uid == uid) {
2298                             try {
2299                                 p.thread.notifyCleartextNetwork(firstPacket);
2300                             } catch (RemoteException ignored) {
2301                             }
2302                         }
2303                     }
2304                 }
2305                 break;
2306             }
2307             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2308                 final String procName;
2309                 final int uid;
2310                 final long memLimit;
2311                 final String reportPackage;
2312                 synchronized (ActivityManagerService.this) {
2313                     procName = mMemWatchDumpProcName;
2314                     uid = mMemWatchDumpUid;
2315                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2316                     if (val == null) {
2317                         val = mMemWatchProcesses.get(procName, 0);
2318                     }
2319                     if (val != null) {
2320                         memLimit = val.first;
2321                         reportPackage = val.second;
2322                     } else {
2323                         memLimit = 0;
2324                         reportPackage = null;
2325                     }
2326                 }
2327                 if (procName == null) {
2328                     return;
2329                 }
2330
2331                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2332                         "Showing dump heap notification from " + procName + "/" + uid);
2333
2334                 INotificationManager inm = NotificationManager.getService();
2335                 if (inm == null) {
2336                     return;
2337                 }
2338
2339                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2340
2341
2342                 Intent deleteIntent = new Intent();
2343                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2344                 Intent intent = new Intent();
2345                 intent.setClassName("android", DumpHeapActivity.class.getName());
2346                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2347                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2348                 if (reportPackage != null) {
2349                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2350                 }
2351                 int userId = UserHandle.getUserId(uid);
2352                 Notification notification =
2353                         new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2354                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2355                         .setWhen(0)
2356                         .setOngoing(true)
2357                         .setAutoCancel(true)
2358                         .setTicker(text)
2359                         .setColor(mContext.getColor(
2360                                 com.android.internal.R.color.system_notification_accent_color))
2361                         .setContentTitle(text)
2362                         .setContentText(
2363                                 mContext.getText(R.string.dump_heap_notification_detail))
2364                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2365                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2366                                 new UserHandle(userId)))
2367                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2368                                 deleteIntent, 0, UserHandle.SYSTEM))
2369                         .build();
2370
2371                 try {
2372                     inm.enqueueNotificationWithTag("android", "android", null,
2373                             SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2374                             notification, userId);
2375                 } catch (RuntimeException e) {
2376                     Slog.w(ActivityManagerService.TAG,
2377                             "Error showing notification for dump heap", e);
2378                 } catch (RemoteException e) {
2379                 }
2380             } break;
2381             case DELETE_DUMPHEAP_MSG: {
2382                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2383                         null, DumpHeapActivity.JAVA_URI,
2384                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2385                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2386                         UserHandle.myUserId());
2387                 synchronized (ActivityManagerService.this) {
2388                     mMemWatchDumpFile = null;
2389                     mMemWatchDumpProcName = null;
2390                     mMemWatchDumpPid = -1;
2391                     mMemWatchDumpUid = -1;
2392                 }
2393             } break;
2394             case FOREGROUND_PROFILE_CHANGED_MSG: {
2395                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2396             } break;
2397             case REPORT_TIME_TRACKER_MSG: {
2398                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2399                 tracker.deliverResult(mContext);
2400             } break;
2401             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2402                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2403             } break;
2404             case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2405                 mUserController.dispatchLockedBootComplete(msg.arg1);
2406             } break;
2407             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2408                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2409                 try {
2410                     connection.shutdown();
2411                 } catch (RemoteException e) {
2412                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2413                 }
2414                 // Only a UiAutomation can set this flag and now that
2415                 // it is finished we make sure it is reset to its default.
2416                 mUserIsMonkey = false;
2417             } break;
2418             case IDLE_UIDS_MSG: {
2419                 idleUids();
2420             } break;
2421             case VR_MODE_CHANGE_MSG: {
2422                 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2423                     return;
2424                 }
2425                 synchronized (ActivityManagerService.this) {
2426                     final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2427                     mWindowManager.disableNonVrUi(disableNonVrUi);
2428                     if (disableNonVrUi) {
2429                         // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2430                         // then remove the pinned stack.
2431                         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2432                                 PINNED_STACK_ID);
2433                         if (pinnedStack != null) {
2434                             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2435                         }
2436                     }
2437                 }
2438             } break;
2439             case NOTIFY_VR_SLEEPING_MSG: {
2440                 notifyVrManagerOfSleepState(msg.arg1 != 0);
2441             } break;
2442             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2443                 synchronized (ActivityManagerService.this) {
2444                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2445                         ProcessRecord r = mLruProcesses.get(i);
2446                         if (r.thread != null) {
2447                             try {
2448                                 r.thread.handleTrustStorageUpdate();
2449                             } catch (RemoteException ex) {
2450                                 Slog.w(TAG, "Failed to handle trust storage update for: " +
2451                                         r.info.processName);
2452                             }
2453                         }
2454                     }
2455                 }
2456             } break;
2457             }
2458         }
2459     };
2460
2461     static final int COLLECT_PSS_BG_MSG = 1;
2462
2463     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2464         @Override
2465         public void handleMessage(Message msg) {
2466             switch (msg.what) {
2467             case COLLECT_PSS_BG_MSG: {
2468                 long start = SystemClock.uptimeMillis();
2469                 MemInfoReader memInfo = null;
2470                 synchronized (ActivityManagerService.this) {
2471                     if (mFullPssPending) {
2472                         mFullPssPending = false;
2473                         memInfo = new MemInfoReader();
2474                     }
2475                 }
2476                 if (memInfo != null) {
2477                     updateCpuStatsNow();
2478                     long nativeTotalPss = 0;
2479                     final List<ProcessCpuTracker.Stats> stats;
2480                     synchronized (mProcessCpuTracker) {
2481                         stats = mProcessCpuTracker.getStats( (st)-> {
2482                             return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2483                         });
2484                     }
2485                     final int N = stats.size();
2486                     for (int j = 0; j < N; j++) {
2487                         synchronized (mPidsSelfLocked) {
2488                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2489                                 // This is one of our own processes; skip it.
2490                                 continue;
2491                             }
2492                         }
2493                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2494                     }
2495                     memInfo.readMemInfo();
2496                     synchronized (ActivityManagerService.this) {
2497                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2498                                 + (SystemClock.uptimeMillis()-start) + "ms");
2499                         final long cachedKb = memInfo.getCachedSizeKb();
2500                         final long freeKb = memInfo.getFreeSizeKb();
2501                         final long zramKb = memInfo.getZramTotalSizeKb();
2502                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2503                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2504                                 kernelKb*1024, nativeTotalPss*1024);
2505                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2506                                 nativeTotalPss);
2507                     }
2508                 }
2509
2510                 int num = 0;
2511                 long[] tmp = new long[2];
2512                 do {
2513                     ProcessRecord proc;
2514                     int procState;
2515                     int pid;
2516                     long lastPssTime;
2517                     synchronized (ActivityManagerService.this) {
2518                         if (mPendingPssProcesses.size() <= 0) {
2519                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2520                                     "Collected PSS of " + num + " processes in "
2521                                     + (SystemClock.uptimeMillis() - start) + "ms");
2522                             mPendingPssProcesses.clear();
2523                             return;
2524                         }
2525                         proc = mPendingPssProcesses.remove(0);
2526                         procState = proc.pssProcState;
2527                         lastPssTime = proc.lastPssTime;
2528                         if (proc.thread != null && procState == proc.setProcState
2529                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2530                                         < SystemClock.uptimeMillis()) {
2531                             pid = proc.pid;
2532                         } else {
2533                             proc = null;
2534                             pid = 0;
2535                         }
2536                     }
2537                     if (proc != null) {
2538                         long pss = Debug.getPss(pid, tmp, null);
2539                         synchronized (ActivityManagerService.this) {
2540                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2541                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2542                                 num++;
2543                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2544                                         SystemClock.uptimeMillis());
2545                             }
2546                         }
2547                     }
2548                 } while (true);
2549             }
2550             }
2551         }
2552     };
2553
2554     public void setSystemProcess() {
2555         try {
2556             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2557             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2558             ServiceManager.addService("meminfo", new MemBinder(this));
2559             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2560             ServiceManager.addService("dbinfo", new DbBinder(this));
2561             if (MONITOR_CPU_USAGE) {
2562                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2563             }
2564             ServiceManager.addService("permission", new PermissionController(this));
2565             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2566
2567             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2568                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2569             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2570
2571             synchronized (this) {
2572                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2573                 app.persistent = true;
2574                 app.pid = MY_PID;
2575                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2576                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2577                 synchronized (mPidsSelfLocked) {
2578                     mPidsSelfLocked.put(app.pid, app);
2579                 }
2580                 updateLruProcessLocked(app, false, null);
2581                 updateOomAdjLocked();
2582             }
2583         } catch (PackageManager.NameNotFoundException e) {
2584             throw new RuntimeException(
2585                     "Unable to find android system package", e);
2586         }
2587     }
2588
2589     public void setWindowManager(WindowManagerService wm) {
2590         mWindowManager = wm;
2591         mStackSupervisor.setWindowManager(wm);
2592         mActivityStarter.setWindowManager(wm);
2593     }
2594
2595     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2596         mUsageStatsService = usageStatsManager;
2597     }
2598
2599     public void startObservingNativeCrashes() {
2600         final NativeCrashListener ncl = new NativeCrashListener(this);
2601         ncl.start();
2602     }
2603
2604     public IAppOpsService getAppOpsService() {
2605         return mAppOpsService;
2606     }
2607
2608     static class MemBinder extends Binder {
2609         ActivityManagerService mActivityManagerService;
2610         MemBinder(ActivityManagerService activityManagerService) {
2611             mActivityManagerService = activityManagerService;
2612         }
2613
2614         @Override
2615         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2616             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2617                     "meminfo", pw)) return;
2618             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2619         }
2620     }
2621
2622     static class GraphicsBinder extends Binder {
2623         ActivityManagerService mActivityManagerService;
2624         GraphicsBinder(ActivityManagerService activityManagerService) {
2625             mActivityManagerService = activityManagerService;
2626         }
2627
2628         @Override
2629         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2630             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2631                     "gfxinfo", pw)) return;
2632             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2633         }
2634     }
2635
2636     static class DbBinder extends Binder {
2637         ActivityManagerService mActivityManagerService;
2638         DbBinder(ActivityManagerService activityManagerService) {
2639             mActivityManagerService = activityManagerService;
2640         }
2641
2642         @Override
2643         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2644             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2645                     "dbinfo", pw)) return;
2646             mActivityManagerService.dumpDbInfo(fd, pw, args);
2647         }
2648     }
2649
2650     static class CpuBinder extends Binder {
2651         ActivityManagerService mActivityManagerService;
2652         CpuBinder(ActivityManagerService activityManagerService) {
2653             mActivityManagerService = activityManagerService;
2654         }
2655
2656         @Override
2657         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2658             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2659                     "cpuinfo", pw)) return;
2660             synchronized (mActivityManagerService.mProcessCpuTracker) {
2661                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2662                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2663                         SystemClock.uptimeMillis()));
2664             }
2665         }
2666     }
2667
2668     public static final class Lifecycle extends SystemService {
2669         private final ActivityManagerService mService;
2670
2671         public Lifecycle(Context context) {
2672             super(context);
2673             mService = new ActivityManagerService(context);
2674         }
2675
2676         @Override
2677         public void onStart() {
2678             mService.start();
2679         }
2680
2681         public ActivityManagerService getService() {
2682             return mService;
2683         }
2684     }
2685
2686     @VisibleForTesting
2687     public ActivityManagerService(Injector injector) {
2688         mInjector = injector;
2689         mContext = mInjector.getContext();
2690         mUiContext = null;
2691         GL_ES_VERSION = 0;
2692         mActivityStarter = null;
2693         mAppErrors = null;
2694         mAppOpsService = mInjector.getAppOpsService(null, null);
2695         mBatteryStatsService = null;
2696         mCompatModePackages = null;
2697         mConstants = null;
2698         mGrantFile = null;
2699         mHandler = null;
2700         mHandlerThread = null;
2701         mIntentFirewall = null;
2702         mKeyguardController = null;
2703         mPermissionReviewRequired = false;
2704         mProcessCpuThread = null;
2705         mProcessStats = null;
2706         mProviderMap = null;
2707         mRecentTasks = null;
2708         mServices = null;
2709         mStackSupervisor = null;
2710         mSystemThread = null;
2711         mTaskChangeNotificationController = null;
2712         mUiHandler = injector.getUiHandler(null);
2713         mUserController = null;
2714         mVrController = null;
2715     }
2716
2717     // Note: This method is invoked on the main thread but may need to attach various
2718     // handlers to other threads.  So take care to be explicit about the looper.
2719     public ActivityManagerService(Context systemContext) {
2720         LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2721         mInjector = new Injector();
2722         mContext = systemContext;
2723
2724         mFactoryTest = FactoryTest.getMode();
2725         mSystemThread = ActivityThread.currentActivityThread();
2726         mUiContext = mSystemThread.getSystemUiContext();
2727
2728         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2729
2730         mPermissionReviewRequired = mContext.getResources().getBoolean(
2731                 com.android.internal.R.bool.config_permissionReviewRequired);
2732
2733         mHandlerThread = new ServiceThread(TAG,
2734                 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2735         mHandlerThread.start();
2736         mHandler = new MainHandler(mHandlerThread.getLooper());
2737         mUiHandler = mInjector.getUiHandler(this);
2738
2739         mConstants = new ActivityManagerConstants(this, mHandler);
2740
2741         /* static; one-time init here */
2742         if (sKillHandler == null) {
2743             sKillThread = new ServiceThread(TAG + ":kill",
2744                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2745             sKillThread.start();
2746             sKillHandler = new KillHandler(sKillThread.getLooper());
2747         }
2748
2749         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2750                 "foreground", BROADCAST_FG_TIMEOUT, false);
2751         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2752                 "background", BROADCAST_BG_TIMEOUT, true);
2753         mBroadcastQueues[0] = mFgBroadcastQueue;
2754         mBroadcastQueues[1] = mBgBroadcastQueue;
2755
2756         mServices = new ActiveServices(this);
2757         mProviderMap = new ProviderMap(this);
2758         mAppErrors = new AppErrors(mUiContext, this);
2759
2760         // TODO: Move creation of battery stats service outside of activity manager service.
2761         File dataDir = Environment.getDataDirectory();
2762         File systemDir = new File(dataDir, "system");
2763         systemDir.mkdirs();
2764         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2765         mBatteryStatsService.getActiveStatistics().readLocked();
2766         mBatteryStatsService.scheduleWriteToDisk();
2767         mOnBattery = DEBUG_POWER ? true
2768                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2769         mBatteryStatsService.getActiveStatistics().setCallback(this);
2770
2771         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2772
2773         mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2774         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2775                 new IAppOpsCallback.Stub() {
2776                     @Override public void opChanged(int op, int uid, String packageName) {
2777                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2778                             if (mAppOpsService.checkOperation(op, uid, packageName)
2779                                     != AppOpsManager.MODE_ALLOWED) {
2780                                 runInBackgroundDisabled(uid);
2781                             }
2782                         }
2783                     }
2784                 });
2785
2786         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2787
2788         mUserController = new UserController(this);
2789
2790         mVrController = new VrController(this);
2791
2792         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2793             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2794
2795         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2796             mUseFifoUiScheduling = true;
2797         }
2798
2799         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2800         mTempConfig.setToDefaults();
2801         mTempConfig.setLocales(LocaleList.getDefault());
2802         mConfigurationSeq = mTempConfig.seq = 1;
2803         mStackSupervisor = createStackSupervisor();
2804         mStackSupervisor.onConfigurationChanged(mTempConfig);
2805         mKeyguardController = mStackSupervisor.mKeyguardController;
2806         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2807         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2808         mTaskChangeNotificationController =
2809                 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2810         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2811         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2812
2813         mProcessCpuThread = new Thread("CpuTracker") {
2814             @Override
2815             public void run() {
2816                 synchronized (mProcessCpuTracker) {
2817                     mProcessCpuInitLatch.countDown();
2818                     mProcessCpuTracker.init();
2819                 }
2820                 while (true) {
2821                     try {
2822                         try {
2823                             synchronized(this) {
2824                                 final long now = SystemClock.uptimeMillis();
2825                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2826                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2827                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2828                                 //        + ", write delay=" + nextWriteDelay);
2829                                 if (nextWriteDelay < nextCpuDelay) {
2830                                     nextCpuDelay = nextWriteDelay;
2831                                 }
2832                                 if (nextCpuDelay > 0) {
2833                                     mProcessCpuMutexFree.set(true);
2834                                     this.wait(nextCpuDelay);
2835                                 }
2836                             }
2837                         } catch (InterruptedException e) {
2838                         }
2839                         updateCpuStatsNow();
2840                     } catch (Exception e) {
2841                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2842                     }
2843                 }
2844             }
2845         };
2846
2847         Watchdog.getInstance().addMonitor(this);
2848         Watchdog.getInstance().addThread(mHandler);
2849     }
2850
2851     protected ActivityStackSupervisor createStackSupervisor() {
2852         return new ActivityStackSupervisor(this, mHandler.getLooper());
2853     }
2854
2855     public void setSystemServiceManager(SystemServiceManager mgr) {
2856         mSystemServiceManager = mgr;
2857     }
2858
2859     public void setInstaller(Installer installer) {
2860         mInstaller = installer;
2861     }
2862
2863     private void start() {
2864         removeAllProcessGroups();
2865         mProcessCpuThread.start();
2866
2867         mBatteryStatsService.publish(mContext);
2868         mAppOpsService.publish(mContext);
2869         Slog.d("AppOps", "AppOpsService published");
2870         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2871         // Wait for the synchronized block started in mProcessCpuThread,
2872         // so that any other acccess to mProcessCpuTracker from main thread
2873         // will be blocked during mProcessCpuTracker initialization.
2874         try {
2875             mProcessCpuInitLatch.await();
2876         } catch (InterruptedException e) {
2877             Slog.wtf(TAG, "Interrupted wait during start", e);
2878             Thread.currentThread().interrupt();
2879             throw new IllegalStateException("Interrupted wait during start");
2880         }
2881     }
2882
2883     void onUserStoppedLocked(int userId) {
2884         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2885     }
2886
2887     public void initPowerManagement() {
2888         mStackSupervisor.initPowerManagement();
2889         mBatteryStatsService.initPowerManagement();
2890         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2891         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2892         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2893         mVoiceWakeLock.setReferenceCounted(false);
2894     }
2895
2896     private ArraySet<String> getBackgroundLaunchBroadcasts() {
2897         if (mBackgroundLaunchBroadcasts == null) {
2898             mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2899         }
2900         return mBackgroundLaunchBroadcasts;
2901     }
2902
2903     @Override
2904     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2905             throws RemoteException {
2906         if (code == SYSPROPS_TRANSACTION) {
2907             // We need to tell all apps about the system property change.
2908             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2909             synchronized(this) {
2910                 final int NP = mProcessNames.getMap().size();
2911                 for (int ip=0; ip<NP; ip++) {
2912                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2913                     final int NA = apps.size();
2914                     for (int ia=0; ia<NA; ia++) {
2915                         ProcessRecord app = apps.valueAt(ia);
2916                         if (app.thread != null) {
2917                             procs.add(app.thread.asBinder());
2918                         }
2919                     }
2920                 }
2921             }
2922
2923             int N = procs.size();
2924             for (int i=0; i<N; i++) {
2925                 Parcel data2 = Parcel.obtain();
2926                 try {
2927                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2928                             Binder.FLAG_ONEWAY);
2929                 } catch (RemoteException e) {
2930                 }
2931                 data2.recycle();
2932             }
2933         }
2934         try {
2935             return super.onTransact(code, data, reply, flags);
2936         } catch (RuntimeException e) {
2937             // The activity manager only throws security exceptions, so let's
2938             // log all others.
2939             if (!(e instanceof SecurityException)) {
2940                 Slog.wtf(TAG, "Activity Manager Crash."
2941                         + " UID:" + Binder.getCallingUid()
2942                         + " PID:" + Binder.getCallingPid()
2943                         + " TRANS:" + code, e);
2944             }
2945             throw e;
2946         }
2947     }
2948
2949     void updateCpuStats() {
2950         final long now = SystemClock.uptimeMillis();
2951         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2952             return;
2953         }
2954         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2955             synchronized (mProcessCpuThread) {
2956                 mProcessCpuThread.notify();
2957             }
2958         }
2959     }
2960
2961     void updateCpuStatsNow() {
2962         synchronized (mProcessCpuTracker) {
2963             mProcessCpuMutexFree.set(false);
2964             final long now = SystemClock.uptimeMillis();
2965             boolean haveNewCpuStats = false;
2966
2967             if (MONITOR_CPU_USAGE &&
2968                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2969                 mLastCpuTime.set(now);
2970                 mProcessCpuTracker.update();
2971                 if (mProcessCpuTracker.hasGoodLastStats()) {
2972                     haveNewCpuStats = true;
2973                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2974                     //Slog.i(TAG, "Total CPU usage: "
2975                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2976
2977                     // Slog the cpu usage if the property is set.
2978                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2979                         int user = mProcessCpuTracker.getLastUserTime();
2980                         int system = mProcessCpuTracker.getLastSystemTime();
2981                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2982                         int irq = mProcessCpuTracker.getLastIrqTime();
2983                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2984                         int idle = mProcessCpuTracker.getLastIdleTime();
2985
2986                         int total = user + system + iowait + irq + softIrq + idle;
2987                         if (total == 0) total = 1;
2988
2989                         EventLog.writeEvent(EventLogTags.CPU,
2990                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2991                                 (user * 100) / total,
2992                                 (system * 100) / total,
2993                                 (iowait * 100) / total,
2994                                 (irq * 100) / total,
2995                                 (softIrq * 100) / total);
2996                     }
2997                 }
2998             }
2999
3000             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3001             synchronized(bstats) {
3002                 synchronized(mPidsSelfLocked) {
3003                     if (haveNewCpuStats) {
3004                         if (bstats.startAddingCpuLocked()) {
3005                             int totalUTime = 0;
3006                             int totalSTime = 0;
3007                             final int N = mProcessCpuTracker.countStats();
3008                             for (int i=0; i<N; i++) {
3009                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3010                                 if (!st.working) {
3011                                     continue;
3012                                 }
3013                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3014                                 totalUTime += st.rel_utime;
3015                                 totalSTime += st.rel_stime;
3016                                 if (pr != null) {
3017                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3018                                     if (ps == null || !ps.isActive()) {
3019                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3020                                                 pr.info.uid, pr.processName);
3021                                     }
3022                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3023                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
3024                                 } else {
3025                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3026                                     if (ps == null || !ps.isActive()) {
3027                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
3028                                                 bstats.mapUid(st.uid), st.name);
3029                                     }
3030                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3031                                 }
3032                             }
3033                             final int userTime = mProcessCpuTracker.getLastUserTime();
3034                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
3035                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3036                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
3037                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3038                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
3039                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3040                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3041                         }
3042                     }
3043                 }
3044
3045                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3046                     mLastWriteTime = now;
3047                     mBatteryStatsService.scheduleWriteToDisk();
3048                 }
3049             }
3050         }
3051     }
3052
3053     @Override
3054     public void batteryNeedsCpuUpdate() {
3055         updateCpuStatsNow();
3056     }
3057
3058     @Override
3059     public void batteryPowerChanged(boolean onBattery) {
3060         // When plugging in, update the CPU stats first before changing
3061         // the plug state.
3062         updateCpuStatsNow();
3063         synchronized (this) {
3064             synchronized(mPidsSelfLocked) {
3065                 mOnBattery = DEBUG_POWER ? true : onBattery;
3066             }
3067         }
3068     }
3069
3070     @Override
3071     public void batterySendBroadcast(Intent intent) {
3072         synchronized (this) {
3073             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3074                     AppOpsManager.OP_NONE, null, false, false,
3075                     -1, SYSTEM_UID, UserHandle.USER_ALL);
3076         }
3077     }
3078
3079     /**
3080      * Initialize the application bind args. These are passed to each
3081      * process when the bindApplication() IPC is sent to the process. They're
3082      * lazily setup to make sure the services are running when they're asked for.
3083      */
3084     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3085         // Isolated processes won't get this optimization, so that we don't
3086         // violate the rules about which services they have access to.
3087         if (isolated) {
3088             if (mIsolatedAppBindArgs == null) {
3089                 mIsolatedAppBindArgs = new HashMap<>();
3090                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3091             }
3092             return mIsolatedAppBindArgs;
3093         }
3094
3095         if (mAppBindArgs == null) {
3096             mAppBindArgs = new HashMap<>();
3097
3098             // Setup the application init args
3099             mAppBindArgs.put("package", ServiceManager.getService("package"));
3100             mAppBindArgs.put("window", ServiceManager.getService("window"));
3101             mAppBindArgs.put(Context.ALARM_SERVICE,
3102                     ServiceManager.getService(Context.ALARM_SERVICE));
3103         }
3104         return mAppBindArgs;
3105     }
3106
3107     /**
3108      * Update AMS states when an activity is resumed. This should only be called by
3109      * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3110      */
3111     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3112         final TaskRecord task = r.getTask();
3113         if (task.isApplicationTask()) {
3114             if (mCurAppTimeTracker != r.appTimeTracker) {
3115                 // We are switching app tracking.  Complete the current one.
3116                 if (mCurAppTimeTracker != null) {
3117                     mCurAppTimeTracker.stop();
3118                     mHandler.obtainMessage(
3119                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3120                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3121                     mCurAppTimeTracker = null;
3122                 }
3123                 if (r.appTimeTracker != null) {
3124                     mCurAppTimeTracker = r.appTimeTracker;
3125                     startTimeTrackingFocusedActivityLocked();
3126                 }
3127             } else {
3128                 startTimeTrackingFocusedActivityLocked();
3129             }
3130         } else {
3131             r.appTimeTracker = null;
3132         }
3133         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3134         // TODO: Probably not, because we don't want to resume voice on switching
3135         // back to this activity
3136         if (task.voiceInteractor != null) {
3137             startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3138         } else {
3139             finishRunningVoiceLocked();
3140
3141             if (mLastResumedActivity != null) {
3142                 final IVoiceInteractionSession session;
3143
3144                 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3145                 if (lastResumedActivityTask != null
3146                         && lastResumedActivityTask.voiceSession != null) {
3147                     session = lastResumedActivityTask.voiceSession;
3148                 } else {
3149                     session = mLastResumedActivity.voiceSession;
3150                 }
3151
3152                 if (session != null) {
3153                     // We had been in a voice interaction session, but now focused has
3154                     // move to something different.  Just finish the session, we can't
3155                     // return to it and retain the proper state and synchronization with
3156                     // the voice interaction service.
3157                     finishVoiceTask(session);
3158                 }
3159             }
3160         }
3161
3162         if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3163             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3164             mHandler.obtainMessage(
3165                     FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3166         }
3167         mLastResumedActivity = r;
3168
3169         mWindowManager.setFocusedApp(r.appToken, true);
3170
3171         applyUpdateLockStateLocked(r);
3172         applyUpdateVrModeLocked(r);
3173
3174         EventLogTags.writeAmSetResumedActivity(
3175                 r == null ? -1 : r.userId,
3176                 r == null ? "NULL" : r.shortComponentName,
3177                 reason);
3178     }
3179
3180     @Override
3181     public void setFocusedStack(int stackId) {
3182         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3183         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3184         final long callingId = Binder.clearCallingIdentity();
3185         try {
3186             synchronized (this) {
3187                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3188                 if (stack == null) {
3189                     return;
3190                 }
3191                 final ActivityRecord r = stack.topRunningActivityLocked();
3192                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3193                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3194                 }
3195             }
3196         } finally {
3197             Binder.restoreCallingIdentity(callingId);
3198         }
3199     }
3200
3201     @Override
3202     public void setFocusedTask(int taskId) {
3203         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3204         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3205         final long callingId = Binder.clearCallingIdentity();
3206         try {
3207             synchronized (this) {
3208                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3209                 if (task == null) {
3210                     return;
3211                 }
3212                 final ActivityRecord r = task.topRunningActivityLocked();
3213                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3214                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3215                 }
3216             }
3217         } finally {
3218             Binder.restoreCallingIdentity(callingId);
3219         }
3220     }
3221
3222     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3223     @Override
3224     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3225         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3226         mTaskChangeNotificationController.registerTaskStackListener(listener);
3227     }
3228
3229     /**
3230      * Unregister a task stack listener so that it stops receiving callbacks.
3231      */
3232     @Override
3233     public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3234          enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3235          mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3236      }
3237
3238     @Override
3239     public void notifyActivityDrawn(IBinder token) {
3240         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3241         synchronized (this) {
3242             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3243             if (r != null) {
3244                 r.getStack().notifyActivityDrawnLocked(r);
3245             }
3246         }
3247     }
3248
3249     final void applyUpdateLockStateLocked(ActivityRecord r) {
3250         // Modifications to the UpdateLock state are done on our handler, outside
3251         // the activity manager's locks.  The new state is determined based on the
3252         // state *now* of the relevant activity record.  The object is passed to
3253         // the handler solely for logging detail, not to be consulted/modified.
3254         final boolean nextState = r != null && r.immersive;
3255         mHandler.sendMessage(
3256                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3257     }
3258
3259     final void applyUpdateVrModeLocked(ActivityRecord r) {
3260         mHandler.sendMessage(
3261                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3262     }
3263
3264     private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3265         mHandler.sendMessage(
3266                 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3267     }
3268
3269     private void notifyVrManagerOfSleepState(boolean isSleeping) {
3270         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3271         if (vrService == null) {
3272             return;
3273         }
3274         vrService.onSleepStateChanged(isSleeping);
3275     }
3276
3277     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3278         Message msg = Message.obtain();
3279         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3280         msg.obj = r.getTask().askedCompatMode ? null : r;
3281         mUiHandler.sendMessage(msg);
3282     }
3283
3284     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3285         final Configuration globalConfig = getGlobalConfiguration();
3286         if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3287                 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3288             final Message msg = Message.obtain();
3289             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3290             msg.obj = r;
3291             mUiHandler.sendMessage(msg);
3292         }
3293     }
3294
3295     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3296             String what, Object obj, ProcessRecord srcApp) {
3297         app.lastActivityTime = now;
3298
3299         if (app.activities.size() > 0) {
3300             // Don't want to touch dependent processes that are hosting activities.
3301             return index;
3302         }
3303
3304         int lrui = mLruProcesses.lastIndexOf(app);
3305         if (lrui < 0) {
3306             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3307                     + what + " " + obj + " from " + srcApp);
3308             return index;
3309         }
3310
3311         if (lrui >= index) {
3312             // Don't want to cause this to move dependent processes *back* in the
3313             // list as if they were less frequently used.
3314             return index;
3315         }
3316
3317         if (lrui >= mLruProcessActivityStart) {
3318             // Don't want to touch dependent processes that are hosting activities.
3319             return index;
3320         }
3321
3322         mLruProcesses.remove(lrui);
3323         if (index > 0) {
3324             index--;
3325         }
3326         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3327                 + " in LRU list: " + app);
3328         mLruProcesses.add(index, app);
3329         return index;
3330     }
3331
3332     static void killProcessGroup(int uid, int pid) {
3333         if (sKillHandler != null) {
3334             sKillHandler.sendMessage(
3335                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3336         } else {
3337             Slog.w(TAG, "Asked to kill process group before system bringup!");
3338             Process.killProcessGroup(uid, pid);
3339         }
3340     }
3341
3342     final void removeLruProcessLocked(ProcessRecord app) {
3343         int lrui = mLruProcesses.lastIndexOf(app);
3344         if (lrui >= 0) {
3345             if (!app.killed) {
3346                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3347                 killProcessQuiet(app.pid);
3348                 killProcessGroup(app.uid, app.pid);
3349             }
3350             if (lrui <= mLruProcessActivityStart) {
3351                 mLruProcessActivityStart--;
3352             }
3353             if (lrui <= mLruProcessServiceStart) {
3354                 mLruProcessServiceStart--;
3355             }
3356             mLruProcesses.remove(lrui);
3357         }
3358     }
3359
3360     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3361             ProcessRecord client) {
3362         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3363                 || app.treatLikeActivity;
3364         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3365         if (!activityChange && hasActivity) {
3366             // The process has activities, so we are only allowing activity-based adjustments
3367             // to move it.  It should be kept in the front of the list with other
3368             // processes that have activities, and we don't want those to change their
3369             // order except due to activity operations.
3370             return;
3371         }
3372
3373         mLruSeq++;
3374         final long now = SystemClock.uptimeMillis();
3375         app.lastActivityTime = now;
3376
3377         // First a quick reject: if the app is already at the position we will
3378         // put it, then there is nothing to do.
3379         if (hasActivity) {
3380             final int N = mLruProcesses.size();
3381             if (N > 0 && mLruProcesses.get(N-1) == app) {
3382                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3383                 return;
3384             }
3385         } else {
3386             if (mLruProcessServiceStart > 0
3387                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3388                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3389                 return;
3390             }
3391         }
3392
3393         int lrui = mLruProcesses.lastIndexOf(app);
3394
3395         if (app.persistent && lrui >= 0) {
3396             // We don't care about the position of persistent processes, as long as
3397             // they are in the list.
3398             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3399             return;
3400         }
3401
3402         /* In progress: compute new position first, so we can avoid doing work
3403            if the process is not actually going to move.  Not yet working.
3404         int addIndex;
3405         int nextIndex;
3406         boolean inActivity = false, inService = false;
3407         if (hasActivity) {
3408             // Process has activities, put it at the very tipsy-top.
3409             addIndex = mLruProcesses.size();
3410             nextIndex = mLruProcessServiceStart;
3411             inActivity = true;
3412         } else if (hasService) {
3413             // Process has services, put it at the top of the service list.
3414             addIndex = mLruProcessActivityStart;
3415             nextIndex = mLruProcessServiceStart;
3416             inActivity = true;
3417             inService = true;
3418         } else  {
3419             // Process not otherwise of interest, it goes to the top of the non-service area.
3420             addIndex = mLruProcessServiceStart;
3421             if (client != null) {
3422                 int clientIndex = mLruProcesses.lastIndexOf(client);
3423                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3424                         + app);
3425                 if (clientIndex >= 0 && addIndex > clientIndex) {
3426                     addIndex = clientIndex;
3427                 }
3428             }
3429             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3430         }
3431
3432         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3433                 + mLruProcessActivityStart + "): " + app);
3434         */
3435
3436         if (lrui >= 0) {
3437             if (lrui < mLruProcessActivityStart) {
3438                 mLruProcessActivityStart--;
3439             }
3440             if (lrui < mLruProcessServiceStart) {
3441                 mLruProcessServiceStart--;
3442             }
3443             /*
3444             if (addIndex > lrui) {
3445                 addIndex--;
3446             }
3447             if (nextIndex > lrui) {
3448                 nextIndex--;
3449             }
3450             */
3451             mLruProcesses.remove(lrui);
3452         }
3453
3454         /*
3455         mLruProcesses.add(addIndex, app);
3456         if (inActivity) {
3457             mLruProcessActivityStart++;
3458         }
3459         if (inService) {
3460             mLruProcessActivityStart++;
3461         }
3462         */
3463
3464         int nextIndex;
3465         if (hasActivity) {
3466             final int N = mLruProcesses.size();
3467             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3468                 // Process doesn't have activities, but has clients with
3469                 // activities...  move it up, but one below the top (the top
3470                 // should always have a real activity).
3471                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3472                         "Adding to second-top of LRU activity list: " + app);
3473                 mLruProcesses.add(N - 1, app);
3474                 // To keep it from spamming the LRU list (by making a bunch of clients),
3475                 // we will push down any other entries owned by the app.
3476                 final int uid = app.info.uid;
3477                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3478                     ProcessRecord subProc = mLruProcesses.get(i);
3479                     if (subProc.info.uid == uid) {
3480                         // We want to push this one down the list.  If the process after
3481                         // it is for the same uid, however, don't do so, because we don't
3482                         // want them internally to be re-ordered.
3483                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3484                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3485                                     "Pushing uid " + uid + " swapping at " + i + ": "
3486                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3487                             ProcessRecord tmp = mLruProcesses.get(i);
3488                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3489                             mLruProcesses.set(i - 1, tmp);
3490                             i--;
3491                         }
3492                     } else {
3493                         // A gap, we can stop here.
3494                         break;
3495                     }
3496                 }
3497             } else {
3498                 // Process has activities, put it at the very tipsy-top.
3499                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3500                 mLruProcesses.add(app);
3501             }
3502             nextIndex = mLruProcessServiceStart;
3503         } else if (hasService) {
3504             // Process has services, put it at the top of the service list.
3505             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3506             mLruProcesses.add(mLruProcessActivityStart, app);
3507             nextIndex = mLruProcessServiceStart;
3508             mLruProcessActivityStart++;
3509         } else  {
3510             // Process not otherwise of interest, it goes to the top of the non-service area.
3511             int index = mLruProcessServiceStart;
3512             if (client != null) {
3513                 // If there is a client, don't allow the process to be moved up higher
3514                 // in the list than that client.
3515                 int clientIndex = mLruProcesses.lastIndexOf(client);
3516                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3517                         + " when updating " + app);
3518                 if (clientIndex <= lrui) {
3519                     // Don't allow the client index restriction to push it down farther in the
3520                     // list than it already is.
3521                     clientIndex = lrui;
3522                 }
3523                 if (clientIndex >= 0 && index > clientIndex) {
3524                     index = clientIndex;
3525                 }
3526             }
3527             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3528             mLruProcesses.add(index, app);
3529             nextIndex = index-1;
3530             mLruProcessActivityStart++;
3531             mLruProcessServiceStart++;
3532         }
3533
3534         // If the app is currently using a content provider or service,
3535         // bump those processes as well.
3536         for (int j=app.connections.size()-1; j>=0; j--) {
3537             ConnectionRecord cr = app.connections.valueAt(j);
3538             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3539                     && cr.binding.service.app != null
3540                     && cr.binding.service.app.lruSeq != mLruSeq
3541                     && !cr.binding.service.app.persistent) {
3542                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3543                         "service connection", cr, app);
3544             }
3545         }
3546         for (int j=app.conProviders.size()-1; j>=0; j--) {
3547             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3548             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3549                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3550                         "provider reference", cpr, app);
3551             }
3552         }
3553     }
3554
3555     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3556         if (uid == SYSTEM_UID) {
3557             // The system gets to run in any process.  If there are multiple
3558             // processes with the same uid, just pick the first (this
3559             // should never happen).
3560             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3561             if (procs == null) return null;
3562             final int procCount = procs.size();
3563             for (int i = 0; i < procCount; i++) {
3564                 final int procUid = procs.keyAt(i);
3565                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3566                     // Don't use an app process or different user process for system component.
3567                     continue;
3568                 }
3569                 return procs.valueAt(i);
3570             }
3571         }
3572         ProcessRecord proc = mProcessNames.get(processName, uid);
3573         if (false && proc != null && !keepIfLarge
3574                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3575                 && proc.lastCachedPss >= 4000) {
3576             // Turn this condition on to cause killing to happen regularly, for testing.
3577             if (proc.baseProcessTracker != null) {
3578                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3579             }
3580             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3581         } else if (proc != null && !keepIfLarge
3582                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3583                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3584             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3585             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3586                 if (proc.baseProcessTracker != null) {
3587                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3588                 }
3589                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3590             }
3591         }
3592         return proc;
3593     }
3594
3595     void notifyPackageUse(String packageName, int reason) {
3596         IPackageManager pm = AppGlobals.getPackageManager();
3597         try {
3598             pm.notifyPackageUse(packageName, reason);
3599         } catch (RemoteException e) {
3600         }
3601     }
3602
3603     boolean isNextTransitionForward() {
3604         int transit = mWindowManager.getPendingAppTransition();
3605         return transit == TRANSIT_ACTIVITY_OPEN
3606                 || transit == TRANSIT_TASK_OPEN
3607                 || transit == TRANSIT_TASK_TO_FRONT;
3608     }
3609
3610     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3611             String processName, String abiOverride, int uid, Runnable crashHandler) {
3612         synchronized(this) {
3613             ApplicationInfo info = new ApplicationInfo();
3614             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3615             // For isolated processes, the former contains the parent's uid and the latter the
3616             // actual uid of the isolated process.
3617             // In the special case introduced by this method (which is, starting an isolated
3618             // process directly from the SystemServer without an actual parent app process) the
3619             // closest thing to a parent's uid is SYSTEM_UID.
3620             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3621             // the |isolated| logic in the ProcessRecord constructor.
3622             info.uid = SYSTEM_UID;
3623             info.processName = processName;
3624             info.className = entryPoint;
3625             info.packageName = "android";
3626             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3627             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3628                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3629                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3630                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3631                     crashHandler);
3632             return proc != null ? proc.pid : 0;
3633         }
3634     }
3635
3636     final ProcessRecord startProcessLocked(String processName,
3637             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3638             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3639             boolean isolated, boolean keepIfLarge) {
3640         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3641                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3642                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3643                 null /* crashHandler */);
3644     }
3645
3646     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3647             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3648             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3649             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3650         long startTime = SystemClock.elapsedRealtime();
3651         ProcessRecord app;
3652         if (!isolated) {
3653             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3654             checkTime(startTime, "startProcess: after getProcessRecord");
3655
3656             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3657                 // If we are in the background, then check to see if this process
3658                 // is bad.  If so, we will just silently fail.
3659                 if (mAppErrors.isBadProcessLocked(info)) {
3660                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3661                             + "/" + info.processName);
3662                     return null;
3663                 }
3664             } else {
3665                 // When the user is explicitly starting a process, then clear its
3666                 // crash count so that we won't make it bad until they see at
3667                 // least one crash dialog again, and make the process good again
3668                 // if it had been bad.
3669                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3670                         + "/" + info.processName);
3671                 mAppErrors.resetProcessCrashTimeLocked(info);
3672                 if (mAppErrors.isBadProcessLocked(info)) {
3673                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3674                             UserHandle.getUserId(info.uid), info.uid,
3675                             info.processName);
3676                     mAppErrors.clearBadProcessLocked(info);
3677                     if (app != null) {
3678                         app.bad = false;
3679                     }
3680                 }
3681             }
3682         } else {
3683             // If this is an isolated process, it can't re-use an existing process.
3684             app = null;
3685         }
3686
3687         // We don't have to do anything more if:
3688         // (1) There is an existing application record; and
3689         // (2) The caller doesn't think it is dead, OR there is no thread
3690         //     object attached to it so we know it couldn't have crashed; and
3691         // (3) There is a pid assigned to it, so it is either starting or
3692         //     already running.
3693         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3694                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3695                 + " thread=" + (app != null ? app.thread : null)
3696                 + " pid=" + (app != null ? app.pid : -1));
3697         if (app != null && app.pid > 0) {
3698             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3699                 // We already have the app running, or are waiting for it to
3700                 // come up (we have a pid but not yet its thread), so keep it.
3701                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3702                 // If this is a new package in the process, add the package to the list
3703                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3704                 checkTime(startTime, "startProcess: done, added package to proc");
3705                 return app;
3706             }
3707
3708             // An application record is attached to a previous process,
3709             // clean it up now.
3710             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3711             checkTime(startTime, "startProcess: bad proc running, killing");
3712             killProcessGroup(app.uid, app.pid);
3713             handleAppDiedLocked(app, true, true);
3714             checkTime(startTime, "startProcess: done killing old proc");
3715         }
3716
3717         String hostingNameStr = hostingName != null
3718                 ? hostingName.flattenToShortString() : null;
3719
3720         if (app == null) {
3721             checkTime(startTime, "startProcess: creating new process record");
3722             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3723             if (app == null) {
3724                 Slog.w(TAG, "Failed making new process record for "
3725                         + processName + "/" + info.uid + " isolated=" + isolated);
3726                 return null;
3727             }
3728             app.crashHandler = crashHandler;
3729             checkTime(startTime, "startProcess: done creating new process record");
3730         } else {
3731             // If this is a new package in the process, add the package to the list
3732             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3733             checkTime(startTime, "startProcess: added package to existing proc");
3734         }
3735
3736         // If the system is not ready yet, then hold off on starting this
3737         // process until it is.
3738         if (!mProcessesReady
3739                 && !isAllowedWhileBooting(info)
3740                 && !allowWhileBooting) {
3741             if (!mProcessesOnHold.contains(app)) {
3742                 mProcessesOnHold.add(app);
3743             }
3744             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3745                     "System not ready, putting on hold: " + app);
3746             checkTime(startTime, "startProcess: returning with proc on hold");
3747             return app;
3748         }
3749
3750         checkTime(startTime, "startProcess: stepping in to startProcess");
3751         startProcessLocked(
3752                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3753         checkTime(startTime, "startProcess: done starting proc!");
3754         return (app.pid != 0) ? app : null;
3755     }
3756
3757     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3758         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3759     }
3760
3761     private final void startProcessLocked(ProcessRecord app,
3762             String hostingType, String hostingNameStr) {
3763         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3764                 null /* entryPoint */, null /* entryPointArgs */);
3765     }
3766
3767     private final void startProcessLocked(ProcessRecord app, String hostingType,
3768             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3769         long startTime = SystemClock.elapsedRealtime();
3770         if (app.pid > 0 && app.pid != MY_PID) {
3771             checkTime(startTime, "startProcess: removing from pids map");
3772             synchronized (mPidsSelfLocked) {
3773                 mPidsSelfLocked.remove(app.pid);
3774                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3775             }
3776             checkTime(startTime, "startProcess: done removing from pids map");
3777             app.setPid(0);
3778         }
3779
3780         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3781                 "startProcessLocked removing on hold: " + app);
3782         mProcessesOnHold.remove(app);
3783
3784         checkTime(startTime, "startProcess: starting to update cpu stats");
3785         updateCpuStats();
3786         checkTime(startTime, "startProcess: done updating cpu stats");
3787
3788         try {
3789             try {
3790                 final int userId = UserHandle.getUserId(app.uid);
3791                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3792             } catch (RemoteException e) {
3793                 throw e.rethrowAsRuntimeException();
3794             }
3795
3796             int uid = app.uid;
3797             int[] gids = null;
3798             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3799             if (!app.isolated) {
3800                 int[] permGids = null;
3801                 try {
3802                     checkTime(startTime, "startProcess: getting gids from package manager");
3803                     final IPackageManager pm = AppGlobals.getPackageManager();
3804                     permGids = pm.getPackageGids(app.info.packageName,
3805                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3806                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
3807                             StorageManagerInternal.class);
3808                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3809                             app.info.packageName);
3810                 } catch (RemoteException e) {
3811                     throw e.rethrowAsRuntimeException();
3812                 }
3813
3814                 /*
3815                  * Add shared application and profile GIDs so applications can share some
3816                  * resources like shared libraries and access user-wide resources
3817                  */
3818                 if (ArrayUtils.isEmpty(permGids)) {
3819                     gids = new int[3];
3820                 } else {
3821                     gids = new int[permGids.length + 3];
3822                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
3823                 }
3824                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3825                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3826                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3827             }
3828             checkTime(startTime, "startProcess: building args");
3829             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3830                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3831                         && mTopComponent != null
3832                         && app.processName.equals(mTopComponent.getPackageName())) {
3833                     uid = 0;
3834                 }
3835                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3836                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3837                     uid = 0;
3838                 }
3839             }
3840             int debugFlags = 0;
3841             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3842                 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3843                 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3844                 // Also turn on CheckJNI for debuggable apps. It's quite
3845                 // awkward to turn on otherwise.
3846                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3847             }
3848             // Run the app in safe mode if its manifest requests so or the
3849             // system is booted in safe mode.
3850             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3851                 mSafeMode == true) {
3852                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3853             }
3854             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3855                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3856             }
3857             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3858             if ("true".equals(genDebugInfoProperty)) {
3859                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3860             }
3861             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3862                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3863             }
3864             if ("1".equals(SystemProperties.get("debug.assert"))) {
3865                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3866             }
3867             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3868                 // Enable all debug flags required by the native debugger.
3869                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3870                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3871                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3872                 mNativeDebuggingApp = null;
3873             }
3874
3875             String invokeWith = null;
3876             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3877                 // Debuggable apps may include a wrapper script with their library directory.
3878                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3879                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3880                 try {
3881                     if (new File(wrapperFileName).exists()) {
3882                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3883                     }
3884                 } finally {
3885                     StrictMode.setThreadPolicy(oldPolicy);
3886                 }
3887             }
3888
3889             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3890             if (requiredAbi == null) {
3891                 requiredAbi = Build.SUPPORTED_ABIS[0];
3892             }
3893
3894             String instructionSet = null;
3895             if (app.info.primaryCpuAbi != null) {
3896                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3897             }
3898
3899             app.gids = gids;
3900             app.requiredAbi = requiredAbi;
3901             app.instructionSet = instructionSet;
3902
3903             // the per-user SELinux context must be set
3904             if (TextUtils.isEmpty(app.info.seInfoUser)) {
3905                 Slog.wtf(TAG, "SELinux tag not defined",
3906                         new IllegalStateException("SELinux tag not defined for "
3907                         + app.info.packageName + " (uid " + app.uid + ")"));
3908             }
3909             final String seInfo = app.info.seInfo
3910                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3911             // Start the process.  It will either succeed and return a result containing
3912             // the PID of the new process, or else throw a RuntimeException.
3913             boolean isActivityProcess = (entryPoint == null);
3914             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3915             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3916                     app.processName);
3917             checkTime(startTime, "startProcess: asking zygote to start proc");
3918             ProcessStartResult startResult;
3919             if (hostingType.equals("webview_service")) {
3920                 startResult = startWebView(entryPoint,
3921                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3922                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3923                         app.info.dataDir, null, entryPointArgs);
3924             } else {
3925                 startResult = Process.start(entryPoint,
3926                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3927                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3928                         app.info.dataDir, invokeWith, entryPointArgs);
3929             }
3930             checkTime(startTime, "startProcess: returned from zygote!");
3931             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3932
3933             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3934             checkTime(startTime, "startProcess: done updating battery stats");
3935
3936             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3937                     UserHandle.getUserId(uid), startResult.pid, uid,
3938                     app.processName, hostingType,
3939                     hostingNameStr != null ? hostingNameStr : "");
3940
3941             try {
3942                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3943                         seInfo, app.info.sourceDir, startResult.pid);
3944             } catch (RemoteException ex) {
3945                 // Ignore
3946             }
3947
3948             if (app.persistent) {
3949                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3950             }
3951
3952             checkTime(startTime, "startProcess: building log message");
3953             StringBuilder buf = mStringBuilder;
3954             buf.setLength(0);
3955             buf.append("Start proc ");
3956             buf.append(startResult.pid);
3957             buf.append(':');
3958             buf.append(app.processName);
3959             buf.append('/');
3960             UserHandle.formatUid(buf, uid);
3961             if (!isActivityProcess) {
3962                 buf.append(" [");
3963                 buf.append(entryPoint);
3964                 buf.append("]");
3965             }
3966             buf.append(" for ");
3967             buf.append(hostingType);
3968             if (hostingNameStr != null) {
3969                 buf.append(" ");
3970                 buf.append(hostingNameStr);
3971             }
3972             Slog.i(TAG, buf.toString());
3973             app.setPid(startResult.pid);
3974             app.usingWrapper = startResult.usingWrapper;
3975             app.removed = false;
3976             app.killed = false;
3977             app.killedByAm = false;
3978             checkTime(startTime, "startProcess: starting to update pids map");
3979             ProcessRecord oldApp;
3980             synchronized (mPidsSelfLocked) {
3981                 oldApp = mPidsSelfLocked.get(startResult.pid);
3982             }
3983             // If there is already an app occupying that pid that hasn't been cleaned up
3984             if (oldApp != null && !app.isolated) {
3985                 // Clean up anything relating to this pid first
3986                 Slog.w(TAG, "Reusing pid " + startResult.pid
3987                         + " while app is still mapped to it");
3988                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3989                         true /*replacingPid*/);
3990             }
3991             synchronized (mPidsSelfLocked) {
3992                 this.mPidsSelfLocked.put(startResult.pid, app);
3993                 if (isActivityProcess) {
3994                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3995                     msg.obj = app;
3996                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3997                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3998                 }
3999             }
4000             checkTime(startTime, "startProcess: done updating pids map");
4001         } catch (RuntimeException e) {
4002             Slog.e(TAG, "Failure starting process " + app.processName, e);
4003
4004             // Something went very wrong while trying to start this process; one
4005             // common case is when the package is frozen due to an active
4006             // upgrade. To recover, clean up any active bookkeeping related to
4007             // starting this process. (We already invoked this method once when
4008             // the package was initially frozen through KILL_APPLICATION_MSG, so
4009             // it doesn't hurt to use it again.)
4010             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4011                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4012         }
4013     }
4014
4015     void updateUsageStats(ActivityRecord component, boolean resumed) {
4016         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4017                 "updateUsageStats: comp=" + component + "res=" + resumed);
4018         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4019         if (resumed) {
4020             if (mUsageStatsService != null) {
4021                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4022                         UsageEvents.Event.MOVE_TO_FOREGROUND);
4023             }
4024             synchronized (stats) {
4025                 stats.noteActivityResumedLocked(component.app.uid);
4026             }
4027         } else {
4028             if (mUsageStatsService != null) {
4029                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4030                         UsageEvents.Event.MOVE_TO_BACKGROUND);
4031             }
4032             synchronized (stats) {
4033                 stats.noteActivityPausedLocked(component.app.uid);
4034             }
4035         }
4036     }
4037
4038     Intent getHomeIntent() {
4039         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4040         intent.setComponent(mTopComponent);
4041         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4042         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4043             intent.addCategory(Intent.CATEGORY_HOME);
4044         }
4045         return intent;
4046     }
4047
4048     boolean startHomeActivityLocked(int userId, String reason) {
4049         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4050                 && mTopAction == null) {
4051             // We are running in factory test mode, but unable to find
4052             // the factory test app, so just sit around displaying the
4053             // error message and don't try to start anything.
4054             return false;
4055         }
4056         Intent intent = getHomeIntent();
4057         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4058         if (aInfo != null) {
4059             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4060             // Don't do this if the home app is currently being
4061             // instrumented.
4062             aInfo = new ActivityInfo(aInfo);
4063             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4064             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4065                     aInfo.applicationInfo.uid, true);
4066             if (app == null || app.instr == null) {
4067                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4068                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4069                 // For ANR debugging to verify if the user activity is the one that actually
4070                 // launched.
4071                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4072                 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4073             }
4074         } else {
4075             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4076         }
4077
4078         return true;
4079     }
4080
4081     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4082         ActivityInfo ai = null;
4083         ComponentName comp = intent.getComponent();
4084         try {
4085             if (comp != null) {
4086                 // Factory test.
4087                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4088             } else {
4089                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4090                         intent,
4091                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4092                         flags, userId);
4093
4094                 if (info != null) {
4095                     ai = info.activityInfo;
4096                 }
4097             }
4098         } catch (RemoteException e) {
4099             // ignore
4100         }
4101
4102         return ai;
4103     }
4104
4105     /**
4106      * Starts the "new version setup screen" if appropriate.
4107      */
4108     void startSetupActivityLocked() {
4109         // Only do this once per boot.
4110         if (mCheckedForSetup) {
4111             return;
4112         }
4113
4114         // We will show this screen if the current one is a different
4115         // version than the last one shown, and we are not running in
4116         // low-level factory test mode.
4117         final ContentResolver resolver = mContext.getContentResolver();
4118         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4119                 Settings.Global.getInt(resolver,
4120                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4121             mCheckedForSetup = true;
4122
4123             // See if we should be showing the platform update setup UI.
4124             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4125             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4126                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4127             if (!ris.isEmpty()) {
4128                 final ResolveInfo ri = ris.get(0);
4129                 String vers = ri.activityInfo.metaData != null
4130                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4131                         : null;
4132                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4133                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4134                             Intent.METADATA_SETUP_VERSION);
4135                 }
4136                 String lastVers = Settings.Secure.getString(
4137                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4138                 if (vers != null && !vers.equals(lastVers)) {
4139                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4140                     intent.setComponent(new ComponentName(
4141                             ri.activityInfo.packageName, ri.activityInfo.name));
4142                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4143                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4144                             null, 0, 0, 0, null, false, false, null, null, null,
4145                             "startSetupActivity");
4146                 }
4147             }
4148         }
4149     }
4150
4151     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4152         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4153     }
4154
4155     void enforceNotIsolatedCaller(String caller) {
4156         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4157             throw new SecurityException("Isolated process not allowed to call " + caller);
4158         }
4159     }
4160
4161     void enforceShellRestriction(String restriction, int userHandle) {
4162         if (Binder.getCallingUid() == SHELL_UID) {
4163             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4164                 throw new SecurityException("Shell does not have permission to access user "
4165                         + userHandle);
4166             }
4167         }
4168     }
4169
4170     @Override
4171     public int getFrontActivityScreenCompatMode() {
4172         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4173         synchronized (this) {
4174             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4175         }
4176     }
4177
4178     @Override
4179     public void setFrontActivityScreenCompatMode(int mode) {
4180         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4181                 "setFrontActivityScreenCompatMode");
4182         synchronized (this) {
4183             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4184         }
4185     }
4186
4187     @Override
4188     public int getPackageScreenCompatMode(String packageName) {
4189         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4190         synchronized (this) {
4191             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4192         }
4193     }
4194
4195     @Override
4196     public void setPackageScreenCompatMode(String packageName, int mode) {
4197         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4198                 "setPackageScreenCompatMode");
4199         synchronized (this) {
4200             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4201         }
4202     }
4203
4204     @Override
4205     public boolean getPackageAskScreenCompat(String packageName) {
4206         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4207         synchronized (this) {
4208             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4209         }
4210     }
4211
4212     @Override
4213     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4214         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4215                 "setPackageAskScreenCompat");
4216         synchronized (this) {
4217             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4218         }
4219     }
4220
4221     private boolean hasUsageStatsPermission(String callingPackage) {
4222         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4223                 Binder.getCallingUid(), callingPackage);
4224         if (mode == AppOpsManager.MODE_DEFAULT) {
4225             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4226                     == PackageManager.PERMISSION_GRANTED;
4227         }
4228         return mode == AppOpsManager.MODE_ALLOWED;
4229     }
4230
4231     @Override
4232     public int getPackageProcessState(String packageName, String callingPackage) {
4233         if (!hasUsageStatsPermission(callingPackage)) {
4234             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4235                     "getPackageProcessState");
4236         }
4237
4238         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4239         synchronized (this) {
4240             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4241                 final ProcessRecord proc = mLruProcesses.get(i);
4242                 if (procState > proc.setProcState) {
4243                     if (proc.pkgList.containsKey(packageName) ||
4244                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4245                         procState = proc.setProcState;
4246                     }
4247                 }
4248             }
4249         }
4250         return procState;
4251     }
4252
4253     @Override
4254     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4255             throws RemoteException {
4256         synchronized (this) {
4257             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4258             if (app == null) {
4259                 throw new IllegalArgumentException("Unknown process: " + process);
4260             }
4261             if (app.thread == null) {
4262                 throw new IllegalArgumentException("Process has no app thread");
4263             }
4264             if (app.trimMemoryLevel >= level) {
4265                 throw new IllegalArgumentException(
4266                         "Unable to set a higher trim level than current level");
4267             }
4268             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4269                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4270                 throw new IllegalArgumentException("Unable to set a background trim level "
4271                     + "on a foreground process");
4272             }
4273             app.thread.scheduleTrimMemory(level);
4274             app.trimMemoryLevel = level;
4275             return true;
4276         }
4277     }
4278
4279     private void dispatchProcessesChanged() {
4280         int N;
4281         synchronized (this) {
4282             N = mPendingProcessChanges.size();
4283             if (mActiveProcessChanges.length < N) {
4284                 mActiveProcessChanges = new ProcessChangeItem[N];
4285             }
4286             mPendingProcessChanges.toArray(mActiveProcessChanges);
4287             mPendingProcessChanges.clear();
4288             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4289                     "*** Delivering " + N + " process changes");
4290         }
4291
4292         int i = mProcessObservers.beginBroadcast();
4293         while (i > 0) {
4294             i--;
4295             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4296             if (observer != null) {
4297                 try {
4298                     for (int j=0; j<N; j++) {
4299                         ProcessChangeItem item = mActiveProcessChanges[j];
4300                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4301                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4302                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4303                                     + item.uid + ": " + item.foregroundActivities);
4304                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4305                                     item.foregroundActivities);
4306                         }
4307                     }
4308                 } catch (RemoteException e) {
4309                 }
4310             }
4311         }
4312         mProcessObservers.finishBroadcast();
4313
4314         synchronized (this) {
4315             for (int j=0; j<N; j++) {
4316                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4317             }
4318         }
4319     }
4320
4321     private void dispatchProcessDied(int pid, int uid) {
4322         int i = mProcessObservers.beginBroadcast();
4323         while (i > 0) {
4324             i--;
4325             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4326             if (observer != null) {
4327                 try {
4328                     observer.onProcessDied(pid, uid);
4329                 } catch (RemoteException e) {
4330                 }
4331             }
4332         }
4333         mProcessObservers.finishBroadcast();
4334     }
4335
4336     @VisibleForTesting
4337     void dispatchUidsChanged() {
4338         int N;
4339         synchronized (this) {
4340             N = mPendingUidChanges.size();
4341             if (mActiveUidChanges.length < N) {
4342                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4343             }
4344             for (int i=0; i<N; i++) {
4345                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4346                 mActiveUidChanges[i] = change;
4347                 if (change.uidRecord != null) {
4348                     change.uidRecord.pendingChange = null;
4349                     change.uidRecord = null;
4350                 }
4351             }
4352             mPendingUidChanges.clear();
4353             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4354                     "*** Delivering " + N + " uid changes");
4355         }
4356
4357         int i = mUidObservers.beginBroadcast();
4358         while (i > 0) {
4359             i--;
4360             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4361                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4362         }
4363         mUidObservers.finishBroadcast();
4364
4365         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4366             for (int j = 0; j < N; ++j) {
4367                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4368                 if (item.change == UidRecord.CHANGE_GONE
4369                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4370                     mValidateUids.remove(item.uid);
4371                 } else {
4372                     UidRecord validateUid = mValidateUids.get(item.uid);
4373                     if (validateUid == null) {
4374                         validateUid = new UidRecord(item.uid);
4375                         mValidateUids.put(item.uid, validateUid);
4376                     }
4377                     if (item.change == UidRecord.CHANGE_IDLE) {
4378                         validateUid.idle = true;
4379                     } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4380                         validateUid.idle = false;
4381                     }
4382                     validateUid.curProcState = validateUid.setProcState = item.processState;
4383                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4384                 }
4385             }
4386         }
4387
4388         synchronized (this) {
4389             for (int j = 0; j < N; j++) {
4390                 mAvailUidChanges.add(mActiveUidChanges[j]);
4391             }
4392         }
4393     }
4394
4395     private void dispatchUidsChangedForObserver(IUidObserver observer,
4396             UidObserverRegistration reg, int changesSize) {
4397         if (observer == null) {
4398             return;
4399         }
4400         try {
4401             for (int j = 0; j < changesSize; j++) {
4402                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4403                 final int change = item.change;
4404                 if (change == UidRecord.CHANGE_IDLE
4405                         || change == UidRecord.CHANGE_GONE_IDLE) {
4406                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4407                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4408                                 "UID idle uid=" + item.uid);
4409                         observer.onUidIdle(item.uid, item.ephemeral);
4410                     }
4411                 } else if (change == UidRecord.CHANGE_ACTIVE) {
4412                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4413                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4414                                 "UID active uid=" + item.uid);
4415                         observer.onUidActive(item.uid);
4416                     }
4417                 }
4418                 if (change == UidRecord.CHANGE_GONE
4419                         || change == UidRecord.CHANGE_GONE_IDLE) {
4420                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4421                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422                                 "UID gone uid=" + item.uid);
4423                         observer.onUidGone(item.uid, item.ephemeral);
4424                     }
4425                     if (reg.lastProcStates != null) {
4426                         reg.lastProcStates.delete(item.uid);
4427                     }
4428                 } else {
4429                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4430                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4431                                 "UID CHANGED uid=" + item.uid
4432                                         + ": " + item.processState);
4433                         boolean doReport = true;
4434                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4435                             final int lastState = reg.lastProcStates.get(item.uid,
4436                                     ActivityManager.PROCESS_STATE_UNKNOWN);
4437                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4438                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
4439                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
4440                                 doReport = lastAboveCut != newAboveCut;
4441                             } else {
4442                                 doReport = item.processState
4443                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
4444                             }
4445                         }
4446                         if (doReport) {
4447                             if (reg.lastProcStates != null) {
4448                                 reg.lastProcStates.put(item.uid, item.processState);
4449                             }
4450                             observer.onUidStateChanged(item.uid, item.processState,
4451                                     item.procStateSeq);
4452                         }
4453                     }
4454                 }
4455             }
4456         } catch (RemoteException e) {
4457         }
4458     }
4459
4460     @Override
4461     public final int startActivity(IApplicationThread caller, String callingPackage,
4462             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4463             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4464         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4465                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4466                 UserHandle.getCallingUserId());
4467     }
4468
4469     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4470         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4471         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4472                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4473                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4474
4475         // TODO: Switch to user app stacks here.
4476         String mimeType = intent.getType();
4477         final Uri data = intent.getData();
4478         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4479             mimeType = getProviderMimeType(data, userId);
4480         }
4481         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4482
4483         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4484         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null,
4485                 null, null, 0, 0, null, null, null, null, false, userId, container, null,
4486                 "startActivity");
4487     }
4488
4489     @Override
4490     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4491             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4492             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4493         enforceNotIsolatedCaller("startActivity");
4494         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4495                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4496         // TODO: Switch to user app stacks here.
4497         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4498                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4499                 profilerInfo, null, null, bOptions, false, userId, null, null,
4500                 "startActivityAsUser");
4501     }
4502
4503     @Override
4504     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4505             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4506             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4507             int userId) {
4508
4509         // This is very dangerous -- it allows you to perform a start activity (including
4510         // permission grants) as any app that may launch one of your own activities.  So
4511         // we will only allow this to be done from activities that are part of the core framework,
4512         // and then only when they are running as the system.
4513         final ActivityRecord sourceRecord;
4514         final int targetUid;
4515         final String targetPackage;
4516         synchronized (this) {
4517             if (resultTo == null) {
4518                 throw new SecurityException("Must be called from an activity");
4519             }
4520             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4521             if (sourceRecord == null) {
4522                 throw new SecurityException("Called with bad activity token: " + resultTo);
4523             }
4524             if (!sourceRecord.info.packageName.equals("android")) {
4525                 throw new SecurityException(
4526                         "Must be called from an activity that is declared in the android package");
4527             }
4528             if (sourceRecord.app == null) {
4529                 throw new SecurityException("Called without a process attached to activity");
4530             }
4531             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4532                 // This is still okay, as long as this activity is running under the
4533                 // uid of the original calling activity.
4534                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4535                     throw new SecurityException(
4536                             "Calling activity in uid " + sourceRecord.app.uid
4537                                     + " must be system uid or original calling uid "
4538                                     + sourceRecord.launchedFromUid);
4539                 }
4540             }
4541             if (ignoreTargetSecurity) {
4542                 if (intent.getComponent() == null) {
4543                     throw new SecurityException(
4544                             "Component must be specified with ignoreTargetSecurity");
4545                 }
4546                 if (intent.getSelector() != null) {
4547                     throw new SecurityException(
4548                             "Selector not allowed with ignoreTargetSecurity");
4549                 }
4550             }
4551             targetUid = sourceRecord.launchedFromUid;
4552             targetPackage = sourceRecord.launchedFromPackage;
4553         }
4554
4555         if (userId == UserHandle.USER_NULL) {
4556             userId = UserHandle.getUserId(sourceRecord.app.uid);
4557         }
4558
4559         // TODO: Switch to user app stacks here.
4560         try {
4561             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4562                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4563                     null, null, bOptions, ignoreTargetSecurity, userId, null, null,
4564                     "startActivityAsCaller");
4565             return ret;
4566         } catch (SecurityException e) {
4567             // XXX need to figure out how to propagate to original app.
4568             // A SecurityException here is generally actually a fault of the original
4569             // calling activity (such as a fairly granting permissions), so propagate it
4570             // back to them.
4571             /*
4572             StringBuilder msg = new StringBuilder();
4573             msg.append("While launching");
4574             msg.append(intent.toString());
4575             msg.append(": ");
4576             msg.append(e.getMessage());
4577             */
4578             throw e;
4579         }
4580     }
4581
4582     @Override
4583     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4584             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4585             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4586         enforceNotIsolatedCaller("startActivityAndWait");
4587         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4588                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4589         WaitResult res = new WaitResult();
4590         // TODO: Switch to user app stacks here.
4591         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4592                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4593                 bOptions, false, userId, null, null, "startActivityAndWait");
4594         return res;
4595     }
4596
4597     @Override
4598     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4599             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4600             int startFlags, Configuration config, Bundle bOptions, int userId) {
4601         enforceNotIsolatedCaller("startActivityWithConfig");
4602         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4603                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4604         // TODO: Switch to user app stacks here.
4605         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4606                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4607                 null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig");
4608         return ret;
4609     }
4610
4611     @Override
4612     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4613             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4614             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4615             throws TransactionTooLargeException {
4616         enforceNotIsolatedCaller("startActivityIntentSender");
4617         // Refuse possible leaked file descriptors
4618         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4619             throw new IllegalArgumentException("File descriptors passed in Intent");
4620         }
4621
4622         if (!(target instanceof PendingIntentRecord)) {
4623             throw new IllegalArgumentException("Bad PendingIntent object");
4624         }
4625
4626         PendingIntentRecord pir = (PendingIntentRecord)target;
4627
4628         synchronized (this) {
4629             // If this is coming from the currently resumed activity, it is
4630             // effectively saying that app switches are allowed at this point.
4631             final ActivityStack stack = getFocusedStack();
4632             if (stack.mResumedActivity != null &&
4633                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4634                 mAppSwitchesAllowedTime = 0;
4635             }
4636         }
4637         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4638                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4639         return ret;
4640     }
4641
4642     @Override
4643     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4644             Intent intent, String resolvedType, IVoiceInteractionSession session,
4645             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4646             Bundle bOptions, int userId) {
4647         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4648                 != PackageManager.PERMISSION_GRANTED) {
4649             String msg = "Permission Denial: startVoiceActivity() from pid="
4650                     + Binder.getCallingPid()
4651                     + ", uid=" + Binder.getCallingUid()
4652                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4653             Slog.w(TAG, msg);
4654             throw new SecurityException(msg);
4655         }
4656         if (session == null || interactor == null) {
4657             throw new NullPointerException("null session or interactor");
4658         }
4659         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4660                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4661         // TODO: Switch to user app stacks here.
4662         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4663                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4664                 null, bOptions, false, userId, null, null, "startVoiceActivity");
4665     }
4666
4667     @Override
4668     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4669             Intent intent, String resolvedType, Bundle bOptions, int userId) {
4670         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4671                 != PackageManager.PERMISSION_GRANTED) {
4672             final String msg = "Permission Denial: startAssistantActivity() from pid="
4673                     + Binder.getCallingPid()
4674                     + ", uid=" + Binder.getCallingUid()
4675                     + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4676             Slog.w(TAG, msg);
4677             throw new SecurityException(msg);
4678         }
4679         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4680                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4681         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4682                 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4683                 userId, null, null, "startAssistantActivity");
4684     }
4685
4686     @Override
4687     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4688             throws RemoteException {
4689         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4690         synchronized (this) {
4691             ActivityRecord activity = getFocusedStack().topActivity();
4692             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4693                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4694             }
4695             if (mRunningVoice != null || activity.getTask().voiceSession != null
4696                     || activity.voiceSession != null) {
4697                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4698                 return;
4699             }
4700             if (activity.pendingVoiceInteractionStart) {
4701                 Slog.w(TAG, "Pending start of voice interaction already.");
4702                 return;
4703             }
4704             activity.pendingVoiceInteractionStart = true;
4705         }
4706         LocalServices.getService(VoiceInteractionManagerInternal.class)
4707                 .startLocalVoiceInteraction(callingActivity, options);
4708     }
4709
4710     @Override
4711     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4712         LocalServices.getService(VoiceInteractionManagerInternal.class)
4713                 .stopLocalVoiceInteraction(callingActivity);
4714     }
4715
4716     @Override
4717     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4718         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4719                 .supportsLocalVoiceInteraction();
4720     }
4721
4722     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4723             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4724         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4725         if (activityToCallback == null) return;
4726         activityToCallback.setVoiceSessionLocked(voiceSession);
4727
4728         // Inform the activity
4729         try {
4730             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4731                     voiceInteractor);
4732             long token = Binder.clearCallingIdentity();
4733             try {
4734                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4735             } finally {
4736                 Binder.restoreCallingIdentity(token);
4737             }
4738             // TODO: VI Should we cache the activity so that it's easier to find later
4739             // rather than scan through all the stacks and activities?
4740         } catch (RemoteException re) {
4741             activityToCallback.clearVoiceSessionLocked();
4742             // TODO: VI Should this terminate the voice session?
4743         }
4744     }
4745
4746     @Override
4747     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4748         synchronized (this) {
4749             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4750                 if (keepAwake) {
4751                     mVoiceWakeLock.acquire();
4752                 } else {
4753                     mVoiceWakeLock.release();
4754                 }
4755             }
4756         }
4757     }
4758
4759     @Override
4760     public boolean startNextMatchingActivity(IBinder callingActivity,
4761             Intent intent, Bundle bOptions) {
4762         // Refuse possible leaked file descriptors
4763         if (intent != null && intent.hasFileDescriptors() == true) {
4764             throw new IllegalArgumentException("File descriptors passed in Intent");
4765         }
4766         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4767
4768         synchronized (this) {
4769             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4770             if (r == null) {
4771                 ActivityOptions.abort(options);
4772                 return false;
4773             }
4774             if (r.app == null || r.app.thread == null) {
4775                 // The caller is not running...  d'oh!
4776                 ActivityOptions.abort(options);
4777                 return false;
4778             }
4779             intent = new Intent(intent);
4780             // The caller is not allowed to change the data.
4781             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4782             // And we are resetting to find the next component...
4783             intent.setComponent(null);
4784
4785             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4786
4787             ActivityInfo aInfo = null;
4788             try {
4789                 List<ResolveInfo> resolves =
4790                     AppGlobals.getPackageManager().queryIntentActivities(
4791                             intent, r.resolvedType,
4792                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4793                             UserHandle.getCallingUserId()).getList();
4794
4795                 // Look for the original activity in the list...
4796                 final int N = resolves != null ? resolves.size() : 0;
4797                 for (int i=0; i<N; i++) {
4798                     ResolveInfo rInfo = resolves.get(i);
4799                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4800                             && rInfo.activityInfo.name.equals(r.info.name)) {
4801                         // We found the current one...  the next matching is
4802                         // after it.
4803                         i++;
4804                         if (i<N) {
4805                             aInfo = resolves.get(i).activityInfo;
4806                         }
4807                         if (debug) {
4808                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4809                                     + "/" + r.info.name);
4810                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4811                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4812                         }
4813                         break;
4814                     }
4815                 }
4816             } catch (RemoteException e) {
4817             }
4818
4819             if (aInfo == null) {
4820                 // Nobody who is next!
4821                 ActivityOptions.abort(options);
4822                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4823                 return false;
4824             }
4825
4826             intent.setComponent(new ComponentName(
4827                     aInfo.applicationInfo.packageName, aInfo.name));
4828             intent.setFlags(intent.getFlags()&~(
4829                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4830                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4831                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4832                     Intent.FLAG_ACTIVITY_NEW_TASK));
4833
4834             // Okay now we need to start the new activity, replacing the
4835             // currently running activity.  This is a little tricky because
4836             // we want to start the new one as if the current one is finished,
4837             // but not finish the current one first so that there is no flicker.
4838             // And thus...
4839             final boolean wasFinishing = r.finishing;
4840             r.finishing = true;
4841
4842             // Propagate reply information over to the new activity.
4843             final ActivityRecord resultTo = r.resultTo;
4844             final String resultWho = r.resultWho;
4845             final int requestCode = r.requestCode;
4846             r.resultTo = null;
4847             if (resultTo != null) {
4848                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4849             }
4850
4851             final long origId = Binder.clearCallingIdentity();
4852             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4853                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4854                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4855                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4856                     false, false, null, null, null, "startNextMatchingActivity");
4857             Binder.restoreCallingIdentity(origId);
4858
4859             r.finishing = wasFinishing;
4860             if (res != ActivityManager.START_SUCCESS) {
4861                 return false;
4862             }
4863             return true;
4864         }
4865     }
4866
4867     @Override
4868     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4869         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4870             String msg = "Permission Denial: startActivityFromRecents called without " +
4871                     START_TASKS_FROM_RECENTS;
4872             Slog.w(TAG, msg);
4873             throw new SecurityException(msg);
4874         }
4875         final long origId = Binder.clearCallingIdentity();
4876         try {
4877             synchronized (this) {
4878                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4879             }
4880         } finally {
4881             Binder.restoreCallingIdentity(origId);
4882         }
4883     }
4884
4885     final int startActivityInPackage(int uid, String callingPackage,
4886             Intent intent, String resolvedType, IBinder resultTo,
4887             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4888             IActivityContainer container, TaskRecord inTask, String reason) {
4889
4890         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4891                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4892
4893         // TODO: Switch to user app stacks here.
4894         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4895                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4896                 null, null, null, bOptions, false, userId, container, inTask, reason);
4897         return ret;
4898     }
4899
4900     @Override
4901     public final int startActivities(IApplicationThread caller, String callingPackage,
4902             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4903             int userId) {
4904         final String reason = "startActivities";
4905         enforceNotIsolatedCaller(reason);
4906         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4907                 userId, false, ALLOW_FULL_ONLY, reason, null);
4908         // TODO: Switch to user app stacks here.
4909         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4910                 resolvedTypes, resultTo, bOptions, userId, reason);
4911         return ret;
4912     }
4913
4914     final int startActivitiesInPackage(int uid, String callingPackage,
4915             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4916             Bundle bOptions, int userId) {
4917
4918         final String reason = "startActivityInPackage";
4919         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4920                 userId, false, ALLOW_FULL_ONLY, reason, null);
4921         // TODO: Switch to user app stacks here.
4922         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4923                 resultTo, bOptions, userId, reason);
4924         return ret;
4925     }
4926
4927     @Override
4928     public void reportActivityFullyDrawn(IBinder token) {
4929         synchronized (this) {
4930             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4931             if (r == null) {
4932                 return;
4933             }
4934             r.reportFullyDrawnLocked();
4935         }
4936     }
4937
4938     @Override
4939     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4940         synchronized (this) {
4941             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4942             if (r == null) {
4943                 return;
4944             }
4945             final long origId = Binder.clearCallingIdentity();
4946             try {
4947                 r.setRequestedOrientation(requestedOrientation);
4948             } finally {
4949                 Binder.restoreCallingIdentity(origId);
4950             }
4951         }
4952     }
4953
4954     @Override
4955     public int getRequestedOrientation(IBinder token) {
4956         synchronized (this) {
4957             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4958             if (r == null) {
4959                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4960             }
4961             return r.getRequestedOrientation();
4962         }
4963     }
4964
4965     @Override
4966     public final void requestActivityRelaunch(IBinder token) {
4967         synchronized(this) {
4968             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4969             if (r == null) {
4970                 return;
4971             }
4972             final long origId = Binder.clearCallingIdentity();
4973             try {
4974                 r.forceNewConfig = true;
4975                 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4976                         true /* preserveWindow */);
4977             } finally {
4978                 Binder.restoreCallingIdentity(origId);
4979             }
4980         }
4981     }
4982
4983     /**
4984      * This is the internal entry point for handling Activity.finish().
4985      *
4986      * @param token The Binder token referencing the Activity we want to finish.
4987      * @param resultCode Result code, if any, from this Activity.
4988      * @param resultData Result data (Intent), if any, from this Activity.
4989      * @param finishTask Whether to finish the task associated with this Activity.
4990      *
4991      * @return Returns true if the activity successfully finished, or false if it is still running.
4992      */
4993     @Override
4994     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4995             int finishTask) {
4996         // Refuse possible leaked file descriptors
4997         if (resultData != null && resultData.hasFileDescriptors() == true) {
4998             throw new IllegalArgumentException("File descriptors passed in Intent");
4999         }
5000
5001         synchronized(this) {
5002             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5003             if (r == null) {
5004                 return true;
5005             }
5006             // Keep track of the root activity of the task before we finish it
5007             TaskRecord tr = r.getTask();
5008             ActivityRecord rootR = tr.getRootActivity();
5009             if (rootR == null) {
5010                 Slog.w(TAG, "Finishing task with all activities already finished");
5011             }
5012             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5013             // finish.
5014             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5015                     mStackSupervisor.isLastLockedTask(tr)) {
5016                 Slog.i(TAG, "Not finishing task in lock task mode");
5017                 mStackSupervisor.showLockTaskToast();
5018                 return false;
5019             }
5020             if (mController != null) {
5021                 // Find the first activity that is not finishing.
5022                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5023                 if (next != null) {
5024                     // ask watcher if this is allowed
5025                     boolean resumeOK = true;
5026                     try {
5027                         resumeOK = mController.activityResuming(next.packageName);
5028                     } catch (RemoteException e) {
5029                         mController = null;
5030                         Watchdog.getInstance().setActivityController(null);
5031                     }
5032
5033                     if (!resumeOK) {
5034                         Slog.i(TAG, "Not finishing activity because controller resumed");
5035                         return false;
5036                     }
5037                 }
5038             }
5039             final long origId = Binder.clearCallingIdentity();
5040             try {
5041                 boolean res;
5042                 final boolean finishWithRootActivity =
5043                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5044                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5045                         || (finishWithRootActivity && r == rootR)) {
5046                     // If requested, remove the task that is associated to this activity only if it
5047                     // was the root activity in the task. The result code and data is ignored
5048                     // because we don't support returning them across task boundaries. Also, to
5049                     // keep backwards compatibility we remove the task from recents when finishing
5050                     // task with root activity.
5051                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5052                     if (!res) {
5053                         Slog.i(TAG, "Removing task failed to finish activity");
5054                     }
5055                 } else {
5056                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5057                             resultData, "app-request", true);
5058                     if (!res) {
5059                         Slog.i(TAG, "Failed to finish by app-request");
5060                     }
5061                 }
5062                 return res;
5063             } finally {
5064                 Binder.restoreCallingIdentity(origId);
5065             }
5066         }
5067     }
5068
5069     @Override
5070     public final void finishHeavyWeightApp() {
5071         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5072                 != PackageManager.PERMISSION_GRANTED) {
5073             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5074                     + Binder.getCallingPid()
5075                     + ", uid=" + Binder.getCallingUid()
5076                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5077             Slog.w(TAG, msg);
5078             throw new SecurityException(msg);
5079         }
5080
5081         synchronized(this) {
5082             if (mHeavyWeightProcess == null) {
5083                 return;
5084             }
5085
5086             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5087             for (int i = 0; i < activities.size(); i++) {
5088                 ActivityRecord r = activities.get(i);
5089                 if (!r.finishing && r.isInStackLocked()) {
5090                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5091                             null, "finish-heavy", true);
5092                 }
5093             }
5094
5095             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5096                     mHeavyWeightProcess.userId, 0));
5097             mHeavyWeightProcess = null;
5098         }
5099     }
5100
5101     @Override
5102     public void crashApplication(int uid, int initialPid, String packageName, int userId,
5103             String message) {
5104         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5105                 != PackageManager.PERMISSION_GRANTED) {
5106             String msg = "Permission Denial: crashApplication() from pid="
5107                     + Binder.getCallingPid()
5108                     + ", uid=" + Binder.getCallingUid()
5109                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5110             Slog.w(TAG, msg);
5111             throw new SecurityException(msg);
5112         }
5113
5114         synchronized(this) {
5115             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5116         }
5117     }
5118
5119     @Override
5120     public final void finishSubActivity(IBinder token, String resultWho,
5121             int requestCode) {
5122         synchronized(this) {
5123             final long origId = Binder.clearCallingIdentity();
5124             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5125             if (r != null) {
5126                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5127             }
5128             Binder.restoreCallingIdentity(origId);
5129         }
5130     }
5131
5132     @Override
5133     public boolean finishActivityAffinity(IBinder token) {
5134         synchronized(this) {
5135             final long origId = Binder.clearCallingIdentity();
5136             try {
5137                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5138                 if (r == null) {
5139                     return false;
5140                 }
5141
5142                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5143                 // can finish.
5144                 final TaskRecord task = r.getTask();
5145                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5146                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5147                     mStackSupervisor.showLockTaskToast();
5148                     return false;
5149                 }
5150                 return task.getStack().finishActivityAffinityLocked(r);
5151             } finally {
5152                 Binder.restoreCallingIdentity(origId);
5153             }
5154         }
5155     }
5156
5157     @Override
5158     public void finishVoiceTask(IVoiceInteractionSession session) {
5159         synchronized (this) {
5160             final long origId = Binder.clearCallingIdentity();
5161             try {
5162                 // TODO: VI Consider treating local voice interactions and voice tasks
5163                 // differently here
5164                 mStackSupervisor.finishVoiceTask(session);
5165             } finally {
5166                 Binder.restoreCallingIdentity(origId);
5167             }
5168         }
5169
5170     }
5171
5172     @Override
5173     public boolean releaseActivityInstance(IBinder token) {
5174         synchronized(this) {
5175             final long origId = Binder.clearCallingIdentity();
5176             try {
5177                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5178                 if (r == null) {
5179                     return false;
5180                 }
5181                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5182             } finally {
5183                 Binder.restoreCallingIdentity(origId);
5184             }
5185         }
5186     }
5187
5188     @Override
5189     public void releaseSomeActivities(IApplicationThread appInt) {
5190         synchronized(this) {
5191             final long origId = Binder.clearCallingIdentity();
5192             try {
5193                 ProcessRecord app = getRecordForAppLocked(appInt);
5194                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5195             } finally {
5196                 Binder.restoreCallingIdentity(origId);
5197             }
5198         }
5199     }
5200
5201     @Override
5202     public boolean willActivityBeVisible(IBinder token) {
5203         synchronized(this) {
5204             ActivityStack stack = ActivityRecord.getStackLocked(token);
5205             if (stack != null) {
5206                 return stack.willActivityBeVisibleLocked(token);
5207             }
5208             return false;
5209         }
5210     }
5211
5212     @Override
5213     public void overridePendingTransition(IBinder token, String packageName,
5214             int enterAnim, int exitAnim) {
5215         synchronized(this) {
5216             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5217             if (self == null) {
5218                 return;
5219             }
5220
5221             final long origId = Binder.clearCallingIdentity();
5222
5223             if (self.state == ActivityState.RESUMED
5224                     || self.state == ActivityState.PAUSING) {
5225                 mWindowManager.overridePendingAppTransition(packageName,
5226                         enterAnim, exitAnim, null);
5227             }
5228
5229             Binder.restoreCallingIdentity(origId);
5230         }
5231     }
5232
5233     /**
5234      * Main function for removing an existing process from the activity manager
5235      * as a result of that process going away.  Clears out all connections
5236      * to the process.
5237      */
5238     private final void handleAppDiedLocked(ProcessRecord app,
5239             boolean restarting, boolean allowRestart) {
5240         int pid = app.pid;
5241         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5242                 false /*replacingPid*/);
5243         if (!kept && !restarting) {
5244             removeLruProcessLocked(app);
5245             if (pid > 0) {
5246                 ProcessList.remove(pid);
5247             }
5248         }
5249
5250         if (mProfileProc == app) {
5251             clearProfilerLocked();
5252         }
5253
5254         // Remove this application's activities from active lists.
5255         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5256
5257         app.activities.clear();
5258
5259         if (app.instr != null) {
5260             Slog.w(TAG, "Crash of app " + app.processName
5261                   + " running instrumentation " + app.instr.mClass);
5262             Bundle info = new Bundle();
5263             info.putString("shortMsg", "Process crashed.");
5264             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5265         }
5266
5267         mWindowManager.deferSurfaceLayout();
5268         try {
5269             if (!restarting && hasVisibleActivities
5270                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5271                 // If there was nothing to resume, and we are not already restarting this process, but
5272                 // there is a visible activity that is hosted by the process...  then make sure all
5273                 // visible activities are running, taking care of restarting this process.
5274                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5275             }
5276         } finally {
5277             mWindowManager.continueSurfaceLayout();
5278         }
5279     }
5280
5281     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5282         final IBinder threadBinder = thread.asBinder();
5283         // Find the application record.
5284         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5285             final ProcessRecord rec = mLruProcesses.get(i);
5286             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5287                 return i;
5288             }
5289         }
5290         return -1;
5291     }
5292
5293     final ProcessRecord getRecordForAppLocked(
5294             IApplicationThread thread) {
5295         if (thread == null) {
5296             return null;
5297         }
5298
5299         int appIndex = getLRURecordIndexForAppLocked(thread);
5300         if (appIndex >= 0) {
5301             return mLruProcesses.get(appIndex);
5302         }
5303
5304         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5305         // double-check that.
5306         final IBinder threadBinder = thread.asBinder();
5307         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5308         for (int i = pmap.size()-1; i >= 0; i--) {
5309             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5310             for (int j = procs.size()-1; j >= 0; j--) {
5311                 final ProcessRecord proc = procs.valueAt(j);
5312                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5313                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5314                             + proc);
5315                     return proc;
5316                 }
5317             }
5318         }
5319
5320         return null;
5321     }
5322
5323     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5324         // If there are no longer any background processes running,
5325         // and the app that died was not running instrumentation,
5326         // then tell everyone we are now low on memory.
5327         boolean haveBg = false;
5328         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5329             ProcessRecord rec = mLruProcesses.get(i);
5330             if (rec.thread != null
5331                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5332                 haveBg = true;
5333                 break;
5334             }
5335         }
5336
5337         if (!haveBg) {
5338             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5339             if (doReport) {
5340                 long now = SystemClock.uptimeMillis();
5341                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5342                     doReport = false;
5343                 } else {
5344                     mLastMemUsageReportTime = now;
5345                 }
5346             }
5347             final ArrayList<ProcessMemInfo> memInfos
5348                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5349             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5350             long now = SystemClock.uptimeMillis();
5351             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5352                 ProcessRecord rec = mLruProcesses.get(i);
5353                 if (rec == dyingProc || rec.thread == null) {
5354                     continue;
5355                 }
5356                 if (doReport) {
5357                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5358                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5359                 }
5360                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5361                     // The low memory report is overriding any current
5362                     // state for a GC request.  Make sure to do
5363                     // heavy/important/visible/foreground processes first.
5364                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5365                         rec.lastRequestedGc = 0;
5366                     } else {
5367                         rec.lastRequestedGc = rec.lastLowMemory;
5368                     }
5369                     rec.reportLowMemory = true;
5370                     rec.lastLowMemory = now;
5371                     mProcessesToGc.remove(rec);
5372                     addProcessToGcListLocked(rec);
5373                 }
5374             }
5375             if (doReport) {
5376                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5377                 mHandler.sendMessage(msg);
5378             }
5379             scheduleAppGcsLocked();
5380         }
5381     }
5382
5383     final void appDiedLocked(ProcessRecord app) {
5384        appDiedLocked(app, app.pid, app.thread, false);
5385     }
5386
5387     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5388             boolean fromBinderDied) {
5389         // First check if this ProcessRecord is actually active for the pid.
5390         synchronized (mPidsSelfLocked) {
5391             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5392             if (curProc != app) {
5393                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5394                 return;
5395             }
5396         }
5397
5398         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5399         synchronized (stats) {
5400             stats.noteProcessDiedLocked(app.info.uid, pid);
5401         }
5402
5403         if (!app.killed) {
5404             if (!fromBinderDied) {
5405                 killProcessQuiet(pid);
5406             }
5407             killProcessGroup(app.uid, pid);
5408             app.killed = true;
5409         }
5410
5411         // Clean up already done if the process has been re-started.
5412         if (app.pid == pid && app.thread != null &&
5413                 app.thread.asBinder() == thread.asBinder()) {
5414             boolean doLowMem = app.instr == null;
5415             boolean doOomAdj = doLowMem;
5416             if (!app.killedByAm) {
5417                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5418                         + ProcessList.makeOomAdjString(app.setAdj)
5419                         + ProcessList.makeProcStateString(app.setProcState));
5420                 mAllowLowerMemLevel = true;
5421             } else {
5422                 // Note that we always want to do oom adj to update our state with the
5423                 // new number of procs.
5424                 mAllowLowerMemLevel = false;
5425                 doLowMem = false;
5426             }
5427             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5428                     app.setAdj, app.setProcState);
5429             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5430                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5431             handleAppDiedLocked(app, false, true);
5432
5433             if (doOomAdj) {
5434                 updateOomAdjLocked();
5435             }
5436             if (doLowMem) {
5437                 doLowMemReportIfNeededLocked(app);
5438             }
5439         } else if (app.pid != pid) {
5440             // A new process has already been started.
5441             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5442                     + ") has died and restarted (pid " + app.pid + ").");
5443             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5444         } else if (DEBUG_PROCESSES) {
5445             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5446                     + thread.asBinder());
5447         }
5448     }
5449
5450     /**
5451      * If a stack trace dump file is configured, dump process stack traces.
5452      * @param clearTraces causes the dump file to be erased prior to the new
5453      *    traces being written, if true; when false, the new traces will be
5454      *    appended to any existing file content.
5455      * @param firstPids of dalvik VM processes to dump stack traces for first
5456      * @param lastPids of dalvik VM processes to dump stack traces for last
5457      * @param nativePids optional list of native pids to dump stack crawls
5458      * @return file containing stack traces, or null if no dump file is configured
5459      */
5460     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5461             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5462             ArrayList<Integer> nativePids) {
5463         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5464         if (tracesPath == null || tracesPath.length() == 0) {
5465             return null;
5466         }
5467
5468         File tracesFile = new File(tracesPath);
5469         try {
5470             if (clearTraces && tracesFile.exists()) tracesFile.delete();
5471             tracesFile.createNewFile();
5472             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5473         } catch (IOException e) {
5474             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5475             return null;
5476         }
5477
5478         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
5479         return tracesFile;
5480     }
5481
5482     public static class DumpStackFileObserver extends FileObserver {
5483         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5484         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5485         static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
5486
5487         private final String mTracesPath;
5488         private boolean mClosed;
5489
5490         public DumpStackFileObserver(String tracesPath) {
5491             super(tracesPath, FileObserver.CLOSE_WRITE);
5492             mTracesPath = tracesPath;
5493         }
5494
5495         @Override
5496         public synchronized void onEvent(int event, String path) {
5497             mClosed = true;
5498             notify();
5499         }
5500
5501         public long dumpWithTimeout(int pid, long timeout) {
5502             sendSignal(pid, SIGNAL_QUIT);
5503             final long start = SystemClock.elapsedRealtime();
5504
5505             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5506             synchronized (this) {
5507                 try {
5508                     wait(waitTime); // Wait for traces file to be closed.
5509                 } catch (InterruptedException e) {
5510                     Slog.wtf(TAG, e);
5511                 }
5512             }
5513
5514             // This avoids a corner case of passing a negative time to the native
5515             // trace in case we've already hit the overall timeout.
5516             final long timeWaited = SystemClock.elapsedRealtime() - start;
5517             if (timeWaited >= timeout) {
5518                 return timeWaited;
5519             }
5520
5521             if (!mClosed) {
5522                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5523                        ". Attempting native stack collection.");
5524
5525                 final long nativeDumpTimeoutMs = Math.min(
5526                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5527
5528                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5529                         (int) (nativeDumpTimeoutMs / 1000));
5530             }
5531
5532             final long end = SystemClock.elapsedRealtime();
5533             mClosed = false;
5534
5535             return (end - start);
5536         }
5537     }
5538
5539     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5540             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5541             ArrayList<Integer> nativePids) {
5542         // Use a FileObserver to detect when traces finish writing.
5543         // The order of traces is considered important to maintain for legibility.
5544         DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
5545
5546         // We must complete all stack dumps within 20 seconds.
5547         long remainingTime = 20 * 1000;
5548         try {
5549             observer.startWatching();
5550
5551             // First collect all of the stacks of the most important pids.
5552             if (firstPids != null) {
5553                 int num = firstPids.size();
5554                 for (int i = 0; i < num; i++) {
5555                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5556                             + firstPids.get(i));
5557                     final long timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5558
5559                     remainingTime -= timeTaken;
5560                     if (remainingTime <= 0) {
5561                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5562                             "); deadline exceeded.");
5563                         return;
5564                     }
5565
5566                     if (DEBUG_ANR) {
5567                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5568                     }
5569                 }
5570             }
5571
5572             // Next collect the stacks of the native pids
5573             if (nativePids != null) {
5574                 for (int pid : nativePids) {
5575                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5576                     final long nativeDumpTimeoutMs = Math.min(
5577                             DumpStackFileObserver.NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5578
5579                     final long start = SystemClock.elapsedRealtime();
5580                     Debug.dumpNativeBacktraceToFileTimeout(
5581                             pid, tracesPath, (int) (nativeDumpTimeoutMs / 1000));
5582                     final long timeTaken = SystemClock.elapsedRealtime() - start;
5583
5584                     remainingTime -= timeTaken;
5585                     if (remainingTime <= 0) {
5586                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5587                             "); deadline exceeded.");
5588                         return;
5589                     }
5590
5591                     if (DEBUG_ANR) {
5592                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5593                     }
5594                 }
5595             }
5596
5597             // Lastly, measure CPU usage.
5598             if (processCpuTracker != null) {
5599                 processCpuTracker.init();
5600                 System.gc();
5601                 processCpuTracker.update();
5602                 try {
5603                     synchronized (processCpuTracker) {
5604                         processCpuTracker.wait(500); // measure over 1/2 second.
5605                     }
5606                 } catch (InterruptedException e) {
5607                 }
5608                 processCpuTracker.update();
5609
5610                 // We'll take the stack crawls of just the top apps using CPU.
5611                 final int N = processCpuTracker.countWorkingStats();
5612                 int numProcs = 0;
5613                 for (int i=0; i<N && numProcs<5; i++) {
5614                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5615                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5616                         numProcs++;
5617
5618                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5619
5620                         final long timeTaken = observer.dumpWithTimeout(stats.pid, remainingTime);
5621                         remainingTime -= timeTaken;
5622                         if (remainingTime <= 0) {
5623                             Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + stats.pid +
5624                                 "); deadline exceeded.");
5625                             return;
5626                         }
5627
5628                         if (DEBUG_ANR) {
5629                             Slog.d(TAG, "Done with extra pid " + stats.pid + " in " + timeTaken + "ms");
5630                         }
5631                     } else if (DEBUG_ANR) {
5632                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5633                                 + stats.pid);
5634                     }
5635                 }
5636             }
5637         } finally {
5638             observer.stopWatching();
5639         }
5640     }
5641
5642     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5643         if (true || IS_USER_BUILD) {
5644             return;
5645         }
5646         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5647         if (tracesPath == null || tracesPath.length() == 0) {
5648             return;
5649         }
5650
5651         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5652         StrictMode.allowThreadDiskWrites();
5653         try {
5654             final File tracesFile = new File(tracesPath);
5655             final File tracesDir = tracesFile.getParentFile();
5656             final File tracesTmp = new File(tracesDir, "__tmp__");
5657             try {
5658                 if (tracesFile.exists()) {
5659                     tracesTmp.delete();
5660                     tracesFile.renameTo(tracesTmp);
5661                 }
5662                 StringBuilder sb = new StringBuilder();
5663                 Time tobj = new Time();
5664                 tobj.set(System.currentTimeMillis());
5665                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5666                 sb.append(": ");
5667                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5668                 sb.append(" since ");
5669                 sb.append(msg);
5670                 FileOutputStream fos = new FileOutputStream(tracesFile);
5671                 fos.write(sb.toString().getBytes());
5672                 if (app == null) {
5673                     fos.write("\n*** No application process!".getBytes());
5674                 }
5675                 fos.close();
5676                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5677             } catch (IOException e) {
5678                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5679                 return;
5680             }
5681
5682             if (app != null) {
5683                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5684                 firstPids.add(app.pid);
5685                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5686             }
5687
5688             File lastTracesFile = null;
5689             File curTracesFile = null;
5690             for (int i=9; i>=0; i--) {
5691                 String name = String.format(Locale.US, "slow%02d.txt", i);
5692                 curTracesFile = new File(tracesDir, name);
5693                 if (curTracesFile.exists()) {
5694                     if (lastTracesFile != null) {
5695                         curTracesFile.renameTo(lastTracesFile);
5696                     } else {
5697                         curTracesFile.delete();
5698                     }
5699                 }
5700                 lastTracesFile = curTracesFile;
5701             }
5702             tracesFile.renameTo(curTracesFile);
5703             if (tracesTmp.exists()) {
5704                 tracesTmp.renameTo(tracesFile);
5705             }
5706         } finally {
5707             StrictMode.setThreadPolicy(oldPolicy);
5708         }
5709     }
5710
5711     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5712         if (!mLaunchWarningShown) {
5713             mLaunchWarningShown = true;
5714             mUiHandler.post(new Runnable() {
5715                 @Override
5716                 public void run() {
5717                     synchronized (ActivityManagerService.this) {
5718                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5719                         d.show();
5720                         mUiHandler.postDelayed(new Runnable() {
5721                             @Override
5722                             public void run() {
5723                                 synchronized (ActivityManagerService.this) {
5724                                     d.dismiss();
5725                                     mLaunchWarningShown = false;
5726                                 }
5727                             }
5728                         }, 4000);
5729                     }
5730                 }
5731             });
5732         }
5733     }
5734
5735     @Override
5736     public boolean clearApplicationUserData(final String packageName,
5737             final IPackageDataObserver observer, int userId) {
5738         enforceNotIsolatedCaller("clearApplicationUserData");
5739         int uid = Binder.getCallingUid();
5740         int pid = Binder.getCallingPid();
5741         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5742                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5743
5744
5745         long callingId = Binder.clearCallingIdentity();
5746         try {
5747             IPackageManager pm = AppGlobals.getPackageManager();
5748             int pkgUid = -1;
5749             synchronized(this) {
5750                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5751                         userId, packageName)) {
5752                     throw new SecurityException(
5753                             "Cannot clear data for a protected package: " + packageName);
5754                 }
5755
5756                 try {
5757                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5758                 } catch (RemoteException e) {
5759                 }
5760                 if (pkgUid == -1) {
5761                     Slog.w(TAG, "Invalid packageName: " + packageName);
5762                     if (observer != null) {
5763                         try {
5764                             observer.onRemoveCompleted(packageName, false);
5765                         } catch (RemoteException e) {
5766                             Slog.i(TAG, "Observer no longer exists.");
5767                         }
5768                     }
5769                     return false;
5770                 }
5771                 if (uid == pkgUid || checkComponentPermission(
5772                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5773                         pid, uid, -1, true)
5774                         == PackageManager.PERMISSION_GRANTED) {
5775                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5776                 } else {
5777                     throw new SecurityException("PID " + pid + " does not have permission "
5778                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5779                                     + " of package " + packageName);
5780                 }
5781
5782                 // Remove all tasks match the cleared application package and user
5783                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5784                     final TaskRecord tr = mRecentTasks.get(i);
5785                     final String taskPackageName =
5786                             tr.getBaseIntent().getComponent().getPackageName();
5787                     if (tr.userId != userId) continue;
5788                     if (!taskPackageName.equals(packageName)) continue;
5789                     mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5790                 }
5791             }
5792
5793             final int pkgUidF = pkgUid;
5794             final int userIdF = userId;
5795             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5796                 @Override
5797                 public void onRemoveCompleted(String packageName, boolean succeeded)
5798                         throws RemoteException {
5799                     synchronized (ActivityManagerService.this) {
5800                         finishForceStopPackageLocked(packageName, pkgUidF);
5801                     }
5802
5803                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5804                             Uri.fromParts("package", packageName, null));
5805                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5806                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5807                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5808                     broadcastIntentInPackage("android", SYSTEM_UID, intent,
5809                             null, null, 0, null, null, null, null, false, false, userIdF);
5810
5811                     if (observer != null) {
5812                         observer.onRemoveCompleted(packageName, succeeded);
5813                     }
5814                 }
5815             };
5816
5817             try {
5818                 // Clear application user data
5819                 pm.clearApplicationUserData(packageName, localObserver, userId);
5820
5821                 synchronized(this) {
5822                     // Remove all permissions granted from/to this package
5823                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5824                 }
5825
5826                 // Reset notification settings.
5827                 INotificationManager inm = NotificationManager.getService();
5828                 inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5829             } catch (RemoteException e) {
5830             }
5831         } finally {
5832             Binder.restoreCallingIdentity(callingId);
5833         }
5834         return true;
5835     }
5836
5837     @Override
5838     public void killBackgroundProcesses(final String packageName, int userId) {
5839         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5840                 != PackageManager.PERMISSION_GRANTED &&
5841                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5842                         != PackageManager.PERMISSION_GRANTED) {
5843             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5844                     + Binder.getCallingPid()
5845                     + ", uid=" + Binder.getCallingUid()
5846                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5847             Slog.w(TAG, msg);
5848             throw new SecurityException(msg);
5849         }
5850
5851         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5852                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5853         long callingId = Binder.clearCallingIdentity();
5854         try {
5855             IPackageManager pm = AppGlobals.getPackageManager();
5856             synchronized(this) {
5857                 int appId = -1;
5858                 try {
5859                     appId = UserHandle.getAppId(
5860                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5861                 } catch (RemoteException e) {
5862                 }
5863                 if (appId == -1) {
5864                     Slog.w(TAG, "Invalid packageName: " + packageName);
5865                     return;
5866                 }
5867                 killPackageProcessesLocked(packageName, appId, userId,
5868                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5869             }
5870         } finally {
5871             Binder.restoreCallingIdentity(callingId);
5872         }
5873     }
5874
5875     @Override
5876     public void killAllBackgroundProcesses() {
5877         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5878                 != PackageManager.PERMISSION_GRANTED) {
5879             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5880                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5881                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5882             Slog.w(TAG, msg);
5883             throw new SecurityException(msg);
5884         }
5885
5886         final long callingId = Binder.clearCallingIdentity();
5887         try {
5888             synchronized (this) {
5889                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5890                 final int NP = mProcessNames.getMap().size();
5891                 for (int ip = 0; ip < NP; ip++) {
5892                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5893                     final int NA = apps.size();
5894                     for (int ia = 0; ia < NA; ia++) {
5895                         final ProcessRecord app = apps.valueAt(ia);
5896                         if (app.persistent) {
5897                             // We don't kill persistent processes.
5898                             continue;
5899                         }
5900                         if (app.removed) {
5901                             procs.add(app);
5902                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5903                             app.removed = true;
5904                             procs.add(app);
5905                         }
5906                     }
5907                 }
5908
5909                 final int N = procs.size();
5910                 for (int i = 0; i < N; i++) {
5911                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5912                 }
5913
5914                 mAllowLowerMemLevel = true;
5915
5916                 updateOomAdjLocked();
5917                 doLowMemReportIfNeededLocked(null);
5918             }
5919         } finally {
5920             Binder.restoreCallingIdentity(callingId);
5921         }
5922     }
5923
5924     /**
5925      * Kills all background processes, except those matching any of the
5926      * specified properties.
5927      *
5928      * @param minTargetSdk the target SDK version at or above which to preserve
5929      *                     processes, or {@code -1} to ignore the target SDK
5930      * @param maxProcState the process state at or below which to preserve
5931      *                     processes, or {@code -1} to ignore the process state
5932      */
5933     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5934         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5935                 != PackageManager.PERMISSION_GRANTED) {
5936             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5937                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5938                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5939             Slog.w(TAG, msg);
5940             throw new SecurityException(msg);
5941         }
5942
5943         final long callingId = Binder.clearCallingIdentity();
5944         try {
5945             synchronized (this) {
5946                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5947                 final int NP = mProcessNames.getMap().size();
5948                 for (int ip = 0; ip < NP; ip++) {
5949                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5950                     final int NA = apps.size();
5951                     for (int ia = 0; ia < NA; ia++) {
5952                         final ProcessRecord app = apps.valueAt(ia);
5953                         if (app.removed) {
5954                             procs.add(app);
5955                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5956                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5957                             app.removed = true;
5958                             procs.add(app);
5959                         }
5960                     }
5961                 }
5962
5963                 final int N = procs.size();
5964                 for (int i = 0; i < N; i++) {
5965                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
5966                 }
5967             }
5968         } finally {
5969             Binder.restoreCallingIdentity(callingId);
5970         }
5971     }
5972
5973     @Override
5974     public void forceStopPackage(final String packageName, int userId) {
5975         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5976                 != PackageManager.PERMISSION_GRANTED) {
5977             String msg = "Permission Denial: forceStopPackage() from pid="
5978                     + Binder.getCallingPid()
5979                     + ", uid=" + Binder.getCallingUid()
5980                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5981             Slog.w(TAG, msg);
5982             throw new SecurityException(msg);
5983         }
5984         final int callingPid = Binder.getCallingPid();
5985         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5986                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5987         long callingId = Binder.clearCallingIdentity();
5988         try {
5989             IPackageManager pm = AppGlobals.getPackageManager();
5990             synchronized(this) {
5991                 int[] users = userId == UserHandle.USER_ALL
5992                         ? mUserController.getUsers() : new int[] { userId };
5993                 for (int user : users) {
5994                     int pkgUid = -1;
5995                     try {
5996                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5997                                 user);
5998                     } catch (RemoteException e) {
5999                     }
6000                     if (pkgUid == -1) {
6001                         Slog.w(TAG, "Invalid packageName: " + packageName);
6002                         continue;
6003                     }
6004                     try {
6005                         pm.setPackageStoppedState(packageName, true, user);
6006                     } catch (RemoteException e) {
6007                     } catch (IllegalArgumentException e) {
6008                         Slog.w(TAG, "Failed trying to unstop package "
6009                                 + packageName + ": " + e);
6010                     }
6011                     if (mUserController.isUserRunningLocked(user, 0)) {
6012                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6013                         finishForceStopPackageLocked(packageName, pkgUid);
6014                     }
6015                 }
6016             }
6017         } finally {
6018             Binder.restoreCallingIdentity(callingId);
6019         }
6020     }
6021
6022     @Override
6023     public void addPackageDependency(String packageName) {
6024         synchronized (this) {
6025             int callingPid = Binder.getCallingPid();
6026             if (callingPid == myPid()) {
6027                 //  Yeah, um, no.
6028                 return;
6029             }
6030             ProcessRecord proc;
6031             synchronized (mPidsSelfLocked) {
6032                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6033             }
6034             if (proc != null) {
6035                 if (proc.pkgDeps == null) {
6036                     proc.pkgDeps = new ArraySet<String>(1);
6037                 }
6038                 proc.pkgDeps.add(packageName);
6039             }
6040         }
6041     }
6042
6043     /*
6044      * The pkg name and app id have to be specified.
6045      */
6046     @Override
6047     public void killApplication(String pkg, int appId, int userId, String reason) {
6048         if (pkg == null) {
6049             return;
6050         }
6051         // Make sure the uid is valid.
6052         if (appId < 0) {
6053             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6054             return;
6055         }
6056         int callerUid = Binder.getCallingUid();
6057         // Only the system server can kill an application
6058         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6059             // Post an aysnc message to kill the application
6060             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6061             msg.arg1 = appId;
6062             msg.arg2 = userId;
6063             Bundle bundle = new Bundle();
6064             bundle.putString("pkg", pkg);
6065             bundle.putString("reason", reason);
6066             msg.obj = bundle;
6067             mHandler.sendMessage(msg);
6068         } else {
6069             throw new SecurityException(callerUid + " cannot kill pkg: " +
6070                     pkg);
6071         }
6072     }
6073
6074     @Override
6075     public void closeSystemDialogs(String reason) {
6076         enforceNotIsolatedCaller("closeSystemDialogs");
6077
6078         final int pid = Binder.getCallingPid();
6079         final int uid = Binder.getCallingUid();
6080         final long origId = Binder.clearCallingIdentity();
6081         try {
6082             synchronized (this) {
6083                 // Only allow this from foreground processes, so that background
6084                 // applications can't abuse it to prevent system UI from being shown.
6085                 if (uid >= FIRST_APPLICATION_UID) {
6086                     ProcessRecord proc;
6087                     synchronized (mPidsSelfLocked) {
6088                         proc = mPidsSelfLocked.get(pid);
6089                     }
6090                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6091                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6092                                 + " from background process " + proc);
6093                         return;
6094                     }
6095                 }
6096                 closeSystemDialogsLocked(reason);
6097             }
6098         } finally {
6099             Binder.restoreCallingIdentity(origId);
6100         }
6101     }
6102
6103     void closeSystemDialogsLocked(String reason) {
6104         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6105         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6106                 | Intent.FLAG_RECEIVER_FOREGROUND);
6107         if (reason != null) {
6108             intent.putExtra("reason", reason);
6109         }
6110         mWindowManager.closeSystemDialogs(reason);
6111
6112         mStackSupervisor.closeSystemDialogsLocked();
6113
6114         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6115                 AppOpsManager.OP_NONE, null, false, false,
6116                 -1, SYSTEM_UID, UserHandle.USER_ALL);
6117     }
6118
6119     @Override
6120     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6121         enforceNotIsolatedCaller("getProcessMemoryInfo");
6122         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6123         for (int i=pids.length-1; i>=0; i--) {
6124             ProcessRecord proc;
6125             int oomAdj;
6126             synchronized (this) {
6127                 synchronized (mPidsSelfLocked) {
6128                     proc = mPidsSelfLocked.get(pids[i]);
6129                     oomAdj = proc != null ? proc.setAdj : 0;
6130                 }
6131             }
6132             infos[i] = new Debug.MemoryInfo();
6133             Debug.getMemoryInfo(pids[i], infos[i]);
6134             if (proc != null) {
6135                 synchronized (this) {
6136                     if (proc.thread != null && proc.setAdj == oomAdj) {
6137                         // Record this for posterity if the process has been stable.
6138                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6139                                 infos[i].getTotalUss(), false, proc.pkgList);
6140                     }
6141                 }
6142             }
6143         }
6144         return infos;
6145     }
6146
6147     @Override
6148     public long[] getProcessPss(int[] pids) {
6149         enforceNotIsolatedCaller("getProcessPss");
6150         long[] pss = new long[pids.length];
6151         for (int i=pids.length-1; i>=0; i--) {
6152             ProcessRecord proc;
6153             int oomAdj;
6154             synchronized (this) {
6155                 synchronized (mPidsSelfLocked) {
6156                     proc = mPidsSelfLocked.get(pids[i]);
6157                     oomAdj = proc != null ? proc.setAdj : 0;
6158                 }
6159             }
6160             long[] tmpUss = new long[1];
6161             pss[i] = Debug.getPss(pids[i], tmpUss, null);
6162             if (proc != null) {
6163                 synchronized (this) {
6164                     if (proc.thread != null && proc.setAdj == oomAdj) {
6165                         // Record this for posterity if the process has been stable.
6166                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6167                     }
6168                 }
6169             }
6170         }
6171         return pss;
6172     }
6173
6174     @Override
6175     public void killApplicationProcess(String processName, int uid) {
6176         if (processName == null) {
6177             return;
6178         }
6179
6180         int callerUid = Binder.getCallingUid();
6181         // Only the system server can kill an application
6182         if (callerUid == SYSTEM_UID) {
6183             synchronized (this) {
6184                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6185                 if (app != null && app.thread != null) {
6186                     try {
6187                         app.thread.scheduleSuicide();
6188                     } catch (RemoteException e) {
6189                         // If the other end already died, then our work here is done.
6190                     }
6191                 } else {
6192                     Slog.w(TAG, "Process/uid not found attempting kill of "
6193                             + processName + " / " + uid);
6194                 }
6195             }
6196         } else {
6197             throw new SecurityException(callerUid + " cannot kill app process: " +
6198                     processName);
6199         }
6200     }
6201
6202     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6203         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6204                 false, true, false, false, UserHandle.getUserId(uid), reason);
6205     }
6206
6207     private void finishForceStopPackageLocked(final String packageName, int uid) {
6208         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6209                 Uri.fromParts("package", packageName, null));
6210         if (!mProcessesReady) {
6211             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6212                     | Intent.FLAG_RECEIVER_FOREGROUND);
6213         }
6214         intent.putExtra(Intent.EXTRA_UID, uid);
6215         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6216         broadcastIntentLocked(null, null, intent,
6217                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6218                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6219     }
6220
6221
6222     private final boolean killPackageProcessesLocked(String packageName, int appId,
6223             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6224             boolean doit, boolean evenPersistent, String reason) {
6225         ArrayList<ProcessRecord> procs = new ArrayList<>();
6226
6227         // Remove all processes this package may have touched: all with the
6228         // same UID (except for the system or root user), and all whose name
6229         // matches the package name.
6230         final int NP = mProcessNames.getMap().size();
6231         for (int ip=0; ip<NP; ip++) {
6232             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6233             final int NA = apps.size();
6234             for (int ia=0; ia<NA; ia++) {
6235                 ProcessRecord app = apps.valueAt(ia);
6236                 if (app.persistent && !evenPersistent) {
6237                     // we don't kill persistent processes
6238                     continue;
6239                 }
6240                 if (app.removed) {
6241                     if (doit) {
6242                         procs.add(app);
6243                     }
6244                     continue;
6245                 }
6246
6247                 // Skip process if it doesn't meet our oom adj requirement.
6248                 if (app.setAdj < minOomAdj) {
6249                     continue;
6250                 }
6251
6252                 // If no package is specified, we call all processes under the
6253                 // give user id.
6254                 if (packageName == null) {
6255                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6256                         continue;
6257                     }
6258                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6259                         continue;
6260                     }
6261                 // Package has been specified, we want to hit all processes
6262                 // that match it.  We need to qualify this by the processes
6263                 // that are running under the specified app and user ID.
6264                 } else {
6265                     final boolean isDep = app.pkgDeps != null
6266                             && app.pkgDeps.contains(packageName);
6267                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6268                         continue;
6269                     }
6270                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6271                         continue;
6272                     }
6273                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6274                         continue;
6275                     }
6276                 }
6277
6278                 // Process has passed all conditions, kill it!
6279                 if (!doit) {
6280                     return true;
6281                 }
6282                 app.removed = true;
6283                 procs.add(app);
6284             }
6285         }
6286
6287         int N = procs.size();
6288         for (int i=0; i<N; i++) {
6289             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6290         }
6291         updateOomAdjLocked();
6292         return N > 0;
6293     }
6294
6295     private void cleanupDisabledPackageComponentsLocked(
6296             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6297
6298         Set<String> disabledClasses = null;
6299         boolean packageDisabled = false;
6300         IPackageManager pm = AppGlobals.getPackageManager();
6301
6302         if (changedClasses == null) {
6303             // Nothing changed...
6304             return;
6305         }
6306
6307         // Determine enable/disable state of the package and its components.
6308         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6309         for (int i = changedClasses.length - 1; i >= 0; i--) {
6310             final String changedClass = changedClasses[i];
6311
6312             if (changedClass.equals(packageName)) {
6313                 try {
6314                     // Entire package setting changed
6315                     enabled = pm.getApplicationEnabledSetting(packageName,
6316                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6317                 } catch (Exception e) {
6318                     // No such package/component; probably racing with uninstall.  In any
6319                     // event it means we have nothing further to do here.
6320                     return;
6321                 }
6322                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6323                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6324                 if (packageDisabled) {
6325                     // Entire package is disabled.
6326                     // No need to continue to check component states.
6327                     disabledClasses = null;
6328                     break;
6329                 }
6330             } else {
6331                 try {
6332                     enabled = pm.getComponentEnabledSetting(
6333                             new ComponentName(packageName, changedClass),
6334                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6335                 } catch (Exception e) {
6336                     // As above, probably racing with uninstall.
6337                     return;
6338                 }
6339                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6340                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6341                     if (disabledClasses == null) {
6342                         disabledClasses = new ArraySet<>(changedClasses.length);
6343                     }
6344                     disabledClasses.add(changedClass);
6345                 }
6346             }
6347         }
6348
6349         if (!packageDisabled && disabledClasses == null) {
6350             // Nothing to do here...
6351             return;
6352         }
6353
6354         // Clean-up disabled activities.
6355         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6356                 packageName, disabledClasses, true, false, userId) && mBooted) {
6357             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6358             mStackSupervisor.scheduleIdleLocked();
6359         }
6360
6361         // Clean-up disabled tasks
6362         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6363
6364         // Clean-up disabled services.
6365         mServices.bringDownDisabledPackageServicesLocked(
6366                 packageName, disabledClasses, userId, false, killProcess, true);
6367
6368         // Clean-up disabled providers.
6369         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6370         mProviderMap.collectPackageProvidersLocked(
6371                 packageName, disabledClasses, true, false, userId, providers);
6372         for (int i = providers.size() - 1; i >= 0; i--) {
6373             removeDyingProviderLocked(null, providers.get(i), true);
6374         }
6375
6376         // Clean-up disabled broadcast receivers.
6377         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6378             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6379                     packageName, disabledClasses, userId, true);
6380         }
6381
6382     }
6383
6384     final boolean clearBroadcastQueueForUserLocked(int userId) {
6385         boolean didSomething = false;
6386         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6387             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6388                     null, null, userId, true);
6389         }
6390         return didSomething;
6391     }
6392
6393     final boolean forceStopPackageLocked(String packageName, int appId,
6394             boolean callerWillRestart, boolean purgeCache, boolean doit,
6395             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6396         int i;
6397
6398         if (userId == UserHandle.USER_ALL && packageName == null) {
6399             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6400         }
6401
6402         if (appId < 0 && packageName != null) {
6403             try {
6404                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6405                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6406             } catch (RemoteException e) {
6407             }
6408         }
6409
6410         if (doit) {
6411             if (packageName != null) {
6412                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6413                         + " user=" + userId + ": " + reason);
6414             } else {
6415                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6416             }
6417
6418             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6419         }
6420
6421         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6422                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6423                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6424
6425         didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6426
6427         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6428                 packageName, null, doit, evenPersistent, userId)) {
6429             if (!doit) {
6430                 return true;
6431             }
6432             didSomething = true;
6433         }
6434
6435         if (mServices.bringDownDisabledPackageServicesLocked(
6436                 packageName, null, userId, evenPersistent, true, doit)) {
6437             if (!doit) {
6438                 return true;
6439             }
6440             didSomething = true;
6441         }
6442
6443         if (packageName == null) {
6444             // Remove all sticky broadcasts from this user.
6445             mStickyBroadcasts.remove(userId);
6446         }
6447
6448         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6449         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6450                 userId, providers)) {
6451             if (!doit) {
6452                 return true;
6453             }
6454             didSomething = true;
6455         }
6456         for (i = providers.size() - 1; i >= 0; i--) {
6457             removeDyingProviderLocked(null, providers.get(i), true);
6458         }
6459
6460         // Remove transient permissions granted from/to this package/user
6461         removeUriPermissionsForPackageLocked(packageName, userId, false);
6462
6463         if (doit) {
6464             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6465                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6466                         packageName, null, userId, doit);
6467             }
6468         }
6469
6470         if (packageName == null || uninstalling) {
6471             // Remove pending intents.  For now we only do this when force
6472             // stopping users, because we have some problems when doing this
6473             // for packages -- app widgets are not currently cleaned up for
6474             // such packages, so they can be left with bad pending intents.
6475             if (mIntentSenderRecords.size() > 0) {
6476                 Iterator<WeakReference<PendingIntentRecord>> it
6477                         = mIntentSenderRecords.values().iterator();
6478                 while (it.hasNext()) {
6479                     WeakReference<PendingIntentRecord> wpir = it.next();
6480                     if (wpir == null) {
6481                         it.remove();
6482                         continue;
6483                     }
6484                     PendingIntentRecord pir = wpir.get();
6485                     if (pir == null) {
6486                         it.remove();
6487                         continue;
6488                     }
6489                     if (packageName == null) {
6490                         // Stopping user, remove all objects for the user.
6491                         if (pir.key.userId != userId) {
6492                             // Not the same user, skip it.
6493                             continue;
6494                         }
6495                     } else {
6496                         if (UserHandle.getAppId(pir.uid) != appId) {
6497                             // Different app id, skip it.
6498                             continue;
6499                         }
6500                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6501                             // Different user, skip it.
6502                             continue;
6503                         }
6504                         if (!pir.key.packageName.equals(packageName)) {
6505                             // Different package, skip it.
6506                             continue;
6507                         }
6508                     }
6509                     if (!doit) {
6510                         return true;
6511                     }
6512                     didSomething = true;
6513                     it.remove();
6514                     makeIntentSenderCanceledLocked(pir);
6515                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6516                         pir.key.activity.pendingResults.remove(pir.ref);
6517                     }
6518                 }
6519             }
6520         }
6521
6522         if (doit) {
6523             if (purgeCache && packageName != null) {
6524                 AttributeCache ac = AttributeCache.instance();
6525                 if (ac != null) {
6526                     ac.removePackage(packageName);
6527                 }
6528             }
6529             if (mBooted) {
6530                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6531                 mStackSupervisor.scheduleIdleLocked();
6532             }
6533         }
6534
6535         return didSomething;
6536     }
6537
6538     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6539         return removeProcessNameLocked(name, uid, null);
6540     }
6541
6542     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6543             final ProcessRecord expecting) {
6544         ProcessRecord old = mProcessNames.get(name, uid);
6545         // Only actually remove when the currently recorded value matches the
6546         // record that we expected; if it doesn't match then we raced with a
6547         // newly created process and we don't want to destroy the new one.
6548         if ((expecting == null) || (old == expecting)) {
6549             mProcessNames.remove(name, uid);
6550         }
6551         if (old != null && old.uidRecord != null) {
6552             old.uidRecord.numProcs--;
6553             if (old.uidRecord.numProcs == 0) {
6554                 // No more processes using this uid, tell clients it is gone.
6555                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6556                         "No more processes in " + old.uidRecord);
6557                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6558                 EventLogTags.writeAmUidStopped(uid);
6559                 mActiveUids.remove(uid);
6560                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6561             }
6562             old.uidRecord = null;
6563         }
6564         mIsolatedProcesses.remove(uid);
6565         return old;
6566     }
6567
6568     private final void addProcessNameLocked(ProcessRecord proc) {
6569         // We shouldn't already have a process under this name, but just in case we
6570         // need to clean up whatever may be there now.
6571         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6572         if (old == proc && proc.persistent) {
6573             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6574             Slog.w(TAG, "Re-adding persistent process " + proc);
6575         } else if (old != null) {
6576             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6577         }
6578         UidRecord uidRec = mActiveUids.get(proc.uid);
6579         if (uidRec == null) {
6580             uidRec = new UidRecord(proc.uid);
6581             // This is the first appearance of the uid, report it now!
6582             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6583                     "Creating new process uid: " + uidRec);
6584             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6585                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6586                 uidRec.setWhitelist = uidRec.curWhitelist = true;
6587             }
6588             uidRec.updateHasInternetPermission();
6589             mActiveUids.put(proc.uid, uidRec);
6590             EventLogTags.writeAmUidRunning(uidRec.uid);
6591             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6592             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6593         }
6594         proc.uidRecord = uidRec;
6595
6596         // Reset render thread tid if it was already set, so new process can set it again.
6597         proc.renderThreadTid = 0;
6598         uidRec.numProcs++;
6599         mProcessNames.put(proc.processName, proc.uid, proc);
6600         if (proc.isolated) {
6601             mIsolatedProcesses.put(proc.uid, proc);
6602         }
6603     }
6604
6605     boolean removeProcessLocked(ProcessRecord app,
6606             boolean callerWillRestart, boolean allowRestart, String reason) {
6607         final String name = app.processName;
6608         final int uid = app.uid;
6609         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6610             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6611
6612         ProcessRecord old = mProcessNames.get(name, uid);
6613         if (old != app) {
6614             // This process is no longer active, so nothing to do.
6615             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6616             return false;
6617         }
6618         removeProcessNameLocked(name, uid);
6619         if (mHeavyWeightProcess == app) {
6620             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6621                     mHeavyWeightProcess.userId, 0));
6622             mHeavyWeightProcess = null;
6623         }
6624         boolean needRestart = false;
6625         if (app.pid > 0 && app.pid != MY_PID) {
6626             int pid = app.pid;
6627             synchronized (mPidsSelfLocked) {
6628                 mPidsSelfLocked.remove(pid);
6629                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6630             }
6631             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6632             if (app.isolated) {
6633                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6634                 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6635             }
6636             boolean willRestart = false;
6637             if (app.persistent && !app.isolated) {
6638                 if (!callerWillRestart) {
6639                     willRestart = true;
6640                 } else {
6641                     needRestart = true;
6642                 }
6643             }
6644             app.kill(reason, true);
6645             handleAppDiedLocked(app, willRestart, allowRestart);
6646             if (willRestart) {
6647                 removeLruProcessLocked(app);
6648                 addAppLocked(app.info, null, false, null /* ABI override */);
6649             }
6650         } else {
6651             mRemovedProcesses.add(app);
6652         }
6653
6654         return needRestart;
6655     }
6656
6657     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6658         cleanupAppInLaunchingProvidersLocked(app, true);
6659         removeProcessLocked(app, false, true, "timeout publishing content providers");
6660     }
6661
6662     private final void processStartTimedOutLocked(ProcessRecord app) {
6663         final int pid = app.pid;
6664         boolean gone = false;
6665         synchronized (mPidsSelfLocked) {
6666             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6667             if (knownApp != null && knownApp.thread == null) {
6668                 mPidsSelfLocked.remove(pid);
6669                 gone = true;
6670             }
6671         }
6672
6673         if (gone) {
6674             Slog.w(TAG, "Process " + app + " failed to attach");
6675             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6676                     pid, app.uid, app.processName);
6677             removeProcessNameLocked(app.processName, app.uid);
6678             if (mHeavyWeightProcess == app) {
6679                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6680                         mHeavyWeightProcess.userId, 0));
6681                 mHeavyWeightProcess = null;
6682             }
6683             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6684             if (app.isolated) {
6685                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6686             }
6687             // Take care of any launching providers waiting for this process.
6688             cleanupAppInLaunchingProvidersLocked(app, true);
6689             // Take care of any services that are waiting for the process.
6690             mServices.processStartTimedOutLocked(app);
6691             app.kill("start timeout", true);
6692             removeLruProcessLocked(app);
6693             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6694                 Slog.w(TAG, "Unattached app died before backup, skipping");
6695                 mHandler.post(new Runnable() {
6696                 @Override
6697                     public void run(){
6698                         try {
6699                             IBackupManager bm = IBackupManager.Stub.asInterface(
6700                                     ServiceManager.getService(Context.BACKUP_SERVICE));
6701                             bm.agentDisconnected(app.info.packageName);
6702                         } catch (RemoteException e) {
6703                             // Can't happen; the backup manager is local
6704                         }
6705                     }
6706                 });
6707             }
6708             if (isPendingBroadcastProcessLocked(pid)) {
6709                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6710                 skipPendingBroadcastLocked(pid);
6711             }
6712         } else {
6713             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6714         }
6715     }
6716
6717     private final boolean attachApplicationLocked(IApplicationThread thread,
6718             int pid) {
6719
6720         // Find the application record that is being attached...  either via
6721         // the pid if we are running in multiple processes, or just pull the
6722         // next app record if we are emulating process with anonymous threads.
6723         ProcessRecord app;
6724         long startTime = SystemClock.uptimeMillis();
6725         if (pid != MY_PID && pid >= 0) {
6726             synchronized (mPidsSelfLocked) {
6727                 app = mPidsSelfLocked.get(pid);
6728             }
6729         } else {
6730             app = null;
6731         }
6732
6733         if (app == null) {
6734             Slog.w(TAG, "No pending application record for pid " + pid
6735                     + " (IApplicationThread " + thread + "); dropping process");
6736             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6737             if (pid > 0 && pid != MY_PID) {
6738                 killProcessQuiet(pid);
6739                 //TODO: killProcessGroup(app.info.uid, pid);
6740             } else {
6741                 try {
6742                     thread.scheduleExit();
6743                 } catch (Exception e) {
6744                     // Ignore exceptions.
6745                 }
6746             }
6747             return false;
6748         }
6749
6750         // If this application record is still attached to a previous
6751         // process, clean it up now.
6752         if (app.thread != null) {
6753             handleAppDiedLocked(app, true, true);
6754         }
6755
6756         // Tell the process all about itself.
6757
6758         if (DEBUG_ALL) Slog.v(
6759                 TAG, "Binding process pid " + pid + " to record " + app);
6760
6761         final String processName = app.processName;
6762         try {
6763             AppDeathRecipient adr = new AppDeathRecipient(
6764                     app, pid, thread);
6765             thread.asBinder().linkToDeath(adr, 0);
6766             app.deathRecipient = adr;
6767         } catch (RemoteException e) {
6768             app.resetPackageList(mProcessStats);
6769             startProcessLocked(app, "link fail", processName);
6770             return false;
6771         }
6772
6773         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6774
6775         app.makeActive(thread, mProcessStats);
6776         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6777         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6778         app.forcingToImportant = null;
6779         updateProcessForegroundLocked(app, false, false);
6780         app.hasShownUi = false;
6781         app.debugging = false;
6782         app.cached = false;
6783         app.killedByAm = false;
6784         app.killed = false;
6785
6786
6787         // We carefully use the same state that PackageManager uses for
6788         // filtering, since we use this flag to decide if we need to install
6789         // providers when user is unlocked later
6790         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6791
6792         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6793
6794         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6795         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6796
6797         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6798             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6799             msg.obj = app;
6800             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6801         }
6802
6803         checkTime(startTime, "attachApplicationLocked: before bindApplication");
6804
6805         if (!normalMode) {
6806             Slog.i(TAG, "Launching preboot mode app: " + app);
6807         }
6808
6809         if (DEBUG_ALL) Slog.v(
6810             TAG, "New app record " + app
6811             + " thread=" + thread.asBinder() + " pid=" + pid);
6812         try {
6813             int testMode = ApplicationThreadConstants.DEBUG_OFF;
6814             if (mDebugApp != null && mDebugApp.equals(processName)) {
6815                 testMode = mWaitForDebugger
6816                     ? ApplicationThreadConstants.DEBUG_WAIT
6817                     : ApplicationThreadConstants.DEBUG_ON;
6818                 app.debugging = true;
6819                 if (mDebugTransient) {
6820                     mDebugApp = mOrigDebugApp;
6821                     mWaitForDebugger = mOrigWaitForDebugger;
6822                 }
6823             }
6824             String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6825             ParcelFileDescriptor profileFd = null;
6826             int samplingInterval = 0;
6827             boolean profileAutoStop = false;
6828             boolean profileStreamingOutput = false;
6829             if (mProfileApp != null && mProfileApp.equals(processName)) {
6830                 mProfileProc = app;
6831                 profileFile = mProfileFile;
6832                 profileFd = mProfileFd;
6833                 samplingInterval = mSamplingInterval;
6834                 profileAutoStop = mAutoStopProfiler;
6835                 profileStreamingOutput = mStreamingOutput;
6836             }
6837             boolean enableTrackAllocation = false;
6838             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6839                 enableTrackAllocation = true;
6840                 mTrackAllocationApp = null;
6841             }
6842
6843             // If the app is being launched for restore or full backup, set it up specially
6844             boolean isRestrictedBackupMode = false;
6845             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6846                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6847                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6848                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6849                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6850             }
6851
6852             if (app.instr != null) {
6853                 notifyPackageUse(app.instr.mClass.getPackageName(),
6854                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6855             }
6856             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6857                     + processName + " with config " + getGlobalConfiguration());
6858             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6859             app.compat = compatibilityInfoForPackageLocked(appInfo);
6860             if (profileFd != null) {
6861                 profileFd = profileFd.dup();
6862             }
6863             ProfilerInfo profilerInfo = profileFile == null ? null
6864                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6865                                        profileStreamingOutput);
6866
6867             // We deprecated Build.SERIAL and it is not accessible to
6868             // apps that target the v2 security sandbox. Since access to
6869             // the serial is now behind a permission we push down the value.
6870             String buildSerial = Build.UNKNOWN;
6871             if (appInfo.targetSandboxVersion != 2) {
6872                 buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6873                         ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6874                         .getSerial();
6875             }
6876
6877             // Check if this is a secondary process that should be incorporated into some
6878             // currently active instrumentation.  (Note we do this AFTER all of the profiling
6879             // stuff above because profiling can currently happen only in the primary
6880             // instrumentation process.)
6881             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6882                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6883                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6884                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6885                         if (aInstr.mTargetProcesses.length == 0) {
6886                             // This is the wildcard mode, where every process brought up for
6887                             // the target instrumentation should be included.
6888                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6889                                 app.instr = aInstr;
6890                                 aInstr.mRunningProcesses.add(app);
6891                             }
6892                         } else {
6893                             for (String proc : aInstr.mTargetProcesses) {
6894                                 if (proc.equals(app.processName)) {
6895                                     app.instr = aInstr;
6896                                     aInstr.mRunningProcesses.add(app);
6897                                     break;
6898                                 }
6899                             }
6900                         }
6901                     }
6902                 }
6903             }
6904
6905             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6906             mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
6907             if (app.instr != null) {
6908                 thread.bindApplication(processName, appInfo, providers,
6909                         app.instr.mClass,
6910                         profilerInfo, app.instr.mArguments,
6911                         app.instr.mWatcher,
6912                         app.instr.mUiAutomationConnection, testMode,
6913                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
6914                         isRestrictedBackupMode || !normalMode, app.persistent,
6915                         new Configuration(getGlobalConfiguration()), app.compat,
6916                         getCommonServicesLocked(app.isolated),
6917                         mCoreSettingsObserver.getCoreSettingsLocked(),
6918                         buildSerial);
6919             } else {
6920                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6921                         null, null, null, testMode,
6922                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
6923                         isRestrictedBackupMode || !normalMode, app.persistent,
6924                         new Configuration(getGlobalConfiguration()), app.compat,
6925                         getCommonServicesLocked(app.isolated),
6926                         mCoreSettingsObserver.getCoreSettingsLocked(),
6927                         buildSerial);
6928             }
6929
6930             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6931             updateLruProcessLocked(app, false, null);
6932             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6933             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6934         } catch (Exception e) {
6935             // todo: Yikes!  What should we do?  For now we will try to
6936             // start another process, but that could easily get us in
6937             // an infinite loop of restarting processes...
6938             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6939
6940             app.resetPackageList(mProcessStats);
6941             app.unlinkDeathRecipient();
6942             startProcessLocked(app, "bind fail", processName);
6943             return false;
6944         }
6945
6946         // Remove this record from the list of starting applications.
6947         mPersistentStartingProcesses.remove(app);
6948         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6949                 "Attach application locked removing on hold: " + app);
6950         mProcessesOnHold.remove(app);
6951
6952         boolean badApp = false;
6953         boolean didSomething = false;
6954
6955         // See if the top visible activity is waiting to run in this process...
6956         if (normalMode) {
6957             try {
6958                 if (mStackSupervisor.attachApplicationLocked(app)) {
6959                     didSomething = true;
6960                 }
6961             } catch (Exception e) {
6962                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6963                 badApp = true;
6964             }
6965         }
6966
6967         // Find any services that should be running in this process...
6968         if (!badApp) {
6969             try {
6970                 didSomething |= mServices.attachApplicationLocked(app, processName);
6971                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6972             } catch (Exception e) {
6973                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6974                 badApp = true;
6975             }
6976         }
6977
6978         // Check if a next-broadcast receiver is in this process...
6979         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6980             try {
6981                 didSomething |= sendPendingBroadcastsLocked(app);
6982                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6983             } catch (Exception e) {
6984                 // If the app died trying to launch the receiver we declare it 'bad'
6985                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6986                 badApp = true;
6987             }
6988         }
6989
6990         // Check whether the next backup agent is in this process...
6991         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
6992             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6993                     "New app is backup target, launching agent for " + app);
6994             notifyPackageUse(mBackupTarget.appInfo.packageName,
6995                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6996             try {
6997                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6998                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6999                         mBackupTarget.backupMode);
7000             } catch (Exception e) {
7001                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7002                 badApp = true;
7003             }
7004         }
7005
7006         if (badApp) {
7007             app.kill("error during init", true);
7008             handleAppDiedLocked(app, false, true);
7009             return false;
7010         }
7011
7012         if (!didSomething) {
7013             updateOomAdjLocked();
7014             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7015         }
7016
7017         return true;
7018     }
7019
7020     @Override
7021     public final void attachApplication(IApplicationThread thread) {
7022         synchronized (this) {
7023             int callingPid = Binder.getCallingPid();
7024             final long origId = Binder.clearCallingIdentity();
7025             attachApplicationLocked(thread, callingPid);
7026             Binder.restoreCallingIdentity(origId);
7027         }
7028     }
7029
7030     @Override
7031     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7032         final long origId = Binder.clearCallingIdentity();
7033         synchronized (this) {
7034             ActivityStack stack = ActivityRecord.getStackLocked(token);
7035             if (stack != null) {
7036                 ActivityRecord r =
7037                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7038                                 false /* processPausingActivities */, config);
7039                 if (stopProfiling) {
7040                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
7041                         try {
7042                             mProfileFd.close();
7043                         } catch (IOException e) {
7044                         }
7045                         clearProfilerLocked();
7046                     }
7047                 }
7048             }
7049         }
7050         Binder.restoreCallingIdentity(origId);
7051     }
7052
7053     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7054         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7055                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7056     }
7057
7058     void enableScreenAfterBoot() {
7059         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7060                 SystemClock.uptimeMillis());
7061         mWindowManager.enableScreenAfterBoot();
7062
7063         synchronized (this) {
7064             updateEventDispatchingLocked();
7065         }
7066     }
7067
7068     @Override
7069     public void showBootMessage(final CharSequence msg, final boolean always) {
7070         if (Binder.getCallingUid() != myUid()) {
7071             throw new SecurityException();
7072         }
7073         mWindowManager.showBootMessage(msg, always);
7074     }
7075
7076     @Override
7077     public void keyguardGoingAway(int flags) {
7078         enforceNotIsolatedCaller("keyguardGoingAway");
7079         final long token = Binder.clearCallingIdentity();
7080         try {
7081             synchronized (this) {
7082                 mKeyguardController.keyguardGoingAway(flags);
7083             }
7084         } finally {
7085             Binder.restoreCallingIdentity(token);
7086         }
7087     }
7088
7089     /**
7090      * @return whther the keyguard is currently locked.
7091      */
7092     boolean isKeyguardLocked() {
7093         return mKeyguardController.isKeyguardLocked();
7094     }
7095
7096     final void finishBooting() {
7097         synchronized (this) {
7098             if (!mBootAnimationComplete) {
7099                 mCallFinishBooting = true;
7100                 return;
7101             }
7102             mCallFinishBooting = false;
7103         }
7104
7105         ArraySet<String> completedIsas = new ArraySet<String>();
7106         for (String abi : Build.SUPPORTED_ABIS) {
7107             zygoteProcess.establishZygoteConnectionForAbi(abi);
7108             final String instructionSet = VMRuntime.getInstructionSet(abi);
7109             if (!completedIsas.contains(instructionSet)) {
7110                 try {
7111                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7112                 } catch (InstallerException e) {
7113                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7114                             e.getMessage() +")");
7115                 }
7116                 completedIsas.add(instructionSet);
7117             }
7118         }
7119
7120         IntentFilter pkgFilter = new IntentFilter();
7121         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7122         pkgFilter.addDataScheme("package");
7123         mContext.registerReceiver(new BroadcastReceiver() {
7124             @Override
7125             public void onReceive(Context context, Intent intent) {
7126                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7127                 if (pkgs != null) {
7128                     for (String pkg : pkgs) {
7129                         synchronized (ActivityManagerService.this) {
7130                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7131                                     0, "query restart")) {
7132                                 setResultCode(Activity.RESULT_OK);
7133                                 return;
7134                             }
7135                         }
7136                     }
7137                 }
7138             }
7139         }, pkgFilter);
7140
7141         IntentFilter dumpheapFilter = new IntentFilter();
7142         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7143         mContext.registerReceiver(new BroadcastReceiver() {
7144             @Override
7145             public void onReceive(Context context, Intent intent) {
7146                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7147                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7148                 } else {
7149                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7150                 }
7151             }
7152         }, dumpheapFilter);
7153
7154         // Let system services know.
7155         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7156
7157         synchronized (this) {
7158             // Ensure that any processes we had put on hold are now started
7159             // up.
7160             final int NP = mProcessesOnHold.size();
7161             if (NP > 0) {
7162                 ArrayList<ProcessRecord> procs =
7163                     new ArrayList<ProcessRecord>(mProcessesOnHold);
7164                 for (int ip=0; ip<NP; ip++) {
7165                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7166                             + procs.get(ip));
7167                     startProcessLocked(procs.get(ip), "on-hold", null);
7168                 }
7169             }
7170
7171             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7172                 // Start looking for apps that are abusing wake locks.
7173                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7174                 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
7175                 // Tell anyone interested that we are done booting!
7176                 SystemProperties.set("sys.boot_completed", "1");
7177
7178                 // And trigger dev.bootcomplete if we are not showing encryption progress
7179                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7180                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7181                     SystemProperties.set("dev.bootcomplete", "1");
7182                 }
7183                 mUserController.sendBootCompletedLocked(
7184                         new IIntentReceiver.Stub() {
7185                             @Override
7186                             public void performReceive(Intent intent, int resultCode,
7187                                     String data, Bundle extras, boolean ordered,
7188                                     boolean sticky, int sendingUser) {
7189                                 synchronized (ActivityManagerService.this) {
7190                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7191                                             true, false);
7192                                 }
7193                             }
7194                         });
7195                 scheduleStartProfilesLocked();
7196             }
7197         }
7198     }
7199
7200     @Override
7201     public void bootAnimationComplete() {
7202         final boolean callFinishBooting;
7203         synchronized (this) {
7204             callFinishBooting = mCallFinishBooting;
7205             mBootAnimationComplete = true;
7206         }
7207         if (callFinishBooting) {
7208             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7209             finishBooting();
7210             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7211         }
7212     }
7213
7214     final void ensureBootCompleted() {
7215         boolean booting;
7216         boolean enableScreen;
7217         synchronized (this) {
7218             booting = mBooting;
7219             mBooting = false;
7220             enableScreen = !mBooted;
7221             mBooted = true;
7222         }
7223
7224         if (booting) {
7225             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7226             finishBooting();
7227             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7228         }
7229
7230         if (enableScreen) {
7231             enableScreenAfterBoot();
7232         }
7233     }
7234
7235     @Override
7236     public final void activityResumed(IBinder token) {
7237         final long origId = Binder.clearCallingIdentity();
7238         synchronized(this) {
7239             ActivityRecord.activityResumedLocked(token);
7240             mWindowManager.notifyAppResumedFinished(token);
7241         }
7242         Binder.restoreCallingIdentity(origId);
7243     }
7244
7245     @Override
7246     public final void activityPaused(IBinder token) {
7247         final long origId = Binder.clearCallingIdentity();
7248         synchronized(this) {
7249             ActivityStack stack = ActivityRecord.getStackLocked(token);
7250             if (stack != null) {
7251                 stack.activityPausedLocked(token, false);
7252             }
7253         }
7254         Binder.restoreCallingIdentity(origId);
7255     }
7256
7257     @Override
7258     public final void activityStopped(IBinder token, Bundle icicle,
7259             PersistableBundle persistentState, CharSequence description) {
7260         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7261
7262         // Refuse possible leaked file descriptors
7263         if (icicle != null && icicle.hasFileDescriptors()) {
7264             throw new IllegalArgumentException("File descriptors passed in Bundle");
7265         }
7266
7267         final long origId = Binder.clearCallingIdentity();
7268
7269         synchronized (this) {
7270             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7271             if (r != null) {
7272                 r.activityStoppedLocked(icicle, persistentState, description);
7273             }
7274         }
7275
7276         trimApplications();
7277
7278         Binder.restoreCallingIdentity(origId);
7279     }
7280
7281     @Override
7282     public final void activityDestroyed(IBinder token) {
7283         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7284         synchronized (this) {
7285             ActivityStack stack = ActivityRecord.getStackLocked(token);
7286             if (stack != null) {
7287                 stack.activityDestroyedLocked(token, "activityDestroyed");
7288             }
7289         }
7290     }
7291
7292     @Override
7293     public final void activityRelaunched(IBinder token) {
7294         final long origId = Binder.clearCallingIdentity();
7295         synchronized (this) {
7296             mStackSupervisor.activityRelaunchedLocked(token);
7297         }
7298         Binder.restoreCallingIdentity(origId);
7299     }
7300
7301     @Override
7302     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7303             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7304         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7305                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7306         synchronized (this) {
7307             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7308             if (record == null) {
7309                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7310                         + "found for: " + token);
7311             }
7312             record.setSizeConfigurations(horizontalSizeConfiguration,
7313                     verticalSizeConfigurations, smallestSizeConfigurations);
7314         }
7315     }
7316
7317     @Override
7318     public final void backgroundResourcesReleased(IBinder token) {
7319         final long origId = Binder.clearCallingIdentity();
7320         try {
7321             synchronized (this) {
7322                 ActivityStack stack = ActivityRecord.getStackLocked(token);
7323                 if (stack != null) {
7324                     stack.backgroundResourcesReleased();
7325                 }
7326             }
7327         } finally {
7328             Binder.restoreCallingIdentity(origId);
7329         }
7330     }
7331
7332     @Override
7333     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7334         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7335     }
7336
7337     @Override
7338     public final void notifyEnterAnimationComplete(IBinder token) {
7339         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7340     }
7341
7342     @Override
7343     public String getCallingPackage(IBinder token) {
7344         synchronized (this) {
7345             ActivityRecord r = getCallingRecordLocked(token);
7346             return r != null ? r.info.packageName : null;
7347         }
7348     }
7349
7350     @Override
7351     public ComponentName getCallingActivity(IBinder token) {
7352         synchronized (this) {
7353             ActivityRecord r = getCallingRecordLocked(token);
7354             return r != null ? r.intent.getComponent() : null;
7355         }
7356     }
7357
7358     private ActivityRecord getCallingRecordLocked(IBinder token) {
7359         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7360         if (r == null) {
7361             return null;
7362         }
7363         return r.resultTo;
7364     }
7365
7366     @Override
7367     public ComponentName getActivityClassForToken(IBinder token) {
7368         synchronized(this) {
7369             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7370             if (r == null) {
7371                 return null;
7372             }
7373             return r.intent.getComponent();
7374         }
7375     }
7376
7377     @Override
7378     public String getPackageForToken(IBinder token) {
7379         synchronized(this) {
7380             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7381             if (r == null) {
7382                 return null;
7383             }
7384             return r.packageName;
7385         }
7386     }
7387
7388     @Override
7389     public boolean isRootVoiceInteraction(IBinder token) {
7390         synchronized(this) {
7391             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7392             if (r == null) {
7393                 return false;
7394             }
7395             return r.rootVoiceInteraction;
7396         }
7397     }
7398
7399     @Override
7400     public IIntentSender getIntentSender(int type,
7401             String packageName, IBinder token, String resultWho,
7402             int requestCode, Intent[] intents, String[] resolvedTypes,
7403             int flags, Bundle bOptions, int userId) {
7404         enforceNotIsolatedCaller("getIntentSender");
7405         // Refuse possible leaked file descriptors
7406         if (intents != null) {
7407             if (intents.length < 1) {
7408                 throw new IllegalArgumentException("Intents array length must be >= 1");
7409             }
7410             for (int i=0; i<intents.length; i++) {
7411                 Intent intent = intents[i];
7412                 if (intent != null) {
7413                     if (intent.hasFileDescriptors()) {
7414                         throw new IllegalArgumentException("File descriptors passed in Intent");
7415                     }
7416                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7417                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7418                         throw new IllegalArgumentException(
7419                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7420                     }
7421                     intents[i] = new Intent(intent);
7422                 }
7423             }
7424             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7425                 throw new IllegalArgumentException(
7426                         "Intent array length does not match resolvedTypes length");
7427             }
7428         }
7429         if (bOptions != null) {
7430             if (bOptions.hasFileDescriptors()) {
7431                 throw new IllegalArgumentException("File descriptors passed in options");
7432             }
7433         }
7434
7435         synchronized(this) {
7436             int callingUid = Binder.getCallingUid();
7437             int origUserId = userId;
7438             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7439                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7440                     ALLOW_NON_FULL, "getIntentSender", null);
7441             if (origUserId == UserHandle.USER_CURRENT) {
7442                 // We don't want to evaluate this until the pending intent is
7443                 // actually executed.  However, we do want to always do the
7444                 // security checking for it above.
7445                 userId = UserHandle.USER_CURRENT;
7446             }
7447             try {
7448                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7449                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7450                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7451                     if (!UserHandle.isSameApp(callingUid, uid)) {
7452                         String msg = "Permission Denial: getIntentSender() from pid="
7453                             + Binder.getCallingPid()
7454                             + ", uid=" + Binder.getCallingUid()
7455                             + ", (need uid=" + uid + ")"
7456                             + " is not allowed to send as package " + packageName;
7457                         Slog.w(TAG, msg);
7458                         throw new SecurityException(msg);
7459                     }
7460                 }
7461
7462                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7463                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7464
7465             } catch (RemoteException e) {
7466                 throw new SecurityException(e);
7467             }
7468         }
7469     }
7470
7471     IIntentSender getIntentSenderLocked(int type, String packageName,
7472             int callingUid, int userId, IBinder token, String resultWho,
7473             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7474             Bundle bOptions) {
7475         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7476         ActivityRecord activity = null;
7477         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7478             activity = ActivityRecord.isInStackLocked(token);
7479             if (activity == null) {
7480                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7481                 return null;
7482             }
7483             if (activity.finishing) {
7484                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7485                 return null;
7486             }
7487         }
7488
7489         // We're going to be splicing together extras before sending, so we're
7490         // okay poking into any contained extras.
7491         if (intents != null) {
7492             for (int i = 0; i < intents.length; i++) {
7493                 intents[i].setDefusable(true);
7494             }
7495         }
7496         Bundle.setDefusable(bOptions, true);
7497
7498         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7499         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7500         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7501         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7502                 |PendingIntent.FLAG_UPDATE_CURRENT);
7503
7504         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7505                 type, packageName, activity, resultWho,
7506                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7507         WeakReference<PendingIntentRecord> ref;
7508         ref = mIntentSenderRecords.get(key);
7509         PendingIntentRecord rec = ref != null ? ref.get() : null;
7510         if (rec != null) {
7511             if (!cancelCurrent) {
7512                 if (updateCurrent) {
7513                     if (rec.key.requestIntent != null) {
7514                         rec.key.requestIntent.replaceExtras(intents != null ?
7515                                 intents[intents.length - 1] : null);
7516                     }
7517                     if (intents != null) {
7518                         intents[intents.length-1] = rec.key.requestIntent;
7519                         rec.key.allIntents = intents;
7520                         rec.key.allResolvedTypes = resolvedTypes;
7521                     } else {
7522                         rec.key.allIntents = null;
7523                         rec.key.allResolvedTypes = null;
7524                     }
7525                 }
7526                 return rec;
7527             }
7528             makeIntentSenderCanceledLocked(rec);
7529             mIntentSenderRecords.remove(key);
7530         }
7531         if (noCreate) {
7532             return rec;
7533         }
7534         rec = new PendingIntentRecord(this, key, callingUid);
7535         mIntentSenderRecords.put(key, rec.ref);
7536         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7537             if (activity.pendingResults == null) {
7538                 activity.pendingResults
7539                         = new HashSet<WeakReference<PendingIntentRecord>>();
7540             }
7541             activity.pendingResults.add(rec.ref);
7542         }
7543         return rec;
7544     }
7545
7546     @Override
7547     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7548             Intent intent, String resolvedType,
7549             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7550         if (target instanceof PendingIntentRecord) {
7551             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7552                     whitelistToken, finishedReceiver, requiredPermission, options);
7553         } else {
7554             if (intent == null) {
7555                 // Weird case: someone has given us their own custom IIntentSender, and now
7556                 // they have someone else trying to send to it but of course this isn't
7557                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7558                 // supplying an Intent... but we never want to dispatch a null Intent to
7559                 // a receiver, so um...  let's make something up.
7560                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7561                 intent = new Intent(Intent.ACTION_MAIN);
7562             }
7563             try {
7564                 target.send(code, intent, resolvedType, whitelistToken, null,
7565                         requiredPermission, options);
7566             } catch (RemoteException e) {
7567             }
7568             // Platform code can rely on getting a result back when the send is done, but if
7569             // this intent sender is from outside of the system we can't rely on it doing that.
7570             // So instead we don't give it the result receiver, and instead just directly
7571             // report the finish immediately.
7572             if (finishedReceiver != null) {
7573                 try {
7574                     finishedReceiver.performReceive(intent, 0,
7575                             null, null, false, false, UserHandle.getCallingUserId());
7576                 } catch (RemoteException e) {
7577                 }
7578             }
7579             return 0;
7580         }
7581     }
7582
7583     @Override
7584     public void cancelIntentSender(IIntentSender sender) {
7585         if (!(sender instanceof PendingIntentRecord)) {
7586             return;
7587         }
7588         synchronized(this) {
7589             PendingIntentRecord rec = (PendingIntentRecord)sender;
7590             try {
7591                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7592                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7593                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7594                     String msg = "Permission Denial: cancelIntentSender() from pid="
7595                         + Binder.getCallingPid()
7596                         + ", uid=" + Binder.getCallingUid()
7597                         + " is not allowed to cancel package "
7598                         + rec.key.packageName;
7599                     Slog.w(TAG, msg);
7600                     throw new SecurityException(msg);
7601                 }
7602             } catch (RemoteException e) {
7603                 throw new SecurityException(e);
7604             }
7605             cancelIntentSenderLocked(rec, true);
7606         }
7607     }
7608
7609     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7610         makeIntentSenderCanceledLocked(rec);
7611         mIntentSenderRecords.remove(rec.key);
7612         if (cleanActivity && rec.key.activity != null) {
7613             rec.key.activity.pendingResults.remove(rec.ref);
7614         }
7615     }
7616
7617     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7618         rec.canceled = true;
7619         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7620         if (callbacks != null) {
7621             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7622         }
7623     }
7624
7625     @Override
7626     public String getPackageForIntentSender(IIntentSender pendingResult) {
7627         if (!(pendingResult instanceof PendingIntentRecord)) {
7628             return null;
7629         }
7630         try {
7631             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7632             return res.key.packageName;
7633         } catch (ClassCastException e) {
7634         }
7635         return null;
7636     }
7637
7638     @Override
7639     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7640         if (!(sender instanceof PendingIntentRecord)) {
7641             return;
7642         }
7643         synchronized(this) {
7644             ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7645         }
7646     }
7647
7648     @Override
7649     public void unregisterIntentSenderCancelListener(IIntentSender sender,
7650             IResultReceiver receiver) {
7651         if (!(sender instanceof PendingIntentRecord)) {
7652             return;
7653         }
7654         synchronized(this) {
7655             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7656         }
7657     }
7658
7659     @Override
7660     public int getUidForIntentSender(IIntentSender sender) {
7661         if (sender instanceof PendingIntentRecord) {
7662             try {
7663                 PendingIntentRecord res = (PendingIntentRecord)sender;
7664                 return res.uid;
7665             } catch (ClassCastException e) {
7666             }
7667         }
7668         return -1;
7669     }
7670
7671     @Override
7672     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7673         if (!(pendingResult instanceof PendingIntentRecord)) {
7674             return false;
7675         }
7676         try {
7677             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7678             if (res.key.allIntents == null) {
7679                 return false;
7680             }
7681             for (int i=0; i<res.key.allIntents.length; i++) {
7682                 Intent intent = res.key.allIntents[i];
7683                 if (intent.getPackage() != null && intent.getComponent() != null) {
7684                     return false;
7685                 }
7686             }
7687             return true;
7688         } catch (ClassCastException e) {
7689         }
7690         return false;
7691     }
7692
7693     @Override
7694     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7695         if (!(pendingResult instanceof PendingIntentRecord)) {
7696             return false;
7697         }
7698         try {
7699             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7700             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7701                 return true;
7702             }
7703             return false;
7704         } catch (ClassCastException e) {
7705         }
7706         return false;
7707     }
7708
7709     @Override
7710     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7711         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7712                 "getIntentForIntentSender()");
7713         if (!(pendingResult instanceof PendingIntentRecord)) {
7714             return null;
7715         }
7716         try {
7717             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7718             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7719         } catch (ClassCastException e) {
7720         }
7721         return null;
7722     }
7723
7724     @Override
7725     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7726         if (!(pendingResult instanceof PendingIntentRecord)) {
7727             return null;
7728         }
7729         try {
7730             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7731             synchronized (this) {
7732                 return getTagForIntentSenderLocked(res, prefix);
7733             }
7734         } catch (ClassCastException e) {
7735         }
7736         return null;
7737     }
7738
7739     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7740         final Intent intent = res.key.requestIntent;
7741         if (intent != null) {
7742             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7743                     || res.lastTagPrefix.equals(prefix))) {
7744                 return res.lastTag;
7745             }
7746             res.lastTagPrefix = prefix;
7747             final StringBuilder sb = new StringBuilder(128);
7748             if (prefix != null) {
7749                 sb.append(prefix);
7750             }
7751             if (intent.getAction() != null) {
7752                 sb.append(intent.getAction());
7753             } else if (intent.getComponent() != null) {
7754                 intent.getComponent().appendShortString(sb);
7755             } else {
7756                 sb.append("?");
7757             }
7758             return res.lastTag = sb.toString();
7759         }
7760         return null;
7761     }
7762
7763     @Override
7764     public void setProcessLimit(int max) {
7765         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7766                 "setProcessLimit()");
7767         synchronized (this) {
7768             mConstants.setOverrideMaxCachedProcesses(max);
7769         }
7770         trimApplications();
7771     }
7772
7773     @Override
7774     public int getProcessLimit() {
7775         synchronized (this) {
7776             return mConstants.getOverrideMaxCachedProcesses();
7777         }
7778     }
7779
7780     void importanceTokenDied(ImportanceToken token) {
7781         synchronized (ActivityManagerService.this) {
7782             synchronized (mPidsSelfLocked) {
7783                 ImportanceToken cur
7784                     = mImportantProcesses.get(token.pid);
7785                 if (cur != token) {
7786                     return;
7787                 }
7788                 mImportantProcesses.remove(token.pid);
7789                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7790                 if (pr == null) {
7791                     return;
7792                 }
7793                 pr.forcingToImportant = null;
7794                 updateProcessForegroundLocked(pr, false, false);
7795             }
7796             updateOomAdjLocked();
7797         }
7798     }
7799
7800     @Override
7801     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7802         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7803                 "setProcessImportant()");
7804         synchronized(this) {
7805             boolean changed = false;
7806
7807             synchronized (mPidsSelfLocked) {
7808                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7809                 if (pr == null && isForeground) {
7810                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7811                     return;
7812                 }
7813                 ImportanceToken oldToken = mImportantProcesses.get(pid);
7814                 if (oldToken != null) {
7815                     oldToken.token.unlinkToDeath(oldToken, 0);
7816                     mImportantProcesses.remove(pid);
7817                     if (pr != null) {
7818                         pr.forcingToImportant = null;
7819                     }
7820                     changed = true;
7821                 }
7822                 if (isForeground && token != null) {
7823                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7824                         @Override
7825                         public void binderDied() {
7826                             importanceTokenDied(this);
7827                         }
7828                     };
7829                     try {
7830                         token.linkToDeath(newToken, 0);
7831                         mImportantProcesses.put(pid, newToken);
7832                         pr.forcingToImportant = newToken;
7833                         changed = true;
7834                     } catch (RemoteException e) {
7835                         // If the process died while doing this, we will later
7836                         // do the cleanup with the process death link.
7837                     }
7838                 }
7839             }
7840
7841             if (changed) {
7842                 updateOomAdjLocked();
7843             }
7844         }
7845     }
7846
7847     @Override
7848     public boolean isAppForeground(int uid) throws RemoteException {
7849         int callerUid = Binder.getCallingUid();
7850         if (UserHandle.isCore(callerUid) || callerUid == uid) {
7851             return isAppForegroundInternal(uid);
7852         }
7853         return false;
7854     }
7855
7856     private boolean isAppForegroundInternal(int uid) {
7857         synchronized (this) {
7858             UidRecord uidRec = mActiveUids.get(uid);
7859             if (uidRec == null || uidRec.idle) {
7860                 return false;
7861             }
7862             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7863         }
7864     }
7865
7866     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7867     // be guarded by permission checking.
7868     int getUidState(int uid) {
7869         synchronized (this) {
7870             return getUidStateLocked(uid);
7871         }
7872     }
7873
7874     int getUidStateLocked(int uid) {
7875         UidRecord uidRec = mActiveUids.get(uid);
7876         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7877     }
7878
7879     @Override
7880     public boolean isInMultiWindowMode(IBinder token) {
7881         final long origId = Binder.clearCallingIdentity();
7882         try {
7883             synchronized(this) {
7884                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7885                 if (r == null) {
7886                     return false;
7887                 }
7888                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7889                 return !r.getTask().mFullscreen;
7890             }
7891         } finally {
7892             Binder.restoreCallingIdentity(origId);
7893         }
7894     }
7895
7896     @Override
7897     public boolean isInPictureInPictureMode(IBinder token) {
7898         final long origId = Binder.clearCallingIdentity();
7899         try {
7900             synchronized(this) {
7901                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
7902             }
7903         } finally {
7904             Binder.restoreCallingIdentity(origId);
7905         }
7906     }
7907
7908     private boolean isInPictureInPictureMode(ActivityRecord r) {
7909         if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
7910                 r.getStack().isInStackLocked(r) == null) {
7911             return false;
7912         }
7913
7914         // If we are animating to fullscreen then we have already dispatched the PIP mode
7915         // changed, so we should reflect that check here as well.
7916         final PinnedActivityStack stack = r.getStack();
7917         final PinnedStackWindowController windowController = stack.getWindowContainerController();
7918         return !windowController.isAnimatingBoundsToFullscreen();
7919     }
7920
7921     @Override
7922     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
7923         final long origId = Binder.clearCallingIdentity();
7924         try {
7925             synchronized(this) {
7926                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7927                         "enterPictureInPictureMode", token, params);
7928
7929                 // If the activity is already in picture in picture mode, then just return early
7930                 if (isInPictureInPictureMode(r)) {
7931                     return true;
7932                 }
7933
7934                 // Activity supports picture-in-picture, now check that we can enter PiP at this
7935                 // point, if it is
7936                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7937                         false /* noThrow */, false /* beforeStopping */)) {
7938                     return false;
7939                 }
7940
7941                 final Runnable enterPipRunnable = () -> {
7942                     // Only update the saved args from the args that are set
7943                     r.pictureInPictureArgs.copyOnlySet(params);
7944                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
7945                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
7946                     // Adjust the source bounds by the insets for the transition down
7947                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
7948                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
7949                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7950                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
7951                     stack.setPictureInPictureAspectRatio(aspectRatio);
7952                     stack.setPictureInPictureActions(actions);
7953
7954                     MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
7955                             r.supportsPictureInPictureWhilePausing);
7956                     logPictureInPictureArgs(params);
7957                 };
7958
7959                 if (isKeyguardLocked()) {
7960                     // If the keyguard is showing or occluded, then try and dismiss it before
7961                     // entering picture-in-picture (this will prompt the user to authenticate if the
7962                     // device is currently locked).
7963                     try {
7964                         dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7965                             @Override
7966                             public void onDismissError() throws RemoteException {
7967                                 // Do nothing
7968                             }
7969
7970                             @Override
7971                             public void onDismissSucceeded() throws RemoteException {
7972                                 mHandler.post(enterPipRunnable);
7973                             }
7974
7975                             @Override
7976                             public void onDismissCancelled() throws RemoteException {
7977                                 // Do nothing
7978                             }
7979                         });
7980                     } catch (RemoteException e) {
7981                         // Local call
7982                     }
7983                 } else {
7984                     // Enter picture in picture immediately otherwise
7985                     enterPipRunnable.run();
7986                 }
7987                 return true;
7988             }
7989         } finally {
7990             Binder.restoreCallingIdentity(origId);
7991         }
7992     }
7993
7994     @Override
7995     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
7996         final long origId = Binder.clearCallingIdentity();
7997         try {
7998             synchronized(this) {
7999                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8000                         "setPictureInPictureParams", token, params);
8001
8002                 // Only update the saved args from the args that are set
8003                 r.pictureInPictureArgs.copyOnlySet(params);
8004                 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8005                     // If the activity is already in picture-in-picture, update the pinned stack now
8006                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
8007                     // be used the next time the activity enters PiP
8008                     final PinnedActivityStack stack = r.getStack();
8009                     if (!stack.isAnimatingBoundsToFullscreen()) {
8010                         stack.setPictureInPictureAspectRatio(
8011                                 r.pictureInPictureArgs.getAspectRatio());
8012                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8013                     }
8014                 }
8015                 logPictureInPictureArgs(params);
8016             }
8017         } finally {
8018             Binder.restoreCallingIdentity(origId);
8019         }
8020     }
8021
8022     @Override
8023     public int getMaxNumPictureInPictureActions(IBinder token) {
8024         // Currently, this is a static constant, but later, we may change this to be dependent on
8025         // the context of the activity
8026         return 3;
8027     }
8028
8029     private void logPictureInPictureArgs(PictureInPictureParams params) {
8030         if (params.hasSetActions()) {
8031             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8032                     params.getActions().size());
8033         }
8034         if (params.hasSetAspectRatio()) {
8035             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8036             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8037             MetricsLogger.action(lm);
8038         }
8039     }
8040
8041     /**
8042      * Checks the state of the system and the activity associated with the given {@param token} to
8043      * verify that picture-in-picture is supported for that activity.
8044      *
8045      * @return the activity record for the given {@param token} if all the checks pass.
8046      */
8047     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8048             IBinder token, PictureInPictureParams params) {
8049         if (!mSupportsPictureInPicture) {
8050             throw new IllegalStateException(caller
8051                     + ": Device doesn't support picture-in-picture mode.");
8052         }
8053
8054         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8055         if (r == null) {
8056             throw new IllegalStateException(caller
8057                     + ": Can't find activity for token=" + token);
8058         }
8059
8060         if (!r.supportsPictureInPicture()) {
8061             throw new IllegalStateException(caller
8062                     + ": Current activity does not support picture-in-picture.");
8063         }
8064
8065         if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8066             throw new IllegalStateException(caller
8067                     + ": Activities on the home, assistant, or recents stack not supported");
8068         }
8069
8070         if (params.hasSetAspectRatio()
8071                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8072                         params.getAspectRatio())) {
8073             final float minAspectRatio = mContext.getResources().getFloat(
8074                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8075             final float maxAspectRatio = mContext.getResources().getFloat(
8076                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8077             throw new IllegalArgumentException(String.format(caller
8078                     + ": Aspect ratio is too extreme (must be between %f and %f).",
8079                             minAspectRatio, maxAspectRatio));
8080         }
8081
8082         // Truncate the number of actions if necessary
8083         params.truncateActions(getMaxNumPictureInPictureActions(token));
8084
8085         return r;
8086     }
8087
8088     // =========================================================
8089     // PROCESS INFO
8090     // =========================================================
8091
8092     static class ProcessInfoService extends IProcessInfoService.Stub {
8093         final ActivityManagerService mActivityManagerService;
8094         ProcessInfoService(ActivityManagerService activityManagerService) {
8095             mActivityManagerService = activityManagerService;
8096         }
8097
8098         @Override
8099         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8100             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8101                     /*in*/ pids, /*out*/ states, null);
8102         }
8103
8104         @Override
8105         public void getProcessStatesAndOomScoresFromPids(
8106                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8107             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8108                     /*in*/ pids, /*out*/ states, /*out*/ scores);
8109         }
8110     }
8111
8112     /**
8113      * For each PID in the given input array, write the current process state
8114      * for that process into the states array, or -1 to indicate that no
8115      * process with the given PID exists. If scores array is provided, write
8116      * the oom score for the process into the scores array, with INVALID_ADJ
8117      * indicating the PID doesn't exist.
8118      */
8119     public void getProcessStatesAndOomScoresForPIDs(
8120             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8121         if (scores != null) {
8122             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8123                     "getProcessStatesAndOomScoresForPIDs()");
8124         }
8125
8126         if (pids == null) {
8127             throw new NullPointerException("pids");
8128         } else if (states == null) {
8129             throw new NullPointerException("states");
8130         } else if (pids.length != states.length) {
8131             throw new IllegalArgumentException("pids and states arrays have different lengths!");
8132         } else if (scores != null && pids.length != scores.length) {
8133             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8134         }
8135
8136         synchronized (mPidsSelfLocked) {
8137             for (int i = 0; i < pids.length; i++) {
8138                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8139                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8140                         pr.curProcState;
8141                 if (scores != null) {
8142                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8143                 }
8144             }
8145         }
8146     }
8147
8148     // =========================================================
8149     // PERMISSIONS
8150     // =========================================================
8151
8152     static class PermissionController extends IPermissionController.Stub {
8153         ActivityManagerService mActivityManagerService;
8154         PermissionController(ActivityManagerService activityManagerService) {
8155             mActivityManagerService = activityManagerService;
8156         }
8157
8158         @Override
8159         public boolean checkPermission(String permission, int pid, int uid) {
8160             return mActivityManagerService.checkPermission(permission, pid,
8161                     uid) == PackageManager.PERMISSION_GRANTED;
8162         }
8163
8164         @Override
8165         public String[] getPackagesForUid(int uid) {
8166             return mActivityManagerService.mContext.getPackageManager()
8167                     .getPackagesForUid(uid);
8168         }
8169
8170         @Override
8171         public boolean isRuntimePermission(String permission) {
8172             try {
8173                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8174                         .getPermissionInfo(permission, 0);
8175                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8176                         == PermissionInfo.PROTECTION_DANGEROUS;
8177             } catch (NameNotFoundException nnfe) {
8178                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8179             }
8180             return false;
8181         }
8182     }
8183
8184     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8185         @Override
8186         public int checkComponentPermission(String permission, int pid, int uid,
8187                 int owningUid, boolean exported) {
8188             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8189                     owningUid, exported);
8190         }
8191
8192         @Override
8193         public Object getAMSLock() {
8194             return ActivityManagerService.this;
8195         }
8196     }
8197
8198     /**
8199      * This can be called with or without the global lock held.
8200      */
8201     int checkComponentPermission(String permission, int pid, int uid,
8202             int owningUid, boolean exported) {
8203         if (pid == MY_PID) {
8204             return PackageManager.PERMISSION_GRANTED;
8205         }
8206         return ActivityManager.checkComponentPermission(permission, uid,
8207                 owningUid, exported);
8208     }
8209
8210     /**
8211      * As the only public entry point for permissions checking, this method
8212      * can enforce the semantic that requesting a check on a null global
8213      * permission is automatically denied.  (Internally a null permission
8214      * string is used when calling {@link #checkComponentPermission} in cases
8215      * when only uid-based security is needed.)
8216      *
8217      * This can be called with or without the global lock held.
8218      */
8219     @Override
8220     public int checkPermission(String permission, int pid, int uid) {
8221         if (permission == null) {
8222             return PackageManager.PERMISSION_DENIED;
8223         }
8224         return checkComponentPermission(permission, pid, uid, -1, true);
8225     }
8226
8227     @Override
8228     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8229         if (permission == null) {
8230             return PackageManager.PERMISSION_DENIED;
8231         }
8232
8233         // We might be performing an operation on behalf of an indirect binder
8234         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8235         // client identity accordingly before proceeding.
8236         Identity tlsIdentity = sCallerIdentity.get();
8237         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8238             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8239                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8240             uid = tlsIdentity.uid;
8241             pid = tlsIdentity.pid;
8242         }
8243
8244         return checkComponentPermission(permission, pid, uid, -1, true);
8245     }
8246
8247     /**
8248      * Binder IPC calls go through the public entry point.
8249      * This can be called with or without the global lock held.
8250      */
8251     int checkCallingPermission(String permission) {
8252         return checkPermission(permission,
8253                 Binder.getCallingPid(),
8254                 UserHandle.getAppId(Binder.getCallingUid()));
8255     }
8256
8257     /**
8258      * This can be called with or without the global lock held.
8259      */
8260     void enforceCallingPermission(String permission, String func) {
8261         if (checkCallingPermission(permission)
8262                 == PackageManager.PERMISSION_GRANTED) {
8263             return;
8264         }
8265
8266         String msg = "Permission Denial: " + func + " from pid="
8267                 + Binder.getCallingPid()
8268                 + ", uid=" + Binder.getCallingUid()
8269                 + " requires " + permission;
8270         Slog.w(TAG, msg);
8271         throw new SecurityException(msg);
8272     }
8273
8274     /**
8275      * Determine if UID is holding permissions required to access {@link Uri} in
8276      * the given {@link ProviderInfo}. Final permission checking is always done
8277      * in {@link ContentProvider}.
8278      */
8279     private final boolean checkHoldingPermissionsLocked(
8280             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8281         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8282                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8283         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8284             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8285                     != PERMISSION_GRANTED) {
8286                 return false;
8287             }
8288         }
8289         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8290     }
8291
8292     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8293             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8294         if (pi.applicationInfo.uid == uid) {
8295             return true;
8296         } else if (!pi.exported) {
8297             return false;
8298         }
8299
8300         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8301         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8302         try {
8303             // check if target holds top-level <provider> permissions
8304             if (!readMet && pi.readPermission != null && considerUidPermissions
8305                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8306                 readMet = true;
8307             }
8308             if (!writeMet && pi.writePermission != null && considerUidPermissions
8309                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8310                 writeMet = true;
8311             }
8312
8313             // track if unprotected read/write is allowed; any denied
8314             // <path-permission> below removes this ability
8315             boolean allowDefaultRead = pi.readPermission == null;
8316             boolean allowDefaultWrite = pi.writePermission == null;
8317
8318             // check if target holds any <path-permission> that match uri
8319             final PathPermission[] pps = pi.pathPermissions;
8320             if (pps != null) {
8321                 final String path = grantUri.uri.getPath();
8322                 int i = pps.length;
8323                 while (i > 0 && (!readMet || !writeMet)) {
8324                     i--;
8325                     PathPermission pp = pps[i];
8326                     if (pp.match(path)) {
8327                         if (!readMet) {
8328                             final String pprperm = pp.getReadPermission();
8329                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8330                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
8331                                     + ": match=" + pp.match(path)
8332                                     + " check=" + pm.checkUidPermission(pprperm, uid));
8333                             if (pprperm != null) {
8334                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8335                                         == PERMISSION_GRANTED) {
8336                                     readMet = true;
8337                                 } else {
8338                                     allowDefaultRead = false;
8339                                 }
8340                             }
8341                         }
8342                         if (!writeMet) {
8343                             final String ppwperm = pp.getWritePermission();
8344                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8345                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
8346                                     + ": match=" + pp.match(path)
8347                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
8348                             if (ppwperm != null) {
8349                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8350                                         == PERMISSION_GRANTED) {
8351                                     writeMet = true;
8352                                 } else {
8353                                     allowDefaultWrite = false;
8354                                 }
8355                             }
8356                         }
8357                     }
8358                 }
8359             }
8360
8361             // grant unprotected <provider> read/write, if not blocked by
8362             // <path-permission> above
8363             if (allowDefaultRead) readMet = true;
8364             if (allowDefaultWrite) writeMet = true;
8365
8366         } catch (RemoteException e) {
8367             return false;
8368         }
8369
8370         return readMet && writeMet;
8371     }
8372
8373     public boolean isAppStartModeDisabled(int uid, String packageName) {
8374         synchronized (this) {
8375             return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8376                     == ActivityManager.APP_START_MODE_DISABLED;
8377         }
8378     }
8379
8380     // Unified app-op and target sdk check
8381     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8382         // Apps that target O+ are always subject to background check
8383         if (packageTargetSdk >= Build.VERSION_CODES.O) {
8384             if (DEBUG_BACKGROUND_CHECK) {
8385                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8386             }
8387             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8388         }
8389         // ...and legacy apps get an AppOp check
8390         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8391                 uid, packageName);
8392         if (DEBUG_BACKGROUND_CHECK) {
8393             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8394         }
8395         switch (appop) {
8396             case AppOpsManager.MODE_ALLOWED:
8397                 return ActivityManager.APP_START_MODE_NORMAL;
8398             case AppOpsManager.MODE_IGNORED:
8399                 return ActivityManager.APP_START_MODE_DELAYED;
8400             default:
8401                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8402         }
8403     }
8404
8405     // Service launch is available to apps with run-in-background exemptions but
8406     // some other background operations are not.  If we're doing a check
8407     // of service-launch policy, allow those callers to proceed unrestricted.
8408     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8409         // Persistent app?
8410         if (mPackageManagerInt.isPackagePersistent(packageName)) {
8411             if (DEBUG_BACKGROUND_CHECK) {
8412                 Slog.i(TAG, "App " + uid + "/" + packageName
8413                         + " is persistent; not restricted in background");
8414             }
8415             return ActivityManager.APP_START_MODE_NORMAL;
8416         }
8417
8418         // Non-persistent but background whitelisted?
8419         if (uidOnBackgroundWhitelist(uid)) {
8420             if (DEBUG_BACKGROUND_CHECK) {
8421                 Slog.i(TAG, "App " + uid + "/" + packageName
8422                         + " on background whitelist; not restricted in background");
8423             }
8424             return ActivityManager.APP_START_MODE_NORMAL;
8425         }
8426
8427         // Is this app on the battery whitelist?
8428         if (isOnDeviceIdleWhitelistLocked(uid)) {
8429             if (DEBUG_BACKGROUND_CHECK) {
8430                 Slog.i(TAG, "App " + uid + "/" + packageName
8431                         + " on idle whitelist; not restricted in background");
8432             }
8433             return ActivityManager.APP_START_MODE_NORMAL;
8434         }
8435
8436         // None of the service-policy criteria apply, so we apply the common criteria
8437         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8438     }
8439
8440     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8441             int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8442         UidRecord uidRec = mActiveUids.get(uid);
8443         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8444                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8445                 + (uidRec != null ? uidRec.idle : false));
8446         if (uidRec == null || alwaysRestrict || uidRec.idle) {
8447             boolean ephemeral;
8448             if (uidRec == null) {
8449                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8450                         UserHandle.getUserId(uid), packageName);
8451             } else {
8452                 ephemeral = uidRec.ephemeral;
8453             }
8454
8455             if (ephemeral) {
8456                 // We are hard-core about ephemeral apps not running in the background.
8457                 return ActivityManager.APP_START_MODE_DISABLED;
8458             } else {
8459                 if (disabledOnly) {
8460                     // The caller is only interested in whether app starts are completely
8461                     // disabled for the given package (that is, it is an instant app).  So
8462                     // we don't need to go further, which is all just seeing if we should
8463                     // apply a "delayed" mode for a regular app.
8464                     return ActivityManager.APP_START_MODE_NORMAL;
8465                 }
8466                 final int startMode = (alwaysRestrict)
8467                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8468                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
8469                                 packageTargetSdk);
8470                 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8471                         + " pkg=" + packageName + " startMode=" + startMode
8472                         + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8473                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8474                     // This is an old app that has been forced into a "compatible as possible"
8475                     // mode of background check.  To increase compatibility, we will allow other
8476                     // foreground apps to cause its services to start.
8477                     if (callingPid >= 0) {
8478                         ProcessRecord proc;
8479                         synchronized (mPidsSelfLocked) {
8480                             proc = mPidsSelfLocked.get(callingPid);
8481                         }
8482                         if (proc != null &&
8483                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8484                             // Whoever is instigating this is in the foreground, so we will allow it
8485                             // to go through.
8486                             return ActivityManager.APP_START_MODE_NORMAL;
8487                         }
8488                     }
8489                 }
8490                 return startMode;
8491             }
8492         }
8493         return ActivityManager.APP_START_MODE_NORMAL;
8494     }
8495
8496     boolean isOnDeviceIdleWhitelistLocked(int uid) {
8497         final int appId = UserHandle.getAppId(uid);
8498         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8499                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8500                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8501     }
8502
8503     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8504         ProviderInfo pi = null;
8505         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8506         if (cpr != null) {
8507             pi = cpr.info;
8508         } else {
8509             try {
8510                 pi = AppGlobals.getPackageManager().resolveContentProvider(
8511                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8512                         userHandle);
8513             } catch (RemoteException ex) {
8514             }
8515         }
8516         return pi;
8517     }
8518
8519     void grantEphemeralAccessLocked(int userId, Intent intent,
8520             int targetAppId, int ephemeralAppId) {
8521         getPackageManagerInternalLocked().
8522                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8523     }
8524
8525     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8526         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8527         if (targetUris != null) {
8528             return targetUris.get(grantUri);
8529         }
8530         return null;
8531     }
8532
8533     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8534             String targetPkg, int targetUid, GrantUri grantUri) {
8535         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8536         if (targetUris == null) {
8537             targetUris = Maps.newArrayMap();
8538             mGrantedUriPermissions.put(targetUid, targetUris);
8539         }
8540
8541         UriPermission perm = targetUris.get(grantUri);
8542         if (perm == null) {
8543             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8544             targetUris.put(grantUri, perm);
8545         }
8546
8547         return perm;
8548     }
8549
8550     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8551             final int modeFlags) {
8552         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8553         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8554                 : UriPermission.STRENGTH_OWNED;
8555
8556         // Root gets to do everything.
8557         if (uid == 0) {
8558             return true;
8559         }
8560
8561         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8562         if (perms == null) return false;
8563
8564         // First look for exact match
8565         final UriPermission exactPerm = perms.get(grantUri);
8566         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8567             return true;
8568         }
8569
8570         // No exact match, look for prefixes
8571         final int N = perms.size();
8572         for (int i = 0; i < N; i++) {
8573             final UriPermission perm = perms.valueAt(i);
8574             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8575                     && perm.getStrength(modeFlags) >= minStrength) {
8576                 return true;
8577             }
8578         }
8579
8580         return false;
8581     }
8582
8583     /**
8584      * @param uri This uri must NOT contain an embedded userId.
8585      * @param userId The userId in which the uri is to be resolved.
8586      */
8587     @Override
8588     public int checkUriPermission(Uri uri, int pid, int uid,
8589             final int modeFlags, int userId, IBinder callerToken) {
8590         enforceNotIsolatedCaller("checkUriPermission");
8591
8592         // Another redirected-binder-call permissions check as in
8593         // {@link checkPermissionWithToken}.
8594         Identity tlsIdentity = sCallerIdentity.get();
8595         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8596             uid = tlsIdentity.uid;
8597             pid = tlsIdentity.pid;
8598         }
8599
8600         // Our own process gets to do everything.
8601         if (pid == MY_PID) {
8602             return PackageManager.PERMISSION_GRANTED;
8603         }
8604         synchronized (this) {
8605             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8606                     ? PackageManager.PERMISSION_GRANTED
8607                     : PackageManager.PERMISSION_DENIED;
8608         }
8609     }
8610
8611     /**
8612      * Check if the targetPkg can be granted permission to access uri by
8613      * the callingUid using the given modeFlags.  Throws a security exception
8614      * if callingUid is not allowed to do this.  Returns the uid of the target
8615      * if the URI permission grant should be performed; returns -1 if it is not
8616      * needed (for example targetPkg already has permission to access the URI).
8617      * If you already know the uid of the target, you can supply it in
8618      * lastTargetUid else set that to -1.
8619      */
8620     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8621             final int modeFlags, int lastTargetUid) {
8622         if (!Intent.isAccessUriMode(modeFlags)) {
8623             return -1;
8624         }
8625
8626         if (targetPkg != null) {
8627             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8628                     "Checking grant " + targetPkg + " permission to " + grantUri);
8629         }
8630
8631         final IPackageManager pm = AppGlobals.getPackageManager();
8632
8633         // If this is not a content: uri, we can't do anything with it.
8634         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8635             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8636                     "Can't grant URI permission for non-content URI: " + grantUri);
8637             return -1;
8638         }
8639
8640         // Bail early if system is trying to hand out permissions directly; it
8641         // must always grant permissions on behalf of someone explicit.
8642         final int callingAppId = UserHandle.getAppId(callingUid);
8643         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8644             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8645                 // Exempted authority for cropping user photos in Settings app
8646             } else {
8647                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8648                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8649                 return -1;
8650             }
8651         }
8652
8653         final String authority = grantUri.uri.getAuthority();
8654         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8655                 MATCH_DEBUG_TRIAGED_MISSING);
8656         if (pi == null) {
8657             Slog.w(TAG, "No content provider found for permission check: " +
8658                     grantUri.uri.toSafeString());
8659             return -1;
8660         }
8661
8662         int targetUid = lastTargetUid;
8663         if (targetUid < 0 && targetPkg != null) {
8664             try {
8665                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8666                         UserHandle.getUserId(callingUid));
8667                 if (targetUid < 0) {
8668                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8669                             "Can't grant URI permission no uid for: " + targetPkg);
8670                     return -1;
8671                 }
8672             } catch (RemoteException ex) {
8673                 return -1;
8674             }
8675         }
8676
8677         // Figure out the value returned when access is allowed
8678         final int allowedResult;
8679         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8680             // If we're extending a persistable grant, then we need to return
8681             // "targetUid" so that we always create a grant data structure to
8682             // support take/release APIs
8683             allowedResult = targetUid;
8684         } else {
8685             // Otherwise, we can return "-1" to indicate that no grant data
8686             // structures need to be created
8687             allowedResult = -1;
8688         }
8689
8690         if (targetUid >= 0) {
8691             // First...  does the target actually need this permission?
8692             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8693                 // No need to grant the target this permission.
8694                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8695                         "Target " + targetPkg + " already has full permission to " + grantUri);
8696                 return allowedResult;
8697             }
8698         } else {
8699             // First...  there is no target package, so can anyone access it?
8700             boolean allowed = pi.exported;
8701             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8702                 if (pi.readPermission != null) {
8703                     allowed = false;
8704                 }
8705             }
8706             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8707                 if (pi.writePermission != null) {
8708                     allowed = false;
8709                 }
8710             }
8711             if (allowed) {
8712                 return allowedResult;
8713             }
8714         }
8715
8716         /* There is a special cross user grant if:
8717          * - The target is on another user.
8718          * - Apps on the current user can access the uri without any uid permissions.
8719          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8720          * grant uri permissions.
8721          */
8722         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8723                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8724                 modeFlags, false /*without considering the uid permissions*/);
8725
8726         // Second...  is the provider allowing granting of URI permissions?
8727         if (!specialCrossUserGrant) {
8728             if (!pi.grantUriPermissions) {
8729                 throw new SecurityException("Provider " + pi.packageName
8730                         + "/" + pi.name
8731                         + " does not allow granting of Uri permissions (uri "
8732                         + grantUri + ")");
8733             }
8734             if (pi.uriPermissionPatterns != null) {
8735                 final int N = pi.uriPermissionPatterns.length;
8736                 boolean allowed = false;
8737                 for (int i=0; i<N; i++) {
8738                     if (pi.uriPermissionPatterns[i] != null
8739                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8740                         allowed = true;
8741                         break;
8742                     }
8743                 }
8744                 if (!allowed) {
8745                     throw new SecurityException("Provider " + pi.packageName
8746                             + "/" + pi.name
8747                             + " does not allow granting of permission to path of Uri "
8748                             + grantUri);
8749                 }
8750             }
8751         }
8752
8753         // Third...  does the caller itself have permission to access
8754         // this uri?
8755         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8756             // Require they hold a strong enough Uri permission
8757             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8758                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8759                     throw new SecurityException(
8760                             "UID " + callingUid + " does not have permission to " + grantUri
8761                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8762                                     + "or related APIs");
8763                 } else {
8764                     throw new SecurityException(
8765                             "UID " + callingUid + " does not have permission to " + grantUri);
8766                 }
8767             }
8768         }
8769         return targetUid;
8770     }
8771
8772     /**
8773      * @param uri This uri must NOT contain an embedded userId.
8774      * @param userId The userId in which the uri is to be resolved.
8775      */
8776     @Override
8777     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8778             final int modeFlags, int userId) {
8779         enforceNotIsolatedCaller("checkGrantUriPermission");
8780         synchronized(this) {
8781             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8782                     new GrantUri(userId, uri, false), modeFlags, -1);
8783         }
8784     }
8785
8786     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8787             final int modeFlags, UriPermissionOwner owner) {
8788         if (!Intent.isAccessUriMode(modeFlags)) {
8789             return;
8790         }
8791
8792         // So here we are: the caller has the assumed permission
8793         // to the uri, and the target doesn't.  Let's now give this to
8794         // the target.
8795
8796         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8797                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8798
8799         final String authority = grantUri.uri.getAuthority();
8800         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8801                 MATCH_DEBUG_TRIAGED_MISSING);
8802         if (pi == null) {
8803             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8804             return;
8805         }
8806
8807         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8808             grantUri.prefix = true;
8809         }
8810         final UriPermission perm = findOrCreateUriPermissionLocked(
8811                 pi.packageName, targetPkg, targetUid, grantUri);
8812         perm.grantModes(modeFlags, owner);
8813     }
8814
8815     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8816             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8817         if (targetPkg == null) {
8818             throw new NullPointerException("targetPkg");
8819         }
8820         int targetUid;
8821         final IPackageManager pm = AppGlobals.getPackageManager();
8822         try {
8823             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8824         } catch (RemoteException ex) {
8825             return;
8826         }
8827
8828         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8829                 targetUid);
8830         if (targetUid < 0) {
8831             return;
8832         }
8833
8834         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8835                 owner);
8836     }
8837
8838     static class NeededUriGrants extends ArrayList<GrantUri> {
8839         final String targetPkg;
8840         final int targetUid;
8841         final int flags;
8842
8843         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8844             this.targetPkg = targetPkg;
8845             this.targetUid = targetUid;
8846             this.flags = flags;
8847         }
8848     }
8849
8850     /**
8851      * Like checkGrantUriPermissionLocked, but takes an Intent.
8852      */
8853     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8854             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8855         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8856                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8857                 + " clip=" + (intent != null ? intent.getClipData() : null)
8858                 + " from " + intent + "; flags=0x"
8859                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8860
8861         if (targetPkg == null) {
8862             throw new NullPointerException("targetPkg");
8863         }
8864
8865         if (intent == null) {
8866             return null;
8867         }
8868         Uri data = intent.getData();
8869         ClipData clip = intent.getClipData();
8870         if (data == null && clip == null) {
8871             return null;
8872         }
8873         // Default userId for uris in the intent (if they don't specify it themselves)
8874         int contentUserHint = intent.getContentUserHint();
8875         if (contentUserHint == UserHandle.USER_CURRENT) {
8876             contentUserHint = UserHandle.getUserId(callingUid);
8877         }
8878         final IPackageManager pm = AppGlobals.getPackageManager();
8879         int targetUid;
8880         if (needed != null) {
8881             targetUid = needed.targetUid;
8882         } else {
8883             try {
8884                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8885                         targetUserId);
8886             } catch (RemoteException ex) {
8887                 return null;
8888             }
8889             if (targetUid < 0) {
8890                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8891                         "Can't grant URI permission no uid for: " + targetPkg
8892                         + " on user " + targetUserId);
8893                 return null;
8894             }
8895         }
8896         if (data != null) {
8897             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8898             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8899                     targetUid);
8900             if (targetUid > 0) {
8901                 if (needed == null) {
8902                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8903                 }
8904                 needed.add(grantUri);
8905             }
8906         }
8907         if (clip != null) {
8908             for (int i=0; i<clip.getItemCount(); i++) {
8909                 Uri uri = clip.getItemAt(i).getUri();
8910                 if (uri != null) {
8911                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8912                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8913                             targetUid);
8914                     if (targetUid > 0) {
8915                         if (needed == null) {
8916                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8917                         }
8918                         needed.add(grantUri);
8919                     }
8920                 } else {
8921                     Intent clipIntent = clip.getItemAt(i).getIntent();
8922                     if (clipIntent != null) {
8923                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8924                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8925                         if (newNeeded != null) {
8926                             needed = newNeeded;
8927                         }
8928                     }
8929                 }
8930             }
8931         }
8932
8933         return needed;
8934     }
8935
8936     /**
8937      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8938      */
8939     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8940             UriPermissionOwner owner) {
8941         if (needed != null) {
8942             for (int i=0; i<needed.size(); i++) {
8943                 GrantUri grantUri = needed.get(i);
8944                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8945                         grantUri, needed.flags, owner);
8946             }
8947         }
8948     }
8949
8950     void grantUriPermissionFromIntentLocked(int callingUid,
8951             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8952         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8953                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8954         if (needed == null) {
8955             return;
8956         }
8957
8958         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8959     }
8960
8961     /**
8962      * @param uri This uri must NOT contain an embedded userId.
8963      * @param userId The userId in which the uri is to be resolved.
8964      */
8965     @Override
8966     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8967             final int modeFlags, int userId) {
8968         enforceNotIsolatedCaller("grantUriPermission");
8969         GrantUri grantUri = new GrantUri(userId, uri, false);
8970         synchronized(this) {
8971             final ProcessRecord r = getRecordForAppLocked(caller);
8972             if (r == null) {
8973                 throw new SecurityException("Unable to find app for caller "
8974                         + caller
8975                         + " when granting permission to uri " + grantUri);
8976             }
8977             if (targetPkg == null) {
8978                 throw new IllegalArgumentException("null target");
8979             }
8980             if (grantUri == null) {
8981                 throw new IllegalArgumentException("null uri");
8982             }
8983
8984             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8985                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8986                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8987                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8988
8989             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8990                     UserHandle.getUserId(r.uid));
8991         }
8992     }
8993
8994     void removeUriPermissionIfNeededLocked(UriPermission perm) {
8995         if (perm.modeFlags == 0) {
8996             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8997                     perm.targetUid);
8998             if (perms != null) {
8999                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9000                         "Removing " + perm.targetUid + " permission to " + perm.uri);
9001
9002                 perms.remove(perm.uri);
9003                 if (perms.isEmpty()) {
9004                     mGrantedUriPermissions.remove(perm.targetUid);
9005                 }
9006             }
9007         }
9008     }
9009
9010     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9011             final int modeFlags) {
9012         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9013                 "Revoking all granted permissions to " + grantUri);
9014
9015         final IPackageManager pm = AppGlobals.getPackageManager();
9016         final String authority = grantUri.uri.getAuthority();
9017         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9018                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9019         if (pi == null) {
9020             Slog.w(TAG, "No content provider found for permission revoke: "
9021                     + grantUri.toSafeString());
9022             return;
9023         }
9024
9025         // Does the caller have this permission on the URI?
9026         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9027             // If they don't have direct access to the URI, then revoke any
9028             // ownerless URI permissions that have been granted to them.
9029             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9030             if (perms != null) {
9031                 boolean persistChanged = false;
9032                 for (int i = perms.size()-1; i >= 0; i--) {
9033                     final UriPermission perm = perms.valueAt(i);
9034                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9035                         continue;
9036                     }
9037                     if (perm.uri.sourceUserId == grantUri.sourceUserId
9038                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9039                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9040                                 "Revoking non-owned " + perm.targetUid
9041                                 + " permission to " + perm.uri);
9042                         persistChanged |= perm.revokeModes(
9043                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9044                         if (perm.modeFlags == 0) {
9045                             perms.removeAt(i);
9046                         }
9047                     }
9048                 }
9049                 if (perms.isEmpty()) {
9050                     mGrantedUriPermissions.remove(callingUid);
9051                 }
9052                 if (persistChanged) {
9053                     schedulePersistUriGrants();
9054                 }
9055             }
9056             return;
9057         }
9058
9059         boolean persistChanged = false;
9060
9061         // Go through all of the permissions and remove any that match.
9062         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9063             final int targetUid = mGrantedUriPermissions.keyAt(i);
9064             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9065
9066             for (int j = perms.size()-1; j >= 0; j--) {
9067                 final UriPermission perm = perms.valueAt(j);
9068                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9069                     continue;
9070                 }
9071                 if (perm.uri.sourceUserId == grantUri.sourceUserId
9072                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9073                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9074                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9075                     persistChanged |= perm.revokeModes(
9076                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9077                             targetPackage == null);
9078                     if (perm.modeFlags == 0) {
9079                         perms.removeAt(j);
9080                     }
9081                 }
9082             }
9083
9084             if (perms.isEmpty()) {
9085                 mGrantedUriPermissions.removeAt(i);
9086             }
9087         }
9088
9089         if (persistChanged) {
9090             schedulePersistUriGrants();
9091         }
9092     }
9093
9094     /**
9095      * @param uri This uri must NOT contain an embedded userId.
9096      * @param userId The userId in which the uri is to be resolved.
9097      */
9098     @Override
9099     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9100             final int modeFlags, int userId) {
9101         enforceNotIsolatedCaller("revokeUriPermission");
9102         synchronized(this) {
9103             final ProcessRecord r = getRecordForAppLocked(caller);
9104             if (r == null) {
9105                 throw new SecurityException("Unable to find app for caller "
9106                         + caller
9107                         + " when revoking permission to uri " + uri);
9108             }
9109             if (uri == null) {
9110                 Slog.w(TAG, "revokeUriPermission: null uri");
9111                 return;
9112             }
9113
9114             if (!Intent.isAccessUriMode(modeFlags)) {
9115                 return;
9116             }
9117
9118             final String authority = uri.getAuthority();
9119             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9120                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9121             if (pi == null) {
9122                 Slog.w(TAG, "No content provider found for permission revoke: "
9123                         + uri.toSafeString());
9124                 return;
9125             }
9126
9127             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9128                     modeFlags);
9129         }
9130     }
9131
9132     /**
9133      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9134      * given package.
9135      *
9136      * @param packageName Package name to match, or {@code null} to apply to all
9137      *            packages.
9138      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9139      *            to all users.
9140      * @param persistable If persistable grants should be removed.
9141      */
9142     private void removeUriPermissionsForPackageLocked(
9143             String packageName, int userHandle, boolean persistable) {
9144         if (userHandle == UserHandle.USER_ALL && packageName == null) {
9145             throw new IllegalArgumentException("Must narrow by either package or user");
9146         }
9147
9148         boolean persistChanged = false;
9149
9150         int N = mGrantedUriPermissions.size();
9151         for (int i = 0; i < N; i++) {
9152             final int targetUid = mGrantedUriPermissions.keyAt(i);
9153             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9154
9155             // Only inspect grants matching user
9156             if (userHandle == UserHandle.USER_ALL
9157                     || userHandle == UserHandle.getUserId(targetUid)) {
9158                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9159                     final UriPermission perm = it.next();
9160
9161                     // Only inspect grants matching package
9162                     if (packageName == null || perm.sourcePkg.equals(packageName)
9163                             || perm.targetPkg.equals(packageName)) {
9164                         // Hacky solution as part of fixing a security bug; ignore
9165                         // grants associated with DownloadManager so we don't have
9166                         // to immediately launch it to regrant the permissions
9167                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9168                                 && !persistable) continue;
9169
9170                         persistChanged |= perm.revokeModes(persistable
9171                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9172
9173                         // Only remove when no modes remain; any persisted grants
9174                         // will keep this alive.
9175                         if (perm.modeFlags == 0) {
9176                             it.remove();
9177                         }
9178                     }
9179                 }
9180
9181                 if (perms.isEmpty()) {
9182                     mGrantedUriPermissions.remove(targetUid);
9183                     N--;
9184                     i--;
9185                 }
9186             }
9187         }
9188
9189         if (persistChanged) {
9190             schedulePersistUriGrants();
9191         }
9192     }
9193
9194     @Override
9195     public IBinder newUriPermissionOwner(String name) {
9196         enforceNotIsolatedCaller("newUriPermissionOwner");
9197         synchronized(this) {
9198             UriPermissionOwner owner = new UriPermissionOwner(this, name);
9199             return owner.getExternalTokenLocked();
9200         }
9201     }
9202
9203     @Override
9204     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9205         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9206         synchronized(this) {
9207             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9208             if (r == null) {
9209                 throw new IllegalArgumentException("Activity does not exist; token="
9210                         + activityToken);
9211             }
9212             return r.getUriPermissionsLocked().getExternalTokenLocked();
9213         }
9214     }
9215     /**
9216      * @param uri This uri must NOT contain an embedded userId.
9217      * @param sourceUserId The userId in which the uri is to be resolved.
9218      * @param targetUserId The userId of the app that receives the grant.
9219      */
9220     @Override
9221     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9222             final int modeFlags, int sourceUserId, int targetUserId) {
9223         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9224                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9225                 "grantUriPermissionFromOwner", null);
9226         synchronized(this) {
9227             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9228             if (owner == null) {
9229                 throw new IllegalArgumentException("Unknown owner: " + token);
9230             }
9231             if (fromUid != Binder.getCallingUid()) {
9232                 if (Binder.getCallingUid() != myUid()) {
9233                     // Only system code can grant URI permissions on behalf
9234                     // of other users.
9235                     throw new SecurityException("nice try");
9236                 }
9237             }
9238             if (targetPkg == null) {
9239                 throw new IllegalArgumentException("null target");
9240             }
9241             if (uri == null) {
9242                 throw new IllegalArgumentException("null uri");
9243             }
9244
9245             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9246                     modeFlags, owner, targetUserId);
9247         }
9248     }
9249
9250     /**
9251      * @param uri This uri must NOT contain an embedded userId.
9252      * @param userId The userId in which the uri is to be resolved.
9253      */
9254     @Override
9255     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9256         synchronized(this) {
9257             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9258             if (owner == null) {
9259                 throw new IllegalArgumentException("Unknown owner: " + token);
9260             }
9261
9262             if (uri == null) {
9263                 owner.removeUriPermissionsLocked(mode);
9264             } else {
9265                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9266                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9267             }
9268         }
9269     }
9270
9271     private void schedulePersistUriGrants() {
9272         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9273             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9274                     10 * DateUtils.SECOND_IN_MILLIS);
9275         }
9276     }
9277
9278     private void writeGrantedUriPermissions() {
9279         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9280
9281         // Snapshot permissions so we can persist without lock
9282         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9283         synchronized (this) {
9284             final int size = mGrantedUriPermissions.size();
9285             for (int i = 0; i < size; i++) {
9286                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9287                 for (UriPermission perm : perms.values()) {
9288                     if (perm.persistedModeFlags != 0) {
9289                         persist.add(perm.snapshot());
9290                     }
9291                 }
9292             }
9293         }
9294
9295         FileOutputStream fos = null;
9296         try {
9297             fos = mGrantFile.startWrite();
9298
9299             XmlSerializer out = new FastXmlSerializer();
9300             out.setOutput(fos, StandardCharsets.UTF_8.name());
9301             out.startDocument(null, true);
9302             out.startTag(null, TAG_URI_GRANTS);
9303             for (UriPermission.Snapshot perm : persist) {
9304                 out.startTag(null, TAG_URI_GRANT);
9305                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9306                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9307                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9308                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9309                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9310                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9311                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9312                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9313                 out.endTag(null, TAG_URI_GRANT);
9314             }
9315             out.endTag(null, TAG_URI_GRANTS);
9316             out.endDocument();
9317
9318             mGrantFile.finishWrite(fos);
9319         } catch (IOException e) {
9320             if (fos != null) {
9321                 mGrantFile.failWrite(fos);
9322             }
9323         }
9324     }
9325
9326     private void readGrantedUriPermissionsLocked() {
9327         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9328
9329         final long now = System.currentTimeMillis();
9330
9331         FileInputStream fis = null;
9332         try {
9333             fis = mGrantFile.openRead();
9334             final XmlPullParser in = Xml.newPullParser();
9335             in.setInput(fis, StandardCharsets.UTF_8.name());
9336
9337             int type;
9338             while ((type = in.next()) != END_DOCUMENT) {
9339                 final String tag = in.getName();
9340                 if (type == START_TAG) {
9341                     if (TAG_URI_GRANT.equals(tag)) {
9342                         final int sourceUserId;
9343                         final int targetUserId;
9344                         final int userHandle = readIntAttribute(in,
9345                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9346                         if (userHandle != UserHandle.USER_NULL) {
9347                             // For backwards compatibility.
9348                             sourceUserId = userHandle;
9349                             targetUserId = userHandle;
9350                         } else {
9351                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9352                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9353                         }
9354                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9355                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9356                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9357                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9358                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9359                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9360
9361                         // Sanity check that provider still belongs to source package
9362                         // Both direct boot aware and unaware packages are fine as we
9363                         // will do filtering at query time to avoid multiple parsing.
9364                         final ProviderInfo pi = getProviderInfoLocked(
9365                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9366                                         | MATCH_DIRECT_BOOT_UNAWARE);
9367                         if (pi != null && sourcePkg.equals(pi.packageName)) {
9368                             int targetUid = -1;
9369                             try {
9370                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
9371                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9372                             } catch (RemoteException e) {
9373                             }
9374                             if (targetUid != -1) {
9375                                 final UriPermission perm = findOrCreateUriPermissionLocked(
9376                                         sourcePkg, targetPkg, targetUid,
9377                                         new GrantUri(sourceUserId, uri, prefix));
9378                                 perm.initPersistedModes(modeFlags, createdTime);
9379                             }
9380                         } else {
9381                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9382                                     + " but instead found " + pi);
9383                         }
9384                     }
9385                 }
9386             }
9387         } catch (FileNotFoundException e) {
9388             // Missing grants is okay
9389         } catch (IOException e) {
9390             Slog.wtf(TAG, "Failed reading Uri grants", e);
9391         } catch (XmlPullParserException e) {
9392             Slog.wtf(TAG, "Failed reading Uri grants", e);
9393         } finally {
9394             IoUtils.closeQuietly(fis);
9395         }
9396     }
9397
9398     /**
9399      * @param uri This uri must NOT contain an embedded userId.
9400      * @param userId The userId in which the uri is to be resolved.
9401      */
9402     @Override
9403     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9404         enforceNotIsolatedCaller("takePersistableUriPermission");
9405
9406         Preconditions.checkFlagsArgument(modeFlags,
9407                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9408
9409         synchronized (this) {
9410             final int callingUid = Binder.getCallingUid();
9411             boolean persistChanged = false;
9412             GrantUri grantUri = new GrantUri(userId, uri, false);
9413
9414             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9415                     new GrantUri(userId, uri, false));
9416             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9417                     new GrantUri(userId, uri, true));
9418
9419             final boolean exactValid = (exactPerm != null)
9420                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9421             final boolean prefixValid = (prefixPerm != null)
9422                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9423
9424             if (!(exactValid || prefixValid)) {
9425                 throw new SecurityException("No persistable permission grants found for UID "
9426                         + callingUid + " and Uri " + grantUri.toSafeString());
9427             }
9428
9429             if (exactValid) {
9430                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9431             }
9432             if (prefixValid) {
9433                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9434             }
9435
9436             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9437
9438             if (persistChanged) {
9439                 schedulePersistUriGrants();
9440             }
9441         }
9442     }
9443
9444     /**
9445      * @param uri This uri must NOT contain an embedded userId.
9446      * @param userId The userId in which the uri is to be resolved.
9447      */
9448     @Override
9449     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9450         enforceNotIsolatedCaller("releasePersistableUriPermission");
9451
9452         Preconditions.checkFlagsArgument(modeFlags,
9453                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9454
9455         synchronized (this) {
9456             final int callingUid = Binder.getCallingUid();
9457             boolean persistChanged = false;
9458
9459             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9460                     new GrantUri(userId, uri, false));
9461             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9462                     new GrantUri(userId, uri, true));
9463             if (exactPerm == null && prefixPerm == null) {
9464                 throw new SecurityException("No permission grants found for UID " + callingUid
9465                         + " and Uri " + uri.toSafeString());
9466             }
9467
9468             if (exactPerm != null) {
9469                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9470                 removeUriPermissionIfNeededLocked(exactPerm);
9471             }
9472             if (prefixPerm != null) {
9473                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9474                 removeUriPermissionIfNeededLocked(prefixPerm);
9475             }
9476
9477             if (persistChanged) {
9478                 schedulePersistUriGrants();
9479             }
9480         }
9481     }
9482
9483     /**
9484      * Prune any older {@link UriPermission} for the given UID until outstanding
9485      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9486      *
9487      * @return if any mutations occured that require persisting.
9488      */
9489     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9490         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9491         if (perms == null) return false;
9492         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9493
9494         final ArrayList<UriPermission> persisted = Lists.newArrayList();
9495         for (UriPermission perm : perms.values()) {
9496             if (perm.persistedModeFlags != 0) {
9497                 persisted.add(perm);
9498             }
9499         }
9500
9501         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9502         if (trimCount <= 0) return false;
9503
9504         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9505         for (int i = 0; i < trimCount; i++) {
9506             final UriPermission perm = persisted.get(i);
9507
9508             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9509                     "Trimming grant created at " + perm.persistedCreateTime);
9510
9511             perm.releasePersistableModes(~0);
9512             removeUriPermissionIfNeededLocked(perm);
9513         }
9514
9515         return true;
9516     }
9517
9518     @Override
9519     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9520             String packageName, boolean incoming) {
9521         enforceNotIsolatedCaller("getPersistedUriPermissions");
9522         Preconditions.checkNotNull(packageName, "packageName");
9523
9524         final int callingUid = Binder.getCallingUid();
9525         final int callingUserId = UserHandle.getUserId(callingUid);
9526         final IPackageManager pm = AppGlobals.getPackageManager();
9527         try {
9528             final int packageUid = pm.getPackageUid(packageName,
9529                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9530             if (packageUid != callingUid) {
9531                 throw new SecurityException(
9532                         "Package " + packageName + " does not belong to calling UID " + callingUid);
9533             }
9534         } catch (RemoteException e) {
9535             throw new SecurityException("Failed to verify package name ownership");
9536         }
9537
9538         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9539         synchronized (this) {
9540             if (incoming) {
9541                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9542                         callingUid);
9543                 if (perms == null) {
9544                     Slog.w(TAG, "No permission grants found for " + packageName);
9545                 } else {
9546                     for (UriPermission perm : perms.values()) {
9547                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9548                             result.add(perm.buildPersistedPublicApiObject());
9549                         }
9550                     }
9551                 }
9552             } else {
9553                 final int size = mGrantedUriPermissions.size();
9554                 for (int i = 0; i < size; i++) {
9555                     final ArrayMap<GrantUri, UriPermission> perms =
9556                             mGrantedUriPermissions.valueAt(i);
9557                     for (UriPermission perm : perms.values()) {
9558                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9559                             result.add(perm.buildPersistedPublicApiObject());
9560                         }
9561                     }
9562                 }
9563             }
9564         }
9565         return new ParceledListSlice<android.content.UriPermission>(result);
9566     }
9567
9568     @Override
9569     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9570             String packageName, int userId) {
9571         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9572                 "getGrantedUriPermissions");
9573
9574         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9575         synchronized (this) {
9576             final int size = mGrantedUriPermissions.size();
9577             for (int i = 0; i < size; i++) {
9578                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9579                 for (UriPermission perm : perms.values()) {
9580                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9581                             && perm.persistedModeFlags != 0) {
9582                         result.add(perm.buildPersistedPublicApiObject());
9583                     }
9584                 }
9585             }
9586         }
9587         return new ParceledListSlice<android.content.UriPermission>(result);
9588     }
9589
9590     @Override
9591     public void clearGrantedUriPermissions(String packageName, int userId) {
9592         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9593                 "clearGrantedUriPermissions");
9594         removeUriPermissionsForPackageLocked(packageName, userId, true);
9595     }
9596
9597     @Override
9598     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9599         synchronized (this) {
9600             ProcessRecord app =
9601                 who != null ? getRecordForAppLocked(who) : null;
9602             if (app == null) return;
9603
9604             Message msg = Message.obtain();
9605             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9606             msg.obj = app;
9607             msg.arg1 = waiting ? 1 : 0;
9608             mUiHandler.sendMessage(msg);
9609         }
9610     }
9611
9612     @Override
9613     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9614         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9615         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9616         outInfo.availMem = getFreeMemory();
9617         outInfo.totalMem = getTotalMemory();
9618         outInfo.threshold = homeAppMem;
9619         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9620         outInfo.hiddenAppThreshold = cachedAppMem;
9621         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9622                 ProcessList.SERVICE_ADJ);
9623         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9624                 ProcessList.VISIBLE_APP_ADJ);
9625         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9626                 ProcessList.FOREGROUND_APP_ADJ);
9627     }
9628
9629     // =========================================================
9630     // TASK MANAGEMENT
9631     // =========================================================
9632
9633     @Override
9634     public List<IBinder> getAppTasks(String callingPackage) {
9635         int callingUid = Binder.getCallingUid();
9636         long ident = Binder.clearCallingIdentity();
9637
9638         synchronized(this) {
9639             ArrayList<IBinder> list = new ArrayList<IBinder>();
9640             try {
9641                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9642
9643                 final int N = mRecentTasks.size();
9644                 for (int i = 0; i < N; i++) {
9645                     TaskRecord tr = mRecentTasks.get(i);
9646                     // Skip tasks that do not match the caller.  We don't need to verify
9647                     // callingPackage, because we are also limiting to callingUid and know
9648                     // that will limit to the correct security sandbox.
9649                     if (tr.effectiveUid != callingUid) {
9650                         continue;
9651                     }
9652                     Intent intent = tr.getBaseIntent();
9653                     if (intent == null ||
9654                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9655                         continue;
9656                     }
9657                     ActivityManager.RecentTaskInfo taskInfo =
9658                             createRecentTaskInfoFromTaskRecord(tr);
9659                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9660                     list.add(taskImpl.asBinder());
9661                 }
9662             } finally {
9663                 Binder.restoreCallingIdentity(ident);
9664             }
9665             return list;
9666         }
9667     }
9668
9669     @Override
9670     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9671         final int callingUid = Binder.getCallingUid();
9672         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9673
9674         synchronized(this) {
9675             if (DEBUG_ALL) Slog.v(
9676                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9677
9678             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9679                     callingUid);
9680
9681             // TODO: Improve with MRU list from all ActivityStacks.
9682             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9683         }
9684
9685         return list;
9686     }
9687
9688     /**
9689      * Creates a new RecentTaskInfo from a TaskRecord.
9690      */
9691     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9692         // Update the task description to reflect any changes in the task stack
9693         tr.updateTaskDescription();
9694
9695         // Compose the recent task info
9696         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9697         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9698         rti.persistentId = tr.taskId;
9699         rti.baseIntent = new Intent(tr.getBaseIntent());
9700         rti.origActivity = tr.origActivity;
9701         rti.realActivity = tr.realActivity;
9702         rti.description = tr.lastDescription;
9703         rti.stackId = tr.getStackId();
9704         rti.userId = tr.userId;
9705         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9706         rti.firstActiveTime = tr.firstActiveTime;
9707         rti.lastActiveTime = tr.lastActiveTime;
9708         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9709         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9710         rti.numActivities = 0;
9711         if (tr.mBounds != null) {
9712             rti.bounds = new Rect(tr.mBounds);
9713         }
9714         rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9715         rti.resizeMode = tr.mResizeMode;
9716
9717         ActivityRecord base = null;
9718         ActivityRecord top = null;
9719         ActivityRecord tmp;
9720
9721         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9722             tmp = tr.mActivities.get(i);
9723             if (tmp.finishing) {
9724                 continue;
9725             }
9726             base = tmp;
9727             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9728                 top = base;
9729             }
9730             rti.numActivities++;
9731         }
9732
9733         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9734         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9735
9736         return rti;
9737     }
9738
9739     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9740         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9741                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9742         if (!allowed) {
9743             if (checkPermission(android.Manifest.permission.GET_TASKS,
9744                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9745                 // Temporary compatibility: some existing apps on the system image may
9746                 // still be requesting the old permission and not switched to the new
9747                 // one; if so, we'll still allow them full access.  This means we need
9748                 // to see if they are holding the old permission and are a system app.
9749                 try {
9750                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9751                         allowed = true;
9752                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9753                                 + " is using old GET_TASKS but privileged; allowing");
9754                     }
9755                 } catch (RemoteException e) {
9756                 }
9757             }
9758         }
9759         if (!allowed) {
9760             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9761                     + " does not hold REAL_GET_TASKS; limiting output");
9762         }
9763         return allowed;
9764     }
9765
9766     @Override
9767     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9768             int userId) {
9769         final int callingUid = Binder.getCallingUid();
9770         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9771                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9772
9773         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9774         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9775         synchronized (this) {
9776             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9777                     callingUid);
9778             final boolean detailed = checkCallingPermission(
9779                     android.Manifest.permission.GET_DETAILED_TASKS)
9780                     == PackageManager.PERMISSION_GRANTED;
9781
9782             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9783                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9784                 return ParceledListSlice.emptyList();
9785             }
9786             mRecentTasks.loadUserRecentsLocked(userId);
9787
9788             final int recentsCount = mRecentTasks.size();
9789             ArrayList<ActivityManager.RecentTaskInfo> res =
9790                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9791
9792             final Set<Integer> includedUsers;
9793             if (includeProfiles) {
9794                 includedUsers = mUserController.getProfileIds(userId);
9795             } else {
9796                 includedUsers = new HashSet<>();
9797             }
9798             includedUsers.add(Integer.valueOf(userId));
9799
9800             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9801                 TaskRecord tr = mRecentTasks.get(i);
9802                 // Only add calling user or related users recent tasks
9803                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9804                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9805                     continue;
9806                 }
9807
9808                 if (tr.realActivitySuspended) {
9809                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9810                     continue;
9811                 }
9812
9813                 // Return the entry if desired by the caller.  We always return
9814                 // the first entry, because callers always expect this to be the
9815                 // foreground app.  We may filter others if the caller has
9816                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9817                 // we should exclude the entry.
9818
9819                 if (i == 0
9820                         || withExcluded
9821                         || (tr.intent == null)
9822                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9823                                 == 0)) {
9824                     if (!allowed) {
9825                         // If the caller doesn't have the GET_TASKS permission, then only
9826                         // allow them to see a small subset of tasks -- their own and home.
9827                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9828                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9829                             continue;
9830                         }
9831                     }
9832                     final ActivityStack stack = tr.getStack();
9833                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9834                         if (stack != null && stack.isHomeOrRecentsStack()) {
9835                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9836                                     "Skipping, home or recents stack task: " + tr);
9837                             continue;
9838                         }
9839                     }
9840                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9841                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9842                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9843                                     "Skipping, top task in docked stack: " + tr);
9844                             continue;
9845                         }
9846                     }
9847                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9848                         if (stack != null && stack.isPinnedStack()) {
9849                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9850                                     "Skipping, pinned stack task: " + tr);
9851                             continue;
9852                         }
9853                     }
9854                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9855                         // Don't include auto remove tasks that are finished or finishing.
9856                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9857                                 "Skipping, auto-remove without activity: " + tr);
9858                         continue;
9859                     }
9860                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9861                             && !tr.isAvailable) {
9862                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9863                                 "Skipping, unavail real act: " + tr);
9864                         continue;
9865                     }
9866
9867                     if (!tr.mUserSetupComplete) {
9868                         // Don't include task launched while user is not done setting-up.
9869                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9870                                 "Skipping, user setup not complete: " + tr);
9871                         continue;
9872                     }
9873
9874                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9875                     if (!detailed) {
9876                         rti.baseIntent.replaceExtras((Bundle)null);
9877                     }
9878
9879                     res.add(rti);
9880                     maxNum--;
9881                 }
9882             }
9883             return new ParceledListSlice<>(res);
9884         }
9885     }
9886
9887     @Override
9888     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9889         synchronized (this) {
9890             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9891                     "getTaskThumbnail()");
9892             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9893                     id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9894             if (tr != null) {
9895                 return tr.getTaskThumbnailLocked();
9896             }
9897         }
9898         return null;
9899     }
9900
9901     @Override
9902     public ActivityManager.TaskDescription getTaskDescription(int id) {
9903         synchronized (this) {
9904             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9905                     "getTaskDescription()");
9906             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9907                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9908             if (tr != null) {
9909                 return tr.lastTaskDescription;
9910             }
9911         }
9912         return null;
9913     }
9914
9915     @Override
9916     public int addAppTask(IBinder activityToken, Intent intent,
9917             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9918         final int callingUid = Binder.getCallingUid();
9919         final long callingIdent = Binder.clearCallingIdentity();
9920
9921         try {
9922             synchronized (this) {
9923                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9924                 if (r == null) {
9925                     throw new IllegalArgumentException("Activity does not exist; token="
9926                             + activityToken);
9927                 }
9928                 ComponentName comp = intent.getComponent();
9929                 if (comp == null) {
9930                     throw new IllegalArgumentException("Intent " + intent
9931                             + " must specify explicit component");
9932                 }
9933                 if (thumbnail.getWidth() != mThumbnailWidth
9934                         || thumbnail.getHeight() != mThumbnailHeight) {
9935                     throw new IllegalArgumentException("Bad thumbnail size: got "
9936                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9937                             + mThumbnailWidth + "x" + mThumbnailHeight);
9938                 }
9939                 if (intent.getSelector() != null) {
9940                     intent.setSelector(null);
9941                 }
9942                 if (intent.getSourceBounds() != null) {
9943                     intent.setSourceBounds(null);
9944                 }
9945                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9946                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9947                         // The caller has added this as an auto-remove task...  that makes no
9948                         // sense, so turn off auto-remove.
9949                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9950                     }
9951                 }
9952                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9953                     mLastAddedTaskActivity = null;
9954                 }
9955                 ActivityInfo ainfo = mLastAddedTaskActivity;
9956                 if (ainfo == null) {
9957                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9958                             comp, 0, UserHandle.getUserId(callingUid));
9959                     if (ainfo.applicationInfo.uid != callingUid) {
9960                         throw new SecurityException(
9961                                 "Can't add task for another application: target uid="
9962                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9963                     }
9964                 }
9965
9966                 TaskRecord task = new TaskRecord(this,
9967                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9968                         ainfo, intent, description, new TaskThumbnailInfo());
9969
9970                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9971                 if (trimIdx >= 0) {
9972                     // If this would have caused a trim, then we'll abort because that
9973                     // means it would be added at the end of the list but then just removed.
9974                     return INVALID_TASK_ID;
9975                 }
9976
9977                 final int N = mRecentTasks.size();
9978                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9979                     final TaskRecord tr = mRecentTasks.remove(N - 1);
9980                     tr.removedFromRecents();
9981                 }
9982
9983                 task.inRecents = true;
9984                 mRecentTasks.add(task);
9985                 r.getStack().addTask(task, false, "addAppTask");
9986
9987                 task.setLastThumbnailLocked(thumbnail);
9988                 task.freeLastThumbnail();
9989                 return task.taskId;
9990             }
9991         } finally {
9992             Binder.restoreCallingIdentity(callingIdent);
9993         }
9994     }
9995
9996     @Override
9997     public Point getAppTaskThumbnailSize() {
9998         synchronized (this) {
9999             return new Point(mThumbnailWidth,  mThumbnailHeight);
10000         }
10001     }
10002
10003     @Override
10004     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10005         synchronized (this) {
10006             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10007             if (r != null) {
10008                 r.setTaskDescription(td);
10009                 final TaskRecord task = r.getTask();
10010                 task.updateTaskDescription();
10011                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10012             }
10013         }
10014     }
10015
10016     @Override
10017     public void setTaskResizeable(int taskId, int resizeableMode) {
10018         synchronized (this) {
10019             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10020                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10021             if (task == null) {
10022                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10023                 return;
10024             }
10025             task.setResizeMode(resizeableMode);
10026         }
10027     }
10028
10029     @Override
10030     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10031         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10032         long ident = Binder.clearCallingIdentity();
10033         try {
10034             synchronized (this) {
10035                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10036                 if (task == null) {
10037                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10038                     return;
10039                 }
10040                 // Place the task in the right stack if it isn't there already based on
10041                 // the requested bounds.
10042                 // The stack transition logic is:
10043                 // - a null bounds on a freeform task moves that task to fullscreen
10044                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10045                 //   that task to freeform
10046                 // - otherwise the task is not moved
10047                 int stackId = task.getStackId();
10048                 if (!StackId.isTaskResizeAllowed(stackId)) {
10049                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10050                 }
10051                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10052                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10053                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10054                     stackId = FREEFORM_WORKSPACE_STACK_ID;
10055                 }
10056
10057                 // Reparent the task to the right stack if necessary
10058                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10059                 if (stackId != task.getStackId()) {
10060                     // Defer resume until the task is resized below
10061                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10062                             DEFER_RESUME, "resizeTask");
10063                     preserveWindow = false;
10064                 }
10065
10066                 // After reparenting (which only resizes the task to the stack bounds), resize the
10067                 // task to the actual bounds provided
10068                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10069             }
10070         } finally {
10071             Binder.restoreCallingIdentity(ident);
10072         }
10073     }
10074
10075     @Override
10076     public Rect getTaskBounds(int taskId) {
10077         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10078         long ident = Binder.clearCallingIdentity();
10079         Rect rect = new Rect();
10080         try {
10081             synchronized (this) {
10082                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10083                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10084                 if (task == null) {
10085                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10086                     return rect;
10087                 }
10088                 if (task.getStack() != null) {
10089                     // Return the bounds from window manager since it will be adjusted for various
10090                     // things like the presense of a docked stack for tasks that aren't resizeable.
10091                     task.getWindowContainerBounds(rect);
10092                 } else {
10093                     // Task isn't in window manager yet since it isn't associated with a stack.
10094                     // Return the persist value from activity manager
10095                     if (task.mBounds != null) {
10096                         rect.set(task.mBounds);
10097                     } else if (task.mLastNonFullscreenBounds != null) {
10098                         rect.set(task.mLastNonFullscreenBounds);
10099                     }
10100                 }
10101             }
10102         } finally {
10103             Binder.restoreCallingIdentity(ident);
10104         }
10105         return rect;
10106     }
10107
10108     @Override
10109     public void cancelTaskWindowTransition(int taskId) {
10110         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10111         final long ident = Binder.clearCallingIdentity();
10112         try {
10113             synchronized (this) {
10114                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10115                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10116                 if (task == null) {
10117                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10118                     return;
10119                 }
10120                 task.cancelWindowTransition();
10121             }
10122         } finally {
10123             Binder.restoreCallingIdentity(ident);
10124         }
10125     }
10126
10127     @Override
10128     public void cancelTaskThumbnailTransition(int taskId) {
10129         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10130         final long ident = Binder.clearCallingIdentity();
10131         try {
10132             synchronized (this) {
10133                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10134                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10135                 if (task == null) {
10136                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10137                     return;
10138                 }
10139                 task.cancelThumbnailTransition();
10140             }
10141         } finally {
10142             Binder.restoreCallingIdentity(ident);
10143         }
10144     }
10145
10146     @Override
10147     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10148         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10149         final long ident = Binder.clearCallingIdentity();
10150         try {
10151             final TaskRecord task;
10152             synchronized (this) {
10153                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10154                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10155                 if (task == null) {
10156                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10157                     return null;
10158                 }
10159             }
10160             // Don't call this while holding the lock as this operation might hit the disk.
10161             return task.getSnapshot(reducedResolution);
10162         } finally {
10163             Binder.restoreCallingIdentity(ident);
10164         }
10165     }
10166
10167     @Override
10168     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10169         if (userId != UserHandle.getCallingUserId()) {
10170             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10171                     "getTaskDescriptionIcon");
10172         }
10173         final File passedIconFile = new File(filePath);
10174         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10175                 passedIconFile.getName());
10176         if (!legitIconFile.getPath().equals(filePath)
10177                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10178             throw new IllegalArgumentException("Bad file path: " + filePath
10179                     + " passed for userId " + userId);
10180         }
10181         return mRecentTasks.getTaskDescriptionIcon(filePath);
10182     }
10183
10184     @Override
10185     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10186             throws RemoteException {
10187         final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10188         if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10189                 activityOptions.getCustomInPlaceResId() == 0) {
10190             throw new IllegalArgumentException("Expected in-place ActivityOption " +
10191                     "with valid animation");
10192         }
10193         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10194         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10195                 activityOptions.getCustomInPlaceResId());
10196         mWindowManager.executeAppTransition();
10197     }
10198
10199     private void removeTasksByPackageNameLocked(String packageName, int userId) {
10200         // Remove all tasks with activities in the specified package from the list of recent tasks
10201         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10202             TaskRecord tr = mRecentTasks.get(i);
10203             if (tr.userId != userId) continue;
10204
10205             ComponentName cn = tr.intent.getComponent();
10206             if (cn != null && cn.getPackageName().equals(packageName)) {
10207                 // If the package name matches, remove the task.
10208                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10209             }
10210         }
10211     }
10212
10213     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10214             int userId) {
10215
10216         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10217             TaskRecord tr = mRecentTasks.get(i);
10218             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10219                 continue;
10220             }
10221
10222             ComponentName cn = tr.intent.getComponent();
10223             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10224                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10225             if (sameComponent) {
10226                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10227             }
10228         }
10229     }
10230
10231     @Override
10232     public void removeStack(int stackId) {
10233         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10234         if (StackId.isHomeOrRecentsStack(stackId)) {
10235             throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10236         }
10237
10238         synchronized (this) {
10239             final long ident = Binder.clearCallingIdentity();
10240             try {
10241                 mStackSupervisor.removeStackLocked(stackId);
10242             } finally {
10243                 Binder.restoreCallingIdentity(ident);
10244             }
10245         }
10246     }
10247
10248     @Override
10249     public void moveStackToDisplay(int stackId, int displayId) {
10250         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10251
10252         synchronized (this) {
10253             final long ident = Binder.clearCallingIdentity();
10254             try {
10255                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10256                         + " to displayId=" + displayId);
10257                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10258             } finally {
10259                 Binder.restoreCallingIdentity(ident);
10260             }
10261         }
10262     }
10263
10264     @Override
10265     public boolean removeTask(int taskId) {
10266         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10267         synchronized (this) {
10268             final long ident = Binder.clearCallingIdentity();
10269             try {
10270                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10271             } finally {
10272                 Binder.restoreCallingIdentity(ident);
10273             }
10274         }
10275     }
10276
10277     /**
10278      * TODO: Add mController hook
10279      */
10280     @Override
10281     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10282         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10283
10284         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10285         synchronized(this) {
10286             moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10287         }
10288     }
10289
10290     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10291         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10292
10293         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10294                 Binder.getCallingUid(), -1, -1, "Task to front")) {
10295             ActivityOptions.abort(options);
10296             return;
10297         }
10298         final long origId = Binder.clearCallingIdentity();
10299         try {
10300             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10301             if (task == null) {
10302                 Slog.d(TAG, "Could not find task for id: "+ taskId);
10303                 return;
10304             }
10305             if (mStackSupervisor.isLockTaskModeViolation(task)) {
10306                 mStackSupervisor.showLockTaskToast();
10307                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10308                 return;
10309             }
10310             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10311             if (prev != null) {
10312                 task.setTaskToReturnTo(prev);
10313             }
10314             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10315                     false /* forceNonResizable */);
10316
10317             final ActivityRecord topActivity = task.getTopActivity();
10318             if (topActivity != null) {
10319
10320                 // We are reshowing a task, use a starting window to hide the initial draw delay
10321                 // so the transition can start earlier.
10322                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10323                         true /* taskSwitch */, fromRecents);
10324             }
10325         } finally {
10326             Binder.restoreCallingIdentity(origId);
10327         }
10328         ActivityOptions.abort(options);
10329     }
10330
10331     /**
10332      * Attempts to move a task backwards in z-order (the order of activities within the task is
10333      * unchanged).
10334      *
10335      * There are several possible results of this call:
10336      * - if the task is locked, then we will show the lock toast
10337      * - if there is a task behind the provided task, then that task is made visible and resumed as
10338      *   this task is moved to the back
10339      * - otherwise, if there are no other tasks in the stack:
10340      *     - if this task is in the pinned stack, then we remove the stack completely, which will
10341      *       have the effect of moving the task to the top or bottom of the fullscreen stack
10342      *       (depending on whether it is visible)
10343      *     - otherwise, we simply return home and hide this task
10344      *
10345      * @param token A reference to the activity we wish to move
10346      * @param nonRoot If false then this only works if the activity is the root
10347      *                of a task; if true it will work for any activity in a task.
10348      * @return Returns true if the move completed, false if not.
10349      */
10350     @Override
10351     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10352         enforceNotIsolatedCaller("moveActivityTaskToBack");
10353         synchronized(this) {
10354             final long origId = Binder.clearCallingIdentity();
10355             try {
10356                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10357                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10358                 if (task != null) {
10359                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10360                 }
10361             } finally {
10362                 Binder.restoreCallingIdentity(origId);
10363             }
10364         }
10365         return false;
10366     }
10367
10368     @Override
10369     public void moveTaskBackwards(int task) {
10370         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10371                 "moveTaskBackwards()");
10372
10373         synchronized(this) {
10374             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10375                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
10376                 return;
10377             }
10378             final long origId = Binder.clearCallingIdentity();
10379             moveTaskBackwardsLocked(task);
10380             Binder.restoreCallingIdentity(origId);
10381         }
10382     }
10383
10384     private final void moveTaskBackwardsLocked(int task) {
10385         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10386     }
10387
10388     @Override
10389     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10390             IActivityContainerCallback callback) throws RemoteException {
10391         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10392         synchronized (this) {
10393             if (parentActivityToken == null) {
10394                 throw new IllegalArgumentException("parent token must not be null");
10395             }
10396             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10397             if (r == null) {
10398                 return null;
10399             }
10400             if (callback == null) {
10401                 throw new IllegalArgumentException("callback must not be null");
10402             }
10403             return mStackSupervisor.createVirtualActivityContainer(r, callback);
10404         }
10405     }
10406
10407     @Override
10408     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10409         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10410         synchronized (this) {
10411             final int stackId = mStackSupervisor.getNextStackId();
10412             final ActivityStack stack =
10413                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10414             if (stack == null) {
10415                 return null;
10416             }
10417             return stack.mActivityContainer;
10418         }
10419     }
10420
10421     @Override
10422     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10423         synchronized (this) {
10424             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10425             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10426                 return stack.mActivityContainer.getDisplayId();
10427             }
10428             return DEFAULT_DISPLAY;
10429         }
10430     }
10431
10432     @Override
10433     public int getActivityStackId(IBinder token) throws RemoteException {
10434         synchronized (this) {
10435             ActivityStack stack = ActivityRecord.getStackLocked(token);
10436             if (stack == null) {
10437                 return INVALID_STACK_ID;
10438             }
10439             return stack.mStackId;
10440         }
10441     }
10442
10443     @Override
10444     public void exitFreeformMode(IBinder token) throws RemoteException {
10445         synchronized (this) {
10446             long ident = Binder.clearCallingIdentity();
10447             try {
10448                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10449                 if (r == null) {
10450                     throw new IllegalArgumentException(
10451                             "exitFreeformMode: No activity record matching token=" + token);
10452                 }
10453
10454                 final ActivityStack stack = r.getStack();
10455                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10456                     throw new IllegalStateException(
10457                             "exitFreeformMode: You can only go fullscreen from freeform.");
10458                 }
10459
10460                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10461                 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10462                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10463             } finally {
10464                 Binder.restoreCallingIdentity(ident);
10465             }
10466         }
10467     }
10468
10469     @Override
10470     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10471         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10472         if (StackId.isHomeOrRecentsStack(stackId)) {
10473             throw new IllegalArgumentException(
10474                     "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10475         }
10476         synchronized (this) {
10477             long ident = Binder.clearCallingIdentity();
10478             try {
10479                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10480                 if (task == null) {
10481                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10482                     return;
10483                 }
10484
10485                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10486                         + " to stackId=" + stackId + " toTop=" + toTop);
10487                 if (stackId == DOCKED_STACK_ID) {
10488                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10489                             null /* initialBounds */);
10490                 }
10491                 task.reparent(stackId, toTop,
10492                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10493             } finally {
10494                 Binder.restoreCallingIdentity(ident);
10495             }
10496         }
10497     }
10498
10499     @Override
10500     public void swapDockedAndFullscreenStack() throws RemoteException {
10501         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10502         synchronized (this) {
10503             long ident = Binder.clearCallingIdentity();
10504             try {
10505                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10506                         FULLSCREEN_WORKSPACE_STACK_ID);
10507                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10508                         : null;
10509                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10510                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10511                         : null;
10512                 if (topTask == null || tasks == null || tasks.size() == 0) {
10513                     Slog.w(TAG,
10514                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
10515                     return;
10516                 }
10517
10518                 // TODO: App transition
10519                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10520
10521                 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10522                 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10523                         DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10524                 final int size = tasks.size();
10525                 for (int i = 0; i < size; i++) {
10526                     final int id = tasks.get(i).taskId;
10527                     if (id == topTask.taskId) {
10528                         continue;
10529                     }
10530
10531                     // Defer the resume until after all the tasks have been moved
10532                     tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10533                             REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10534                             "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10535                 }
10536
10537                 // Because we deferred the resume to avoid conflicts with stack switches while
10538                 // resuming, we need to do it after all the tasks are moved.
10539                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10540                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10541
10542                 mWindowManager.executeAppTransition();
10543             } finally {
10544                 Binder.restoreCallingIdentity(ident);
10545             }
10546         }
10547     }
10548
10549     /**
10550      * Moves the input task to the docked stack.
10551      *
10552      * @param taskId Id of task to move.
10553      * @param createMode The mode the docked stack should be created in if it doesn't exist
10554      *                   already. See
10555      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10556      *                   and
10557      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10558      * @param toTop If the task and stack should be moved to the top.
10559      * @param animate Whether we should play an animation for the moving the task
10560      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10561      *                      docked stack. Pass {@code null} to use default bounds.
10562      */
10563     @Override
10564     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10565             Rect initialBounds) {
10566         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10567         synchronized (this) {
10568             long ident = Binder.clearCallingIdentity();
10569             try {
10570                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10571                 if (task == null) {
10572                     Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10573                     return false;
10574                 }
10575
10576                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10577                         + " to createMode=" + createMode + " toTop=" + toTop);
10578                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10579
10580                 // Defer resuming until we move the home stack to the front below
10581                 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10582                         REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10583                         "moveTaskToDockedStack");
10584                 if (moved) {
10585                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10586                 }
10587                 return moved;
10588             } finally {
10589                 Binder.restoreCallingIdentity(ident);
10590             }
10591         }
10592     }
10593
10594     /**
10595      * Moves the top activity in the input stackId to the pinned stack.
10596      *
10597      * @param stackId Id of stack to move the top activity to pinned stack.
10598      * @param bounds Bounds to use for pinned stack.
10599      *
10600      * @return True if the top activity of the input stack was successfully moved to the pinned
10601      *          stack.
10602      */
10603     @Override
10604     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10605         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10606         synchronized (this) {
10607             if (!mSupportsPictureInPicture) {
10608                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10609                         + "Device doesn't support picture-in-picture mode");
10610             }
10611
10612             long ident = Binder.clearCallingIdentity();
10613             try {
10614                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10615             } finally {
10616                 Binder.restoreCallingIdentity(ident);
10617             }
10618         }
10619     }
10620
10621     @Override
10622     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10623             boolean preserveWindows, boolean animate, int animationDuration) {
10624         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10625         long ident = Binder.clearCallingIdentity();
10626         try {
10627             synchronized (this) {
10628                 if (animate) {
10629                     if (stackId == PINNED_STACK_ID) {
10630                         final PinnedActivityStack pinnedStack =
10631                                 mStackSupervisor.getStack(PINNED_STACK_ID);
10632                         if (pinnedStack != null) {
10633                             pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10634                                     destBounds, animationDuration, false /* fromFullscreen */);
10635                         }
10636                     } else {
10637                         throw new IllegalArgumentException("Stack: " + stackId
10638                                 + " doesn't support animated resize.");
10639                     }
10640                 } else {
10641                     mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10642                             null /* tempTaskInsetBounds */, preserveWindows,
10643                             allowResizeInDockedMode, !DEFER_RESUME);
10644                 }
10645             }
10646         } finally {
10647             Binder.restoreCallingIdentity(ident);
10648         }
10649     }
10650
10651     @Override
10652     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10653             Rect tempDockedTaskInsetBounds,
10654             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10655         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10656                 "resizeDockedStack()");
10657         long ident = Binder.clearCallingIdentity();
10658         try {
10659             synchronized (this) {
10660                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10661                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10662                         PRESERVE_WINDOWS);
10663             }
10664         } finally {
10665             Binder.restoreCallingIdentity(ident);
10666         }
10667     }
10668
10669     @Override
10670     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10671         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10672                 "resizePinnedStack()");
10673         final long ident = Binder.clearCallingIdentity();
10674         try {
10675             synchronized (this) {
10676                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10677             }
10678         } finally {
10679             Binder.restoreCallingIdentity(ident);
10680         }
10681     }
10682
10683     /**
10684      * Try to place task to provided position. The final position might be different depending on
10685      * current user and stacks state. The task will be moved to target stack if it's currently in
10686      * different stack.
10687      */
10688     @Override
10689     public void positionTaskInStack(int taskId, int stackId, int position) {
10690         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10691         if (StackId.isHomeOrRecentsStack(stackId)) {
10692             throw new IllegalArgumentException(
10693                     "positionTaskInStack: Attempt to change the position of task "
10694                     + taskId + " in/to home/recents stack");
10695         }
10696         synchronized (this) {
10697             long ident = Binder.clearCallingIdentity();
10698             try {
10699                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10700                         + taskId + " in stackId=" + stackId + " at position=" + position);
10701                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10702                 if (task == null) {
10703                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
10704                             + taskId);
10705                 }
10706
10707                 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10708                         !ON_TOP);
10709
10710                 // TODO: Have the callers of this API call a separate reparent method if that is
10711                 // what they intended to do vs. having this method also do reparenting.
10712                 if (task.getStack() == stack) {
10713                     // Change position in current stack.
10714                     stack.positionChildAt(task, position);
10715                 } else {
10716                     // Reparent to new stack.
10717                     task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10718                             !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10719                 }
10720             } finally {
10721                 Binder.restoreCallingIdentity(ident);
10722             }
10723         }
10724     }
10725
10726     @Override
10727     public List<StackInfo> getAllStackInfos() {
10728         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10729         long ident = Binder.clearCallingIdentity();
10730         try {
10731             synchronized (this) {
10732                 return mStackSupervisor.getAllStackInfosLocked();
10733             }
10734         } finally {
10735             Binder.restoreCallingIdentity(ident);
10736         }
10737     }
10738
10739     @Override
10740     public StackInfo getStackInfo(int stackId) {
10741         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10742         long ident = Binder.clearCallingIdentity();
10743         try {
10744             synchronized (this) {
10745                 return mStackSupervisor.getStackInfoLocked(stackId);
10746             }
10747         } finally {
10748             Binder.restoreCallingIdentity(ident);
10749         }
10750     }
10751
10752     @Override
10753     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10754         synchronized(this) {
10755             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10756         }
10757     }
10758
10759     @Override
10760     public void updateDeviceOwner(String packageName) {
10761         final int callingUid = Binder.getCallingUid();
10762         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10763             throw new SecurityException("updateDeviceOwner called from non-system process");
10764         }
10765         synchronized (this) {
10766             mDeviceOwnerName = packageName;
10767         }
10768     }
10769
10770     @Override
10771     public void updateLockTaskPackages(int userId, String[] packages) {
10772         final int callingUid = Binder.getCallingUid();
10773         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10774             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10775                     "updateLockTaskPackages()");
10776         }
10777         synchronized (this) {
10778             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10779                     Arrays.toString(packages));
10780             mLockTaskPackages.put(userId, packages);
10781             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10782         }
10783     }
10784
10785
10786     void startLockTaskModeLocked(TaskRecord task) {
10787         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10788         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10789             return;
10790         }
10791
10792         // When a task is locked, dismiss the pinned stack if it exists
10793         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10794                 PINNED_STACK_ID);
10795         if (pinnedStack != null) {
10796             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10797         }
10798
10799         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10800         // is initiated by system after the pinning request was shown and locked mode is initiated
10801         // by an authorized app directly
10802         final int callingUid = Binder.getCallingUid();
10803         boolean isSystemInitiated = callingUid == SYSTEM_UID;
10804         long ident = Binder.clearCallingIdentity();
10805         try {
10806             if (!isSystemInitiated) {
10807                 task.mLockTaskUid = callingUid;
10808                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10809                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10810                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10811                     StatusBarManagerInternal statusBarManager =
10812                             LocalServices.getService(StatusBarManagerInternal.class);
10813                     if (statusBarManager != null) {
10814                         statusBarManager.showScreenPinningRequest(task.taskId);
10815                     }
10816                     return;
10817                 }
10818
10819                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10820                 if (stack == null || task != stack.topTask()) {
10821                     throw new IllegalArgumentException("Invalid task, not in foreground");
10822                 }
10823             }
10824             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10825                     "Locking fully");
10826             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10827                     ActivityManager.LOCK_TASK_MODE_PINNED :
10828                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10829                     "startLockTask", true);
10830         } finally {
10831             Binder.restoreCallingIdentity(ident);
10832         }
10833     }
10834
10835     @Override
10836     public void startLockTaskModeById(int taskId) {
10837         synchronized (this) {
10838             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10839             if (task != null) {
10840                 startLockTaskModeLocked(task);
10841             }
10842         }
10843     }
10844
10845     @Override
10846     public void startLockTaskModeByToken(IBinder token) {
10847         synchronized (this) {
10848             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10849             if (r == null) {
10850                 return;
10851             }
10852             final TaskRecord task = r.getTask();
10853             if (task != null) {
10854                 startLockTaskModeLocked(task);
10855             }
10856         }
10857     }
10858
10859     @Override
10860     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10861         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10862         // This makes inner call to look as if it was initiated by system.
10863         long ident = Binder.clearCallingIdentity();
10864         try {
10865             synchronized (this) {
10866                 startLockTaskModeById(taskId);
10867             }
10868         } finally {
10869             Binder.restoreCallingIdentity(ident);
10870         }
10871     }
10872
10873     @Override
10874     public void stopLockTaskMode() {
10875         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10876         if (lockTask == null) {
10877             // Our work here is done.
10878             return;
10879         }
10880
10881         final int callingUid = Binder.getCallingUid();
10882         final int lockTaskUid = lockTask.mLockTaskUid;
10883         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10884         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10885             // Done.
10886             return;
10887         } else {
10888             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10889             // It is possible lockTaskMode was started by the system process because
10890             // android:lockTaskMode is set to a locking value in the application manifest
10891             // instead of the app calling startLockTaskMode. In this case
10892             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10893             // {@link TaskRecord.effectiveUid} instead. Also caller with
10894             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10895             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10896                     && callingUid != lockTaskUid
10897                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10898                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10899                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10900             }
10901         }
10902         long ident = Binder.clearCallingIdentity();
10903         try {
10904             Log.d(TAG, "stopLockTaskMode");
10905             // Stop lock task
10906             synchronized (this) {
10907                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10908                         "stopLockTask", true);
10909             }
10910             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10911             if (tm != null) {
10912                 tm.showInCallScreen(false);
10913             }
10914         } finally {
10915             Binder.restoreCallingIdentity(ident);
10916         }
10917     }
10918
10919     /**
10920      * This API should be called by SystemUI only when user perform certain action to dismiss
10921      * lock task mode. We should only dismiss pinned lock task mode in this case.
10922      */
10923     @Override
10924     public void stopSystemLockTaskMode() throws RemoteException {
10925         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10926             stopLockTaskMode();
10927         } else {
10928             mStackSupervisor.showLockTaskToast();
10929         }
10930     }
10931
10932     @Override
10933     public boolean isInLockTaskMode() {
10934         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10935     }
10936
10937     @Override
10938     public int getLockTaskModeState() {
10939         synchronized (this) {
10940             return mStackSupervisor.getLockTaskModeState();
10941         }
10942     }
10943
10944     @Override
10945     public void showLockTaskEscapeMessage(IBinder token) {
10946         synchronized (this) {
10947             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10948             if (r == null) {
10949                 return;
10950             }
10951             mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
10952         }
10953     }
10954
10955     @Override
10956     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
10957             throws RemoteException {
10958         synchronized (this) {
10959             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10960             if (r == null) {
10961                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
10962                         + token);
10963                 return;
10964             }
10965             final long origId = Binder.clearCallingIdentity();
10966             try {
10967                 r.setDisablePreviewScreenshots(disable);
10968             } finally {
10969                 Binder.restoreCallingIdentity(origId);
10970             }
10971         }
10972     }
10973
10974     // =========================================================
10975     // CONTENT PROVIDERS
10976     // =========================================================
10977
10978     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10979         List<ProviderInfo> providers = null;
10980         try {
10981             providers = AppGlobals.getPackageManager()
10982                     .queryContentProviders(app.processName, app.uid,
10983                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10984                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
10985                     .getList();
10986         } catch (RemoteException ex) {
10987         }
10988         if (DEBUG_MU) Slog.v(TAG_MU,
10989                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10990         int userId = app.userId;
10991         if (providers != null) {
10992             int N = providers.size();
10993             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10994             for (int i=0; i<N; i++) {
10995                 // TODO: keep logic in sync with installEncryptionUnawareProviders
10996                 ProviderInfo cpi =
10997                     (ProviderInfo)providers.get(i);
10998                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10999                         cpi.name, cpi.flags);
11000                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11001                     // This is a singleton provider, but a user besides the
11002                     // default user is asking to initialize a process it runs
11003                     // in...  well, no, it doesn't actually run in this process,
11004                     // it runs in the process of the default user.  Get rid of it.
11005                     providers.remove(i);
11006                     N--;
11007                     i--;
11008                     continue;
11009                 }
11010
11011                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11012                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11013                 if (cpr == null) {
11014                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11015                     mProviderMap.putProviderByClass(comp, cpr);
11016                 }
11017                 if (DEBUG_MU) Slog.v(TAG_MU,
11018                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11019                 app.pubProviders.put(cpi.name, cpr);
11020                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11021                     // Don't add this if it is a platform component that is marked
11022                     // to run in multiple processes, because this is actually
11023                     // part of the framework so doesn't make sense to track as a
11024                     // separate apk in the process.
11025                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11026                             mProcessStats);
11027                 }
11028                 notifyPackageUse(cpi.applicationInfo.packageName,
11029                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11030             }
11031         }
11032         return providers;
11033     }
11034
11035     /**
11036      * Check if the calling UID has a possible chance at accessing the provider
11037      * at the given authority and user.
11038      */
11039     public String checkContentProviderAccess(String authority, int userId) {
11040         if (userId == UserHandle.USER_ALL) {
11041             mContext.enforceCallingOrSelfPermission(
11042                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11043             userId = UserHandle.getCallingUserId();
11044         }
11045
11046         ProviderInfo cpi = null;
11047         try {
11048             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11049                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11050                             | PackageManager.MATCH_DISABLED_COMPONENTS
11051                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
11052                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11053                     userId);
11054         } catch (RemoteException ignored) {
11055         }
11056         if (cpi == null) {
11057             return "Failed to find provider " + authority + " for user " + userId
11058                     + "; expected to find a valid ContentProvider for this authority";
11059         }
11060
11061         ProcessRecord r = null;
11062         synchronized (mPidsSelfLocked) {
11063             r = mPidsSelfLocked.get(Binder.getCallingPid());
11064         }
11065         if (r == null) {
11066             return "Failed to find PID " + Binder.getCallingPid();
11067         }
11068
11069         synchronized (this) {
11070             return checkContentProviderPermissionLocked(cpi, r, userId, true);
11071         }
11072     }
11073
11074     /**
11075      * Check if {@link ProcessRecord} has a possible chance at accessing the
11076      * given {@link ProviderInfo}. Final permission checking is always done
11077      * in {@link ContentProvider}.
11078      */
11079     private final String checkContentProviderPermissionLocked(
11080             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11081         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11082         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11083         boolean checkedGrants = false;
11084         if (checkUser) {
11085             // Looking for cross-user grants before enforcing the typical cross-users permissions
11086             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11087             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11088                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11089                     return null;
11090                 }
11091                 checkedGrants = true;
11092             }
11093             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11094                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11095             if (userId != tmpTargetUserId) {
11096                 // When we actually went to determine the final targer user ID, this ended
11097                 // up different than our initial check for the authority.  This is because
11098                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11099                 // SELF.  So we need to re-check the grants again.
11100                 checkedGrants = false;
11101             }
11102         }
11103         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11104                 cpi.applicationInfo.uid, cpi.exported)
11105                 == PackageManager.PERMISSION_GRANTED) {
11106             return null;
11107         }
11108         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11109                 cpi.applicationInfo.uid, cpi.exported)
11110                 == PackageManager.PERMISSION_GRANTED) {
11111             return null;
11112         }
11113
11114         PathPermission[] pps = cpi.pathPermissions;
11115         if (pps != null) {
11116             int i = pps.length;
11117             while (i > 0) {
11118                 i--;
11119                 PathPermission pp = pps[i];
11120                 String pprperm = pp.getReadPermission();
11121                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11122                         cpi.applicationInfo.uid, cpi.exported)
11123                         == PackageManager.PERMISSION_GRANTED) {
11124                     return null;
11125                 }
11126                 String ppwperm = pp.getWritePermission();
11127                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11128                         cpi.applicationInfo.uid, cpi.exported)
11129                         == PackageManager.PERMISSION_GRANTED) {
11130                     return null;
11131                 }
11132             }
11133         }
11134         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11135             return null;
11136         }
11137
11138         final String suffix;
11139         if (!cpi.exported) {
11140             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11141         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11142             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11143         } else {
11144             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11145         }
11146         final String msg = "Permission Denial: opening provider " + cpi.name
11147                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11148                 + ", uid=" + callingUid + ")" + suffix;
11149         Slog.w(TAG, msg);
11150         return msg;
11151     }
11152
11153     /**
11154      * Returns if the ContentProvider has granted a uri to callingUid
11155      */
11156     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11157         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11158         if (perms != null) {
11159             for (int i=perms.size()-1; i>=0; i--) {
11160                 GrantUri grantUri = perms.keyAt(i);
11161                 if (grantUri.sourceUserId == userId || !checkUser) {
11162                     if (matchesProvider(grantUri.uri, cpi)) {
11163                         return true;
11164                     }
11165                 }
11166             }
11167         }
11168         return false;
11169     }
11170
11171     /**
11172      * Returns true if the uri authority is one of the authorities specified in the provider.
11173      */
11174     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11175         String uriAuth = uri.getAuthority();
11176         String cpiAuth = cpi.authority;
11177         if (cpiAuth.indexOf(';') == -1) {
11178             return cpiAuth.equals(uriAuth);
11179         }
11180         String[] cpiAuths = cpiAuth.split(";");
11181         int length = cpiAuths.length;
11182         for (int i = 0; i < length; i++) {
11183             if (cpiAuths[i].equals(uriAuth)) return true;
11184         }
11185         return false;
11186     }
11187
11188     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11189             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11190         if (r != null) {
11191             for (int i=0; i<r.conProviders.size(); i++) {
11192                 ContentProviderConnection conn = r.conProviders.get(i);
11193                 if (conn.provider == cpr) {
11194                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11195                             "Adding provider requested by "
11196                             + r.processName + " from process "
11197                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11198                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11199                     if (stable) {
11200                         conn.stableCount++;
11201                         conn.numStableIncs++;
11202                     } else {
11203                         conn.unstableCount++;
11204                         conn.numUnstableIncs++;
11205                     }
11206                     return conn;
11207                 }
11208             }
11209             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11210             if (stable) {
11211                 conn.stableCount = 1;
11212                 conn.numStableIncs = 1;
11213             } else {
11214                 conn.unstableCount = 1;
11215                 conn.numUnstableIncs = 1;
11216             }
11217             cpr.connections.add(conn);
11218             r.conProviders.add(conn);
11219             startAssociationLocked(r.uid, r.processName, r.curProcState,
11220                     cpr.uid, cpr.name, cpr.info.processName);
11221             return conn;
11222         }
11223         cpr.addExternalProcessHandleLocked(externalProcessToken);
11224         return null;
11225     }
11226
11227     boolean decProviderCountLocked(ContentProviderConnection conn,
11228             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11229         if (conn != null) {
11230             cpr = conn.provider;
11231             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11232                     "Removing provider requested by "
11233                     + conn.client.processName + " from process "
11234                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11235                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11236             if (stable) {
11237                 conn.stableCount--;
11238             } else {
11239                 conn.unstableCount--;
11240             }
11241             if (conn.stableCount == 0 && conn.unstableCount == 0) {
11242                 cpr.connections.remove(conn);
11243                 conn.client.conProviders.remove(conn);
11244                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11245                     // The client is more important than last activity -- note the time this
11246                     // is happening, so we keep the old provider process around a bit as last
11247                     // activity to avoid thrashing it.
11248                     if (cpr.proc != null) {
11249                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11250                     }
11251                 }
11252                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11253                 return true;
11254             }
11255             return false;
11256         }
11257         cpr.removeExternalProcessHandleLocked(externalProcessToken);
11258         return false;
11259     }
11260
11261     private void checkTime(long startTime, String where) {
11262         long now = SystemClock.uptimeMillis();
11263         if ((now-startTime) > 50) {
11264             // If we are taking more than 50ms, log about it.
11265             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11266         }
11267     }
11268
11269     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11270             PROC_SPACE_TERM,
11271             PROC_SPACE_TERM|PROC_PARENS,
11272             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11273     };
11274
11275     private final long[] mProcessStateStatsLongs = new long[1];
11276
11277     boolean isProcessAliveLocked(ProcessRecord proc) {
11278         if (proc.procStatFile == null) {
11279             proc.procStatFile = "/proc/" + proc.pid + "/stat";
11280         }
11281         mProcessStateStatsLongs[0] = 0;
11282         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11283                 mProcessStateStatsLongs, null)) {
11284             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11285             return false;
11286         }
11287         final long state = mProcessStateStatsLongs[0];
11288         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11289                 + (char)state);
11290         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11291     }
11292
11293     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11294             String name, IBinder token, boolean stable, int userId) {
11295         ContentProviderRecord cpr;
11296         ContentProviderConnection conn = null;
11297         ProviderInfo cpi = null;
11298
11299         synchronized(this) {
11300             long startTime = SystemClock.uptimeMillis();
11301
11302             ProcessRecord r = null;
11303             if (caller != null) {
11304                 r = getRecordForAppLocked(caller);
11305                 if (r == null) {
11306                     throw new SecurityException(
11307                             "Unable to find app for caller " + caller
11308                           + " (pid=" + Binder.getCallingPid()
11309                           + ") when getting content provider " + name);
11310                 }
11311             }
11312
11313             boolean checkCrossUser = true;
11314
11315             checkTime(startTime, "getContentProviderImpl: getProviderByName");
11316
11317             // First check if this content provider has been published...
11318             cpr = mProviderMap.getProviderByName(name, userId);
11319             // If that didn't work, check if it exists for user 0 and then
11320             // verify that it's a singleton provider before using it.
11321             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11322                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11323                 if (cpr != null) {
11324                     cpi = cpr.info;
11325                     if (isSingleton(cpi.processName, cpi.applicationInfo,
11326                             cpi.name, cpi.flags)
11327                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11328                         userId = UserHandle.USER_SYSTEM;
11329                         checkCrossUser = false;
11330                     } else {
11331                         cpr = null;
11332                         cpi = null;
11333                     }
11334                 }
11335             }
11336
11337             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11338             if (providerRunning) {
11339                 cpi = cpr.info;
11340                 String msg;
11341                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11342                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11343                         != null) {
11344                     throw new SecurityException(msg);
11345                 }
11346                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11347
11348                 if (r != null && cpr.canRunHere(r)) {
11349                     // This provider has been published or is in the process
11350                     // of being published...  but it is also allowed to run
11351                     // in the caller's process, so don't make a connection
11352                     // and just let the caller instantiate its own instance.
11353                     ContentProviderHolder holder = cpr.newHolder(null);
11354                     // don't give caller the provider object, it needs
11355                     // to make its own.
11356                     holder.provider = null;
11357                     return holder;
11358                 }
11359                 // Don't expose providers between normal apps and instant apps
11360                 try {
11361                     if (AppGlobals.getPackageManager()
11362                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11363                         return null;
11364                     }
11365                 } catch (RemoteException e) {
11366                 }
11367
11368                 final long origId = Binder.clearCallingIdentity();
11369
11370                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11371
11372                 // In this case the provider instance already exists, so we can
11373                 // return it right away.
11374                 conn = incProviderCountLocked(r, cpr, token, stable);
11375                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11376                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11377                         // If this is a perceptible app accessing the provider,
11378                         // make sure to count it as being accessed and thus
11379                         // back up on the LRU list.  This is good because
11380                         // content providers are often expensive to start.
11381                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11382                         updateLruProcessLocked(cpr.proc, false, null);
11383                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11384                     }
11385                 }
11386
11387                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11388                 final int verifiedAdj = cpr.proc.verifiedAdj;
11389                 boolean success = updateOomAdjLocked(cpr.proc, true);
11390                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11391                 // if the process has been successfully adjusted.  So to reduce races with
11392                 // it, we will check whether the process still exists.  Note that this doesn't
11393                 // completely get rid of races with LMK killing the process, but should make
11394                 // them much smaller.
11395                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11396                     success = false;
11397                 }
11398                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11399                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11400                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11401                 // NOTE: there is still a race here where a signal could be
11402                 // pending on the process even though we managed to update its
11403                 // adj level.  Not sure what to do about this, but at least
11404                 // the race is now smaller.
11405                 if (!success) {
11406                     // Uh oh...  it looks like the provider's process
11407                     // has been killed on us.  We need to wait for a new
11408                     // process to be started, and make sure its death
11409                     // doesn't kill our process.
11410                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11411                             + " is crashing; detaching " + r);
11412                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11413                     checkTime(startTime, "getContentProviderImpl: before appDied");
11414                     appDiedLocked(cpr.proc);
11415                     checkTime(startTime, "getContentProviderImpl: after appDied");
11416                     if (!lastRef) {
11417                         // This wasn't the last ref our process had on
11418                         // the provider...  we have now been killed, bail.
11419                         return null;
11420                     }
11421                     providerRunning = false;
11422                     conn = null;
11423                 } else {
11424                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
11425                 }
11426
11427                 Binder.restoreCallingIdentity(origId);
11428             }
11429
11430             if (!providerRunning) {
11431                 try {
11432                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11433                     cpi = AppGlobals.getPackageManager().
11434                         resolveContentProvider(name,
11435                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11436                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11437                 } catch (RemoteException ex) {
11438                 }
11439                 if (cpi == null) {
11440                     return null;
11441                 }
11442                 // If the provider is a singleton AND
11443                 // (it's a call within the same user || the provider is a
11444                 // privileged app)
11445                 // Then allow connecting to the singleton provider
11446                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11447                         cpi.name, cpi.flags)
11448                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11449                 if (singleton) {
11450                     userId = UserHandle.USER_SYSTEM;
11451                 }
11452                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11453                 checkTime(startTime, "getContentProviderImpl: got app info for user");
11454
11455                 String msg;
11456                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11457                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11458                         != null) {
11459                     throw new SecurityException(msg);
11460                 }
11461                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11462
11463                 if (!mProcessesReady
11464                         && !cpi.processName.equals("system")) {
11465                     // If this content provider does not run in the system
11466                     // process, and the system is not yet ready to run other
11467                     // processes, then fail fast instead of hanging.
11468                     throw new IllegalArgumentException(
11469                             "Attempt to launch content provider before system ready");
11470                 }
11471
11472                 // Make sure that the user who owns this provider is running.  If not,
11473                 // we don't want to allow it to run.
11474                 if (!mUserController.isUserRunningLocked(userId, 0)) {
11475                     Slog.w(TAG, "Unable to launch app "
11476                             + cpi.applicationInfo.packageName + "/"
11477                             + cpi.applicationInfo.uid + " for provider "
11478                             + name + ": user " + userId + " is stopped");
11479                     return null;
11480                 }
11481
11482                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11483                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11484                 cpr = mProviderMap.getProviderByClass(comp, userId);
11485                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11486                 final boolean firstClass = cpr == null;
11487                 if (firstClass) {
11488                     final long ident = Binder.clearCallingIdentity();
11489
11490                     // If permissions need a review before any of the app components can run,
11491                     // we return no provider and launch a review activity if the calling app
11492                     // is in the foreground.
11493                     if (mPermissionReviewRequired) {
11494                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11495                             return null;
11496                         }
11497                     }
11498
11499                     try {
11500                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11501                         ApplicationInfo ai =
11502                             AppGlobals.getPackageManager().
11503                                 getApplicationInfo(
11504                                         cpi.applicationInfo.packageName,
11505                                         STOCK_PM_FLAGS, userId);
11506                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11507                         if (ai == null) {
11508                             Slog.w(TAG, "No package info for content provider "
11509                                     + cpi.name);
11510                             return null;
11511                         }
11512                         ai = getAppInfoForUser(ai, userId);
11513                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11514                     } catch (RemoteException ex) {
11515                         // pm is in same process, this will never happen.
11516                     } finally {
11517                         Binder.restoreCallingIdentity(ident);
11518                     }
11519                 }
11520
11521                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11522
11523                 if (r != null && cpr.canRunHere(r)) {
11524                     // If this is a multiprocess provider, then just return its
11525                     // info and allow the caller to instantiate it.  Only do
11526                     // this if the provider is the same user as the caller's
11527                     // process, or can run as root (so can be in any process).
11528                     return cpr.newHolder(null);
11529                 }
11530
11531                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11532                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11533                             + cpr.info.name + " callers=" + Debug.getCallers(6));
11534
11535                 // This is single process, and our app is now connecting to it.
11536                 // See if we are already in the process of launching this
11537                 // provider.
11538                 final int N = mLaunchingProviders.size();
11539                 int i;
11540                 for (i = 0; i < N; i++) {
11541                     if (mLaunchingProviders.get(i) == cpr) {
11542                         break;
11543                     }
11544                 }
11545
11546                 // If the provider is not already being launched, then get it
11547                 // started.
11548                 if (i >= N) {
11549                     final long origId = Binder.clearCallingIdentity();
11550
11551                     try {
11552                         // Content provider is now in use, its package can't be stopped.
11553                         try {
11554                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
11555                             AppGlobals.getPackageManager().setPackageStoppedState(
11556                                     cpr.appInfo.packageName, false, userId);
11557                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
11558                         } catch (RemoteException e) {
11559                         } catch (IllegalArgumentException e) {
11560                             Slog.w(TAG, "Failed trying to unstop package "
11561                                     + cpr.appInfo.packageName + ": " + e);
11562                         }
11563
11564                         // Use existing process if already started
11565                         checkTime(startTime, "getContentProviderImpl: looking for process record");
11566                         ProcessRecord proc = getProcessRecordLocked(
11567                                 cpi.processName, cpr.appInfo.uid, false);
11568                         if (proc != null && proc.thread != null && !proc.killed) {
11569                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11570                                     "Installing in existing process " + proc);
11571                             if (!proc.pubProviders.containsKey(cpi.name)) {
11572                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
11573                                 proc.pubProviders.put(cpi.name, cpr);
11574                                 try {
11575                                     proc.thread.scheduleInstallProvider(cpi);
11576                                 } catch (RemoteException e) {
11577                                 }
11578                             }
11579                         } else {
11580                             checkTime(startTime, "getContentProviderImpl: before start process");
11581                             proc = startProcessLocked(cpi.processName,
11582                                     cpr.appInfo, false, 0, "content provider",
11583                                     new ComponentName(cpi.applicationInfo.packageName,
11584                                             cpi.name), false, false, false);
11585                             checkTime(startTime, "getContentProviderImpl: after start process");
11586                             if (proc == null) {
11587                                 Slog.w(TAG, "Unable to launch app "
11588                                         + cpi.applicationInfo.packageName + "/"
11589                                         + cpi.applicationInfo.uid + " for provider "
11590                                         + name + ": process is bad");
11591                                 return null;
11592                             }
11593                         }
11594                         cpr.launchingApp = proc;
11595                         mLaunchingProviders.add(cpr);
11596                     } finally {
11597                         Binder.restoreCallingIdentity(origId);
11598                     }
11599                 }
11600
11601                 checkTime(startTime, "getContentProviderImpl: updating data structures");
11602
11603                 // Make sure the provider is published (the same provider class
11604                 // may be published under multiple names).
11605                 if (firstClass) {
11606                     mProviderMap.putProviderByClass(comp, cpr);
11607                 }
11608
11609                 mProviderMap.putProviderByName(name, cpr);
11610                 conn = incProviderCountLocked(r, cpr, token, stable);
11611                 if (conn != null) {
11612                     conn.waiting = true;
11613                 }
11614             }
11615             checkTime(startTime, "getContentProviderImpl: done!");
11616
11617             grantEphemeralAccessLocked(userId, null /*intent*/,
11618                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11619         }
11620
11621         // Wait for the provider to be published...
11622         synchronized (cpr) {
11623             while (cpr.provider == null) {
11624                 if (cpr.launchingApp == null) {
11625                     Slog.w(TAG, "Unable to launch app "
11626                             + cpi.applicationInfo.packageName + "/"
11627                             + cpi.applicationInfo.uid + " for provider "
11628                             + name + ": launching app became null");
11629                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11630                             UserHandle.getUserId(cpi.applicationInfo.uid),
11631                             cpi.applicationInfo.packageName,
11632                             cpi.applicationInfo.uid, name);
11633                     return null;
11634                 }
11635                 try {
11636                     if (DEBUG_MU) Slog.v(TAG_MU,
11637                             "Waiting to start provider " + cpr
11638                             + " launchingApp=" + cpr.launchingApp);
11639                     if (conn != null) {
11640                         conn.waiting = true;
11641                     }
11642                     cpr.wait();
11643                 } catch (InterruptedException ex) {
11644                 } finally {
11645                     if (conn != null) {
11646                         conn.waiting = false;
11647                     }
11648                 }
11649             }
11650         }
11651         return cpr != null ? cpr.newHolder(conn) : null;
11652     }
11653
11654     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11655             ProcessRecord r, final int userId) {
11656         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11657                 cpi.packageName, userId)) {
11658
11659             final boolean callerForeground = r == null || r.setSchedGroup
11660                     != ProcessList.SCHED_GROUP_BACKGROUND;
11661
11662             // Show a permission review UI only for starting from a foreground app
11663             if (!callerForeground) {
11664                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11665                         + cpi.packageName + " requires a permissions review");
11666                 return false;
11667             }
11668
11669             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11670             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11671                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11672             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11673
11674             if (DEBUG_PERMISSIONS_REVIEW) {
11675                 Slog.i(TAG, "u" + userId + " Launching permission review "
11676                         + "for package " + cpi.packageName);
11677             }
11678
11679             final UserHandle userHandle = new UserHandle(userId);
11680             mHandler.post(new Runnable() {
11681                 @Override
11682                 public void run() {
11683                     mContext.startActivityAsUser(intent, userHandle);
11684                 }
11685             });
11686
11687             return false;
11688         }
11689
11690         return true;
11691     }
11692
11693     PackageManagerInternal getPackageManagerInternalLocked() {
11694         if (mPackageManagerInt == null) {
11695             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11696         }
11697         return mPackageManagerInt;
11698     }
11699
11700     @Override
11701     public final ContentProviderHolder getContentProvider(
11702             IApplicationThread caller, String name, int userId, boolean stable) {
11703         enforceNotIsolatedCaller("getContentProvider");
11704         if (caller == null) {
11705             String msg = "null IApplicationThread when getting content provider "
11706                     + name;
11707             Slog.w(TAG, msg);
11708             throw new SecurityException(msg);
11709         }
11710         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11711         // with cross-user grant.
11712         return getContentProviderImpl(caller, name, null, stable, userId);
11713     }
11714
11715     public ContentProviderHolder getContentProviderExternal(
11716             String name, int userId, IBinder token) {
11717         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11718             "Do not have permission in call getContentProviderExternal()");
11719         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11720                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11721         return getContentProviderExternalUnchecked(name, token, userId);
11722     }
11723
11724     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11725             IBinder token, int userId) {
11726         return getContentProviderImpl(null, name, token, true, userId);
11727     }
11728
11729     /**
11730      * Drop a content provider from a ProcessRecord's bookkeeping
11731      */
11732     public void removeContentProvider(IBinder connection, boolean stable) {
11733         enforceNotIsolatedCaller("removeContentProvider");
11734         long ident = Binder.clearCallingIdentity();
11735         try {
11736             synchronized (this) {
11737                 ContentProviderConnection conn;
11738                 try {
11739                     conn = (ContentProviderConnection)connection;
11740                 } catch (ClassCastException e) {
11741                     String msg ="removeContentProvider: " + connection
11742                             + " not a ContentProviderConnection";
11743                     Slog.w(TAG, msg);
11744                     throw new IllegalArgumentException(msg);
11745                 }
11746                 if (conn == null) {
11747                     throw new NullPointerException("connection is null");
11748                 }
11749                 if (decProviderCountLocked(conn, null, null, stable)) {
11750                     updateOomAdjLocked();
11751                 }
11752             }
11753         } finally {
11754             Binder.restoreCallingIdentity(ident);
11755         }
11756     }
11757
11758     public void removeContentProviderExternal(String name, IBinder token) {
11759         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11760             "Do not have permission in call removeContentProviderExternal()");
11761         int userId = UserHandle.getCallingUserId();
11762         long ident = Binder.clearCallingIdentity();
11763         try {
11764             removeContentProviderExternalUnchecked(name, token, userId);
11765         } finally {
11766             Binder.restoreCallingIdentity(ident);
11767         }
11768     }
11769
11770     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11771         synchronized (this) {
11772             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11773             if(cpr == null) {
11774                 //remove from mProvidersByClass
11775                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11776                 return;
11777             }
11778
11779             //update content provider record entry info
11780             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11781             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11782             if (localCpr.hasExternalProcessHandles()) {
11783                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11784                     updateOomAdjLocked();
11785                 } else {
11786                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11787                             + " with no external reference for token: "
11788                             + token + ".");
11789                 }
11790             } else {
11791                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11792                         + " with no external references.");
11793             }
11794         }
11795     }
11796
11797     public final void publishContentProviders(IApplicationThread caller,
11798             List<ContentProviderHolder> providers) {
11799         if (providers == null) {
11800             return;
11801         }
11802
11803         enforceNotIsolatedCaller("publishContentProviders");
11804         synchronized (this) {
11805             final ProcessRecord r = getRecordForAppLocked(caller);
11806             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11807             if (r == null) {
11808                 throw new SecurityException(
11809                         "Unable to find app for caller " + caller
11810                       + " (pid=" + Binder.getCallingPid()
11811                       + ") when publishing content providers");
11812             }
11813
11814             final long origId = Binder.clearCallingIdentity();
11815
11816             final int N = providers.size();
11817             for (int i = 0; i < N; i++) {
11818                 ContentProviderHolder src = providers.get(i);
11819                 if (src == null || src.info == null || src.provider == null) {
11820                     continue;
11821                 }
11822                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11823                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11824                 if (dst != null) {
11825                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11826                     mProviderMap.putProviderByClass(comp, dst);
11827                     String names[] = dst.info.authority.split(";");
11828                     for (int j = 0; j < names.length; j++) {
11829                         mProviderMap.putProviderByName(names[j], dst);
11830                     }
11831
11832                     int launchingCount = mLaunchingProviders.size();
11833                     int j;
11834                     boolean wasInLaunchingProviders = false;
11835                     for (j = 0; j < launchingCount; j++) {
11836                         if (mLaunchingProviders.get(j) == dst) {
11837                             mLaunchingProviders.remove(j);
11838                             wasInLaunchingProviders = true;
11839                             j--;
11840                             launchingCount--;
11841                         }
11842                     }
11843                     if (wasInLaunchingProviders) {
11844                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11845                     }
11846                     synchronized (dst) {
11847                         dst.provider = src.provider;
11848                         dst.proc = r;
11849                         dst.notifyAll();
11850                     }
11851                     updateOomAdjLocked(r, true);
11852                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11853                             src.info.authority);
11854                 }
11855             }
11856
11857             Binder.restoreCallingIdentity(origId);
11858         }
11859     }
11860
11861     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11862         ContentProviderConnection conn;
11863         try {
11864             conn = (ContentProviderConnection)connection;
11865         } catch (ClassCastException e) {
11866             String msg ="refContentProvider: " + connection
11867                     + " not a ContentProviderConnection";
11868             Slog.w(TAG, msg);
11869             throw new IllegalArgumentException(msg);
11870         }
11871         if (conn == null) {
11872             throw new NullPointerException("connection is null");
11873         }
11874
11875         synchronized (this) {
11876             if (stable > 0) {
11877                 conn.numStableIncs += stable;
11878             }
11879             stable = conn.stableCount + stable;
11880             if (stable < 0) {
11881                 throw new IllegalStateException("stableCount < 0: " + stable);
11882             }
11883
11884             if (unstable > 0) {
11885                 conn.numUnstableIncs += unstable;
11886             }
11887             unstable = conn.unstableCount + unstable;
11888             if (unstable < 0) {
11889                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11890             }
11891
11892             if ((stable+unstable) <= 0) {
11893                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11894                         + stable + " unstable=" + unstable);
11895             }
11896             conn.stableCount = stable;
11897             conn.unstableCount = unstable;
11898             return !conn.dead;
11899         }
11900     }
11901
11902     public void unstableProviderDied(IBinder connection) {
11903         ContentProviderConnection conn;
11904         try {
11905             conn = (ContentProviderConnection)connection;
11906         } catch (ClassCastException e) {
11907             String msg ="refContentProvider: " + connection
11908                     + " not a ContentProviderConnection";
11909             Slog.w(TAG, msg);
11910             throw new IllegalArgumentException(msg);
11911         }
11912         if (conn == null) {
11913             throw new NullPointerException("connection is null");
11914         }
11915
11916         // Safely retrieve the content provider associated with the connection.
11917         IContentProvider provider;
11918         synchronized (this) {
11919             provider = conn.provider.provider;
11920         }
11921
11922         if (provider == null) {
11923             // Um, yeah, we're way ahead of you.
11924             return;
11925         }
11926
11927         // Make sure the caller is being honest with us.
11928         if (provider.asBinder().pingBinder()) {
11929             // Er, no, still looks good to us.
11930             synchronized (this) {
11931                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11932                         + " says " + conn + " died, but we don't agree");
11933                 return;
11934             }
11935         }
11936
11937         // Well look at that!  It's dead!
11938         synchronized (this) {
11939             if (conn.provider.provider != provider) {
11940                 // But something changed...  good enough.
11941                 return;
11942             }
11943
11944             ProcessRecord proc = conn.provider.proc;
11945             if (proc == null || proc.thread == null) {
11946                 // Seems like the process is already cleaned up.
11947                 return;
11948             }
11949
11950             // As far as we're concerned, this is just like receiving a
11951             // death notification...  just a bit prematurely.
11952             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11953                     + ") early provider death");
11954             final long ident = Binder.clearCallingIdentity();
11955             try {
11956                 appDiedLocked(proc);
11957             } finally {
11958                 Binder.restoreCallingIdentity(ident);
11959             }
11960         }
11961     }
11962
11963     @Override
11964     public void appNotRespondingViaProvider(IBinder connection) {
11965         enforceCallingPermission(
11966                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11967
11968         final ContentProviderConnection conn = (ContentProviderConnection) connection;
11969         if (conn == null) {
11970             Slog.w(TAG, "ContentProviderConnection is null");
11971             return;
11972         }
11973
11974         final ProcessRecord host = conn.provider.proc;
11975         if (host == null) {
11976             Slog.w(TAG, "Failed to find hosting ProcessRecord");
11977             return;
11978         }
11979
11980         mHandler.post(new Runnable() {
11981             @Override
11982             public void run() {
11983                 mAppErrors.appNotResponding(host, null, null, false,
11984                         "ContentProvider not responding");
11985             }
11986         });
11987     }
11988
11989     public final void installSystemProviders() {
11990         List<ProviderInfo> providers;
11991         synchronized (this) {
11992             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
11993             providers = generateApplicationProvidersLocked(app);
11994             if (providers != null) {
11995                 for (int i=providers.size()-1; i>=0; i--) {
11996                     ProviderInfo pi = (ProviderInfo)providers.get(i);
11997                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11998                         Slog.w(TAG, "Not installing system proc provider " + pi.name
11999                                 + ": not system .apk");
12000                         providers.remove(i);
12001                     }
12002                 }
12003             }
12004         }
12005         if (providers != null) {
12006             mSystemThread.installSystemProviders(providers);
12007         }
12008
12009         mConstants.start(mContext.getContentResolver());
12010         mCoreSettingsObserver = new CoreSettingsObserver(this);
12011         mFontScaleSettingObserver = new FontScaleSettingObserver();
12012
12013         // Now that the settings provider is published we can consider sending
12014         // in a rescue party.
12015         RescueParty.onSettingsProviderPublished(mContext);
12016
12017         //mUsageStatsService.monitorPackages();
12018     }
12019
12020     private void startPersistentApps(int matchFlags) {
12021         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12022
12023         synchronized (this) {
12024             try {
12025                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12026                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12027                 for (ApplicationInfo app : apps) {
12028                     if (!"android".equals(app.packageName)) {
12029                         addAppLocked(app, null, false, null /* ABI override */);
12030                     }
12031                 }
12032             } catch (RemoteException ex) {
12033             }
12034         }
12035     }
12036
12037     /**
12038      * When a user is unlocked, we need to install encryption-unaware providers
12039      * belonging to any running apps.
12040      */
12041     private void installEncryptionUnawareProviders(int userId) {
12042         // We're only interested in providers that are encryption unaware, and
12043         // we don't care about uninstalled apps, since there's no way they're
12044         // running at this point.
12045         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12046
12047         synchronized (this) {
12048             final int NP = mProcessNames.getMap().size();
12049             for (int ip = 0; ip < NP; ip++) {
12050                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12051                 final int NA = apps.size();
12052                 for (int ia = 0; ia < NA; ia++) {
12053                     final ProcessRecord app = apps.valueAt(ia);
12054                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
12055
12056                     final int NG = app.pkgList.size();
12057                     for (int ig = 0; ig < NG; ig++) {
12058                         try {
12059                             final String pkgName = app.pkgList.keyAt(ig);
12060                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12061                                     .getPackageInfo(pkgName, matchFlags, userId);
12062                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12063                                 for (ProviderInfo pi : pkgInfo.providers) {
12064                                     // TODO: keep in sync with generateApplicationProvidersLocked
12065                                     final boolean processMatch = Objects.equals(pi.processName,
12066                                             app.processName) || pi.multiprocess;
12067                                     final boolean userMatch = isSingleton(pi.processName,
12068                                             pi.applicationInfo, pi.name, pi.flags)
12069                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
12070                                     if (processMatch && userMatch) {
12071                                         Log.v(TAG, "Installing " + pi);
12072                                         app.thread.scheduleInstallProvider(pi);
12073                                     } else {
12074                                         Log.v(TAG, "Skipping " + pi);
12075                                     }
12076                                 }
12077                             }
12078                         } catch (RemoteException ignored) {
12079                         }
12080                     }
12081                 }
12082             }
12083         }
12084     }
12085
12086     /**
12087      * Allows apps to retrieve the MIME type of a URI.
12088      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12089      * users, then it does not need permission to access the ContentProvider.
12090      * Either, it needs cross-user uri grants.
12091      *
12092      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12093      *
12094      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12095      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12096      */
12097     public String getProviderMimeType(Uri uri, int userId) {
12098         enforceNotIsolatedCaller("getProviderMimeType");
12099         final String name = uri.getAuthority();
12100         int callingUid = Binder.getCallingUid();
12101         int callingPid = Binder.getCallingPid();
12102         long ident = 0;
12103         boolean clearedIdentity = false;
12104         synchronized (this) {
12105             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12106         }
12107         if (canClearIdentity(callingPid, callingUid, userId)) {
12108             clearedIdentity = true;
12109             ident = Binder.clearCallingIdentity();
12110         }
12111         ContentProviderHolder holder = null;
12112         try {
12113             holder = getContentProviderExternalUnchecked(name, null, userId);
12114             if (holder != null) {
12115                 return holder.provider.getType(uri);
12116             }
12117         } catch (RemoteException e) {
12118             Log.w(TAG, "Content provider dead retrieving " + uri, e);
12119             return null;
12120         } catch (Exception e) {
12121             Log.w(TAG, "Exception while determining type of " + uri, e);
12122             return null;
12123         } finally {
12124             // We need to clear the identity to call removeContentProviderExternalUnchecked
12125             if (!clearedIdentity) {
12126                 ident = Binder.clearCallingIdentity();
12127             }
12128             try {
12129                 if (holder != null) {
12130                     removeContentProviderExternalUnchecked(name, null, userId);
12131                 }
12132             } finally {
12133                 Binder.restoreCallingIdentity(ident);
12134             }
12135         }
12136
12137         return null;
12138     }
12139
12140     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12141         if (UserHandle.getUserId(callingUid) == userId) {
12142             return true;
12143         }
12144         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12145                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12146                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12147                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12148                 return true;
12149         }
12150         return false;
12151     }
12152
12153     // =========================================================
12154     // GLOBAL MANAGEMENT
12155     // =========================================================
12156
12157     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12158             boolean isolated, int isolatedUid) {
12159         String proc = customProcess != null ? customProcess : info.processName;
12160         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12161         final int userId = UserHandle.getUserId(info.uid);
12162         int uid = info.uid;
12163         if (isolated) {
12164             if (isolatedUid == 0) {
12165                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12166                 while (true) {
12167                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12168                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12169                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12170                     }
12171                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12172                     mNextIsolatedProcessUid++;
12173                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12174                         // No process for this uid, use it.
12175                         break;
12176                     }
12177                     stepsLeft--;
12178                     if (stepsLeft <= 0) {
12179                         return null;
12180                     }
12181                 }
12182             } else {
12183                 // Special case for startIsolatedProcess (internal only), where
12184                 // the uid of the isolated process is specified by the caller.
12185                 uid = isolatedUid;
12186             }
12187             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12188
12189             // Register the isolated UID with this application so BatteryStats knows to
12190             // attribute resource usage to the application.
12191             //
12192             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12193             // about the process state of the isolated UID *before* it is registered with the
12194             // owning application.
12195             mBatteryStatsService.addIsolatedUid(uid, info.uid);
12196         }
12197         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12198         if (!mBooted && !mBooting
12199                 && userId == UserHandle.USER_SYSTEM
12200                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12201             r.persistent = true;
12202             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12203         }
12204         addProcessNameLocked(r);
12205         return r;
12206     }
12207
12208     private boolean uidOnBackgroundWhitelist(final int uid) {
12209         final int appId = UserHandle.getAppId(uid);
12210         final int[] whitelist = mBackgroundAppIdWhitelist;
12211         final int N = whitelist.length;
12212         for (int i = 0; i < N; i++) {
12213             if (appId == whitelist[i]) {
12214                 return true;
12215             }
12216         }
12217         return false;
12218     }
12219
12220     @Override
12221     public void backgroundWhitelistUid(final int uid) {
12222         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12223             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12224         }
12225
12226         if (DEBUG_BACKGROUND_CHECK) {
12227             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12228         }
12229         synchronized (this) {
12230             final int N = mBackgroundAppIdWhitelist.length;
12231             int[] newList = new int[N+1];
12232             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12233             newList[N] = UserHandle.getAppId(uid);
12234             mBackgroundAppIdWhitelist = newList;
12235         }
12236     }
12237
12238     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12239             String abiOverride) {
12240         ProcessRecord app;
12241         if (!isolated) {
12242             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12243                     info.uid, true);
12244         } else {
12245             app = null;
12246         }
12247
12248         if (app == null) {
12249             app = newProcessRecordLocked(info, customProcess, isolated, 0);
12250             updateLruProcessLocked(app, false, null);
12251             updateOomAdjLocked();
12252         }
12253
12254         // This package really, really can not be stopped.
12255         try {
12256             AppGlobals.getPackageManager().setPackageStoppedState(
12257                     info.packageName, false, UserHandle.getUserId(app.uid));
12258         } catch (RemoteException e) {
12259         } catch (IllegalArgumentException e) {
12260             Slog.w(TAG, "Failed trying to unstop package "
12261                     + info.packageName + ": " + e);
12262         }
12263
12264         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12265             app.persistent = true;
12266             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12267         }
12268         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12269             mPersistentStartingProcesses.add(app);
12270             startProcessLocked(app, "added application",
12271                     customProcess != null ? customProcess : app.processName, abiOverride,
12272                     null /* entryPoint */, null /* entryPointArgs */);
12273         }
12274
12275         return app;
12276     }
12277
12278     public void unhandledBack() {
12279         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12280                 "unhandledBack()");
12281
12282         synchronized(this) {
12283             final long origId = Binder.clearCallingIdentity();
12284             try {
12285                 getFocusedStack().unhandledBackLocked();
12286             } finally {
12287                 Binder.restoreCallingIdentity(origId);
12288             }
12289         }
12290     }
12291
12292     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12293         enforceNotIsolatedCaller("openContentUri");
12294         final int userId = UserHandle.getCallingUserId();
12295         final Uri uri = Uri.parse(uriString);
12296         String name = uri.getAuthority();
12297         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12298         ParcelFileDescriptor pfd = null;
12299         if (cph != null) {
12300             // We record the binder invoker's uid in thread-local storage before
12301             // going to the content provider to open the file.  Later, in the code
12302             // that handles all permissions checks, we look for this uid and use
12303             // that rather than the Activity Manager's own uid.  The effect is that
12304             // we do the check against the caller's permissions even though it looks
12305             // to the content provider like the Activity Manager itself is making
12306             // the request.
12307             Binder token = new Binder();
12308             sCallerIdentity.set(new Identity(
12309                     token, Binder.getCallingPid(), Binder.getCallingUid()));
12310             try {
12311                 pfd = cph.provider.openFile(null, uri, "r", null, token);
12312             } catch (FileNotFoundException e) {
12313                 // do nothing; pfd will be returned null
12314             } finally {
12315                 // Ensure that whatever happens, we clean up the identity state
12316                 sCallerIdentity.remove();
12317                 // Ensure we're done with the provider.
12318                 removeContentProviderExternalUnchecked(name, null, userId);
12319             }
12320         } else {
12321             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12322         }
12323         return pfd;
12324     }
12325
12326     // Actually is sleeping or shutting down or whatever else in the future
12327     // is an inactive state.
12328     boolean isSleepingOrShuttingDownLocked() {
12329         return isSleepingLocked() || mShuttingDown;
12330     }
12331
12332     boolean isShuttingDownLocked() {
12333         return mShuttingDown;
12334     }
12335
12336     boolean isSleepingLocked() {
12337         return mSleeping;
12338     }
12339
12340     void onWakefulnessChanged(int wakefulness) {
12341         synchronized(this) {
12342             mWakefulness = wakefulness;
12343             updateSleepIfNeededLocked();
12344         }
12345     }
12346
12347     void finishRunningVoiceLocked() {
12348         if (mRunningVoice != null) {
12349             mRunningVoice = null;
12350             mVoiceWakeLock.release();
12351             updateSleepIfNeededLocked();
12352         }
12353     }
12354
12355     void startTimeTrackingFocusedActivityLocked() {
12356         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12357         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12358             mCurAppTimeTracker.start(resumedActivity.packageName);
12359         }
12360     }
12361
12362     void updateSleepIfNeededLocked() {
12363         final boolean shouldSleep = shouldSleepLocked();
12364         if (mSleeping && !shouldSleep) {
12365             mSleeping = false;
12366             startTimeTrackingFocusedActivityLocked();
12367             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12368             mStackSupervisor.comeOutOfSleepIfNeededLocked();
12369             sendNotifyVrManagerOfSleepState(false);
12370             updateOomAdjLocked();
12371         } else if (!mSleeping && shouldSleep) {
12372             mSleeping = true;
12373             if (mCurAppTimeTracker != null) {
12374                 mCurAppTimeTracker.stop();
12375             }
12376             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12377             mStackSupervisor.goingToSleepLocked();
12378             sendNotifyVrManagerOfSleepState(true);
12379             updateOomAdjLocked();
12380
12381             // Initialize the wake times of all processes.
12382             checkExcessivePowerUsageLocked(false);
12383             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12384             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12385             mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
12386         }
12387
12388         // Also update state in a special way for running foreground services UI.
12389         switch (mWakefulness) {
12390             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12391             case PowerManagerInternal.WAKEFULNESS_DREAMING:
12392             case PowerManagerInternal.WAKEFULNESS_DOZING:
12393                 mServices.updateScreenStateLocked(false);
12394                 break;
12395             case PowerManagerInternal.WAKEFULNESS_AWAKE:
12396             default:
12397                 mServices.updateScreenStateLocked(true);
12398                 break;
12399         }
12400     }
12401
12402     private boolean shouldSleepLocked() {
12403         // Resume applications while running a voice interactor.
12404         if (mRunningVoice != null) {
12405             return false;
12406         }
12407
12408         // TODO: Transform the lock screen state into a sleep token instead.
12409         switch (mWakefulness) {
12410             case PowerManagerInternal.WAKEFULNESS_AWAKE:
12411             case PowerManagerInternal.WAKEFULNESS_DREAMING:
12412             case PowerManagerInternal.WAKEFULNESS_DOZING:
12413                 // Pause applications whenever the lock screen is shown or any sleep
12414                 // tokens have been acquired.
12415                 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12416             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12417             default:
12418                 // If we're asleep then pause applications unconditionally.
12419                 return true;
12420         }
12421     }
12422
12423     /** Pokes the task persister. */
12424     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12425         mRecentTasks.notifyTaskPersisterLocked(task, flush);
12426     }
12427
12428     /**
12429      * Notifies all listeners when the pinned stack animation starts.
12430      */
12431     @Override
12432     public void notifyPinnedStackAnimationStarted() {
12433         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12434     }
12435
12436     /**
12437      * Notifies all listeners when the pinned stack animation ends.
12438      */
12439     @Override
12440     public void notifyPinnedStackAnimationEnded() {
12441         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12442     }
12443
12444     @Override
12445     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12446         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12447     }
12448
12449     @Override
12450     public boolean shutdown(int timeout) {
12451         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12452                 != PackageManager.PERMISSION_GRANTED) {
12453             throw new SecurityException("Requires permission "
12454                     + android.Manifest.permission.SHUTDOWN);
12455         }
12456
12457         boolean timedout = false;
12458
12459         synchronized(this) {
12460             mShuttingDown = true;
12461             updateEventDispatchingLocked();
12462             timedout = mStackSupervisor.shutdownLocked(timeout);
12463         }
12464
12465         mAppOpsService.shutdown();
12466         if (mUsageStatsService != null) {
12467             mUsageStatsService.prepareShutdown();
12468         }
12469         mBatteryStatsService.shutdown();
12470         synchronized (this) {
12471             mProcessStats.shutdownLocked();
12472             notifyTaskPersisterLocked(null, true);
12473         }
12474
12475         return timedout;
12476     }
12477
12478     public final void activitySlept(IBinder token) {
12479         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12480
12481         final long origId = Binder.clearCallingIdentity();
12482
12483         synchronized (this) {
12484             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12485             if (r != null) {
12486                 mStackSupervisor.activitySleptLocked(r);
12487             }
12488         }
12489
12490         Binder.restoreCallingIdentity(origId);
12491     }
12492
12493     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12494         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12495         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12496         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12497             boolean wasRunningVoice = mRunningVoice != null;
12498             mRunningVoice = session;
12499             if (!wasRunningVoice) {
12500                 mVoiceWakeLock.acquire();
12501                 updateSleepIfNeededLocked();
12502             }
12503         }
12504     }
12505
12506     private void updateEventDispatchingLocked() {
12507         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12508     }
12509
12510     @Override
12511     public void setLockScreenShown(boolean showing) {
12512         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12513                 != PackageManager.PERMISSION_GRANTED) {
12514             throw new SecurityException("Requires permission "
12515                     + android.Manifest.permission.DEVICE_POWER);
12516         }
12517
12518         synchronized(this) {
12519             long ident = Binder.clearCallingIdentity();
12520             try {
12521                 mKeyguardController.setKeyguardShown(showing);
12522             } finally {
12523                 Binder.restoreCallingIdentity(ident);
12524             }
12525         }
12526     }
12527
12528     @Override
12529     public void notifyLockedProfile(@UserIdInt int userId) {
12530         try {
12531             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12532                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12533             }
12534         } catch (RemoteException ex) {
12535             throw new SecurityException("Fail to check is caller a privileged app", ex);
12536         }
12537
12538         synchronized (this) {
12539             final long ident = Binder.clearCallingIdentity();
12540             try {
12541                 if (mUserController.shouldConfirmCredentials(userId)) {
12542                     if (mKeyguardController.isKeyguardLocked()) {
12543                         // Showing launcher to avoid user entering credential twice.
12544                         final int currentUserId = mUserController.getCurrentUserIdLocked();
12545                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12546                     }
12547                     mStackSupervisor.lockAllProfileTasks(userId);
12548                 }
12549             } finally {
12550                 Binder.restoreCallingIdentity(ident);
12551             }
12552         }
12553     }
12554
12555     @Override
12556     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12557         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12558         synchronized (this) {
12559             final long ident = Binder.clearCallingIdentity();
12560             try {
12561                 mActivityStarter.startConfirmCredentialIntent(intent, options);
12562             } finally {
12563                 Binder.restoreCallingIdentity(ident);
12564             }
12565         }
12566     }
12567
12568     @Override
12569     public void stopAppSwitches() {
12570         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12571                 != PackageManager.PERMISSION_GRANTED) {
12572             throw new SecurityException("viewquires permission "
12573                     + android.Manifest.permission.STOP_APP_SWITCHES);
12574         }
12575
12576         synchronized(this) {
12577             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12578                     + APP_SWITCH_DELAY_TIME;
12579             mDidAppSwitch = false;
12580             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12581             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12582             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12583         }
12584     }
12585
12586     public void resumeAppSwitches() {
12587         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12588                 != PackageManager.PERMISSION_GRANTED) {
12589             throw new SecurityException("Requires permission "
12590                     + android.Manifest.permission.STOP_APP_SWITCHES);
12591         }
12592
12593         synchronized(this) {
12594             // Note that we don't execute any pending app switches... we will
12595             // let those wait until either the timeout, or the next start
12596             // activity request.
12597             mAppSwitchesAllowedTime = 0;
12598         }
12599     }
12600
12601     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12602             int callingPid, int callingUid, String name) {
12603         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12604             return true;
12605         }
12606
12607         int perm = checkComponentPermission(
12608                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12609                 sourceUid, -1, true);
12610         if (perm == PackageManager.PERMISSION_GRANTED) {
12611             return true;
12612         }
12613
12614         // If the actual IPC caller is different from the logical source, then
12615         // also see if they are allowed to control app switches.
12616         if (callingUid != -1 && callingUid != sourceUid) {
12617             perm = checkComponentPermission(
12618                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12619                     callingUid, -1, true);
12620             if (perm == PackageManager.PERMISSION_GRANTED) {
12621                 return true;
12622             }
12623         }
12624
12625         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12626         return false;
12627     }
12628
12629     public void setDebugApp(String packageName, boolean waitForDebugger,
12630             boolean persistent) {
12631         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12632                 "setDebugApp()");
12633
12634         long ident = Binder.clearCallingIdentity();
12635         try {
12636             // Note that this is not really thread safe if there are multiple
12637             // callers into it at the same time, but that's not a situation we
12638             // care about.
12639             if (persistent) {
12640                 final ContentResolver resolver = mContext.getContentResolver();
12641                 Settings.Global.putString(
12642                     resolver, Settings.Global.DEBUG_APP,
12643                     packageName);
12644                 Settings.Global.putInt(
12645                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12646                     waitForDebugger ? 1 : 0);
12647             }
12648
12649             synchronized (this) {
12650                 if (!persistent) {
12651                     mOrigDebugApp = mDebugApp;
12652                     mOrigWaitForDebugger = mWaitForDebugger;
12653                 }
12654                 mDebugApp = packageName;
12655                 mWaitForDebugger = waitForDebugger;
12656                 mDebugTransient = !persistent;
12657                 if (packageName != null) {
12658                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12659                             false, UserHandle.USER_ALL, "set debug app");
12660                 }
12661             }
12662         } finally {
12663             Binder.restoreCallingIdentity(ident);
12664         }
12665     }
12666
12667     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12668         synchronized (this) {
12669             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12670             if (!isDebuggable) {
12671                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12672                     throw new SecurityException("Process not debuggable: " + app.packageName);
12673                 }
12674             }
12675
12676             mTrackAllocationApp = processName;
12677         }
12678     }
12679
12680     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12681         synchronized (this) {
12682             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12683             if (!isDebuggable) {
12684                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12685                     throw new SecurityException("Process not debuggable: " + app.packageName);
12686                 }
12687             }
12688             mProfileApp = processName;
12689             mProfileFile = profilerInfo.profileFile;
12690             if (mProfileFd != null) {
12691                 try {
12692                     mProfileFd.close();
12693                 } catch (IOException e) {
12694                 }
12695                 mProfileFd = null;
12696             }
12697             mProfileFd = profilerInfo.profileFd;
12698             mSamplingInterval = profilerInfo.samplingInterval;
12699             mAutoStopProfiler = profilerInfo.autoStopProfiler;
12700             mStreamingOutput = profilerInfo.streamingOutput;
12701             mProfileType = 0;
12702         }
12703     }
12704
12705     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12706         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12707         if (!isDebuggable) {
12708             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12709                 throw new SecurityException("Process not debuggable: " + app.packageName);
12710             }
12711         }
12712         mNativeDebuggingApp = processName;
12713     }
12714
12715     @Override
12716     public void setAlwaysFinish(boolean enabled) {
12717         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12718                 "setAlwaysFinish()");
12719
12720         long ident = Binder.clearCallingIdentity();
12721         try {
12722             Settings.Global.putInt(
12723                     mContext.getContentResolver(),
12724                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12725
12726             synchronized (this) {
12727                 mAlwaysFinishActivities = enabled;
12728             }
12729         } finally {
12730             Binder.restoreCallingIdentity(ident);
12731         }
12732     }
12733
12734     @Override
12735     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12736         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12737                 "setActivityController()");
12738         synchronized (this) {
12739             mController = controller;
12740             mControllerIsAMonkey = imAMonkey;
12741             Watchdog.getInstance().setActivityController(controller);
12742         }
12743     }
12744
12745     @Override
12746     public void setUserIsMonkey(boolean userIsMonkey) {
12747         synchronized (this) {
12748             synchronized (mPidsSelfLocked) {
12749                 final int callingPid = Binder.getCallingPid();
12750                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12751                 if (proc == null) {
12752                     throw new SecurityException("Unknown process: " + callingPid);
12753                 }
12754                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12755                     throw new SecurityException("Only an instrumentation process "
12756                             + "with a UiAutomation can call setUserIsMonkey");
12757                 }
12758             }
12759             mUserIsMonkey = userIsMonkey;
12760         }
12761     }
12762
12763     @Override
12764     public boolean isUserAMonkey() {
12765         synchronized (this) {
12766             // If there is a controller also implies the user is a monkey.
12767             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12768         }
12769     }
12770
12771     /**
12772      * @deprecated This method is only used by a few internal components and it will soon be
12773      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12774      * No new code should be calling it.
12775      */
12776     @Deprecated
12777     @Override
12778     public void requestBugReport(int bugreportType) {
12779         String extraOptions = null;
12780         switch (bugreportType) {
12781             case ActivityManager.BUGREPORT_OPTION_FULL:
12782                 // Default options.
12783                 break;
12784             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12785                 extraOptions = "bugreportplus";
12786                 break;
12787             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12788                 extraOptions = "bugreportremote";
12789                 break;
12790             case ActivityManager.BUGREPORT_OPTION_WEAR:
12791                 extraOptions = "bugreportwear";
12792                 break;
12793             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12794                 extraOptions = "bugreporttelephony";
12795                 break;
12796             default:
12797                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12798                         + bugreportType);
12799         }
12800         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12801         if (extraOptions != null) {
12802             SystemProperties.set("dumpstate.options", extraOptions);
12803         }
12804         SystemProperties.set("ctl.start", "bugreport");
12805     }
12806
12807     /**
12808      * @deprecated This method is only used by a few internal components and it will soon be
12809      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12810      * No new code should be calling it.
12811      */
12812     @Deprecated
12813     @Override
12814     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12815
12816         if (!TextUtils.isEmpty(shareTitle)) {
12817             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12818                 String errorStr = "shareTitle should be less than " +
12819                         MAX_BUGREPORT_TITLE_SIZE + " characters";
12820                 throw new IllegalArgumentException(errorStr);
12821             } else {
12822                 if (!TextUtils.isEmpty(shareDescription)) {
12823                     int length;
12824                     try {
12825                         length = shareDescription.getBytes("UTF-8").length;
12826                     } catch (UnsupportedEncodingException e) {
12827                         String errorStr = "shareDescription: UnsupportedEncodingException";
12828                         throw new IllegalArgumentException(errorStr);
12829                     }
12830                     if (length > SystemProperties.PROP_VALUE_MAX) {
12831                         String errorStr = "shareTitle should be less than " +
12832                                 SystemProperties.PROP_VALUE_MAX + " bytes";
12833                         throw new IllegalArgumentException(errorStr);
12834                     } else {
12835                         SystemProperties.set("dumpstate.options.description", shareDescription);
12836                     }
12837                 }
12838                 SystemProperties.set("dumpstate.options.title", shareTitle);
12839             }
12840         }
12841
12842         Slog.d(TAG, "Bugreport notification title " + shareTitle
12843                 + " description " + shareDescription);
12844         requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12845     }
12846
12847     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12848         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12849     }
12850
12851     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12852         if (r != null && (r.instr != null || r.usingWrapper)) {
12853             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12854         }
12855         return KEY_DISPATCHING_TIMEOUT;
12856     }
12857
12858     @Override
12859     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12860         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12861                 != PackageManager.PERMISSION_GRANTED) {
12862             throw new SecurityException("Requires permission "
12863                     + android.Manifest.permission.FILTER_EVENTS);
12864         }
12865         ProcessRecord proc;
12866         long timeout;
12867         synchronized (this) {
12868             synchronized (mPidsSelfLocked) {
12869                 proc = mPidsSelfLocked.get(pid);
12870             }
12871             timeout = getInputDispatchingTimeoutLocked(proc);
12872         }
12873
12874         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12875             return -1;
12876         }
12877
12878         return timeout;
12879     }
12880
12881     /**
12882      * Handle input dispatching timeouts.
12883      * Returns whether input dispatching should be aborted or not.
12884      */
12885     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12886             final ActivityRecord activity, final ActivityRecord parent,
12887             final boolean aboveSystem, String reason) {
12888         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12889                 != PackageManager.PERMISSION_GRANTED) {
12890             throw new SecurityException("Requires permission "
12891                     + android.Manifest.permission.FILTER_EVENTS);
12892         }
12893
12894         final String annotation;
12895         if (reason == null) {
12896             annotation = "Input dispatching timed out";
12897         } else {
12898             annotation = "Input dispatching timed out (" + reason + ")";
12899         }
12900
12901         if (proc != null) {
12902             synchronized (this) {
12903                 if (proc.debugging) {
12904                     return false;
12905                 }
12906
12907                 if (mDidDexOpt) {
12908                     // Give more time since we were dexopting.
12909                     mDidDexOpt = false;
12910                     return false;
12911                 }
12912
12913                 if (proc.instr != null) {
12914                     Bundle info = new Bundle();
12915                     info.putString("shortMsg", "keyDispatchingTimedOut");
12916                     info.putString("longMsg", annotation);
12917                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12918                     return true;
12919                 }
12920             }
12921             mHandler.post(new Runnable() {
12922                 @Override
12923                 public void run() {
12924                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12925                 }
12926             });
12927         }
12928
12929         return true;
12930     }
12931
12932     @Override
12933     public Bundle getAssistContextExtras(int requestType) {
12934         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12935                 null, null, true /* focused */, true /* newSessionId */,
12936                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12937         if (pae == null) {
12938             return null;
12939         }
12940         synchronized (pae) {
12941             while (!pae.haveResult) {
12942                 try {
12943                     pae.wait();
12944                 } catch (InterruptedException e) {
12945                 }
12946             }
12947         }
12948         synchronized (this) {
12949             buildAssistBundleLocked(pae, pae.result);
12950             mPendingAssistExtras.remove(pae);
12951             mUiHandler.removeCallbacks(pae);
12952         }
12953         return pae.extras;
12954     }
12955
12956     @Override
12957     public boolean isAssistDataAllowedOnCurrentActivity() {
12958         int userId;
12959         synchronized (this) {
12960             final ActivityStack focusedStack = getFocusedStack();
12961             if (focusedStack == null || focusedStack.isAssistantStack()) {
12962                 return false;
12963             }
12964
12965             final ActivityRecord activity = focusedStack.topActivity();
12966             if (activity == null) {
12967                 return false;
12968             }
12969             userId = activity.userId;
12970         }
12971         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12972                 Context.DEVICE_POLICY_SERVICE);
12973         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12974     }
12975
12976     @Override
12977     public boolean showAssistFromActivity(IBinder token, Bundle args) {
12978         long ident = Binder.clearCallingIdentity();
12979         try {
12980             synchronized (this) {
12981                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12982                 ActivityRecord top = getFocusedStack().topActivity();
12983                 if (top != caller) {
12984                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12985                             + " is not current top " + top);
12986                     return false;
12987                 }
12988                 if (!top.nowVisible) {
12989                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12990                             + " is not visible");
12991                     return false;
12992                 }
12993             }
12994             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12995                     token);
12996         } finally {
12997             Binder.restoreCallingIdentity(ident);
12998         }
12999     }
13000
13001     @Override
13002     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13003             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13004         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13005                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13006                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13007     }
13008
13009     @Override
13010     public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13011             IBinder activityToken, int flags) {
13012         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13013                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13014                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13015     }
13016
13017     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13018             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13019             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13020             int flags) {
13021         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13022                 "enqueueAssistContext()");
13023
13024         synchronized (this) {
13025             ActivityRecord activity = getFocusedStack().topActivity();
13026             if (activity == null) {
13027                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13028                 return null;
13029             }
13030             if (activity.app == null || activity.app.thread == null) {
13031                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13032                 return null;
13033             }
13034             if (focused) {
13035                 if (activityToken != null) {
13036                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13037                     if (activity != caller) {
13038                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13039                                 + " is not current top " + activity);
13040                         return null;
13041                     }
13042                 }
13043             } else {
13044                 activity = ActivityRecord.forTokenLocked(activityToken);
13045                 if (activity == null) {
13046                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13047                             + " couldn't be found");
13048                     return null;
13049                 }
13050             }
13051
13052             PendingAssistExtras pae;
13053             Bundle extras = new Bundle();
13054             if (args != null) {
13055                 extras.putAll(args);
13056             }
13057             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13058             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13059
13060             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13061                     userHandle);
13062             pae.isHome = activity.isHomeActivity();
13063
13064             // Increment the sessionId if necessary
13065             if (newSessionId) {
13066                 mViSessionId++;
13067             }
13068             try {
13069                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13070                         mViSessionId, flags);
13071                 mPendingAssistExtras.add(pae);
13072                 mUiHandler.postDelayed(pae, timeout);
13073             } catch (RemoteException e) {
13074                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13075                 return null;
13076             }
13077             return pae;
13078         }
13079     }
13080
13081     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13082         IResultReceiver receiver;
13083         synchronized (this) {
13084             mPendingAssistExtras.remove(pae);
13085             receiver = pae.receiver;
13086         }
13087         if (receiver != null) {
13088             // Caller wants result sent back to them.
13089             Bundle sendBundle = new Bundle();
13090             // At least return the receiver extras
13091             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13092                     pae.receiverExtras);
13093             try {
13094                 pae.receiver.send(0, sendBundle);
13095             } catch (RemoteException e) {
13096             }
13097         }
13098     }
13099
13100     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13101         if (result != null) {
13102             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13103         }
13104         if (pae.hint != null) {
13105             pae.extras.putBoolean(pae.hint, true);
13106         }
13107     }
13108
13109     /** Called from an app when assist data is ready. */
13110     @Override
13111     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13112             AssistContent content, Uri referrer) {
13113         PendingAssistExtras pae = (PendingAssistExtras)token;
13114         synchronized (pae) {
13115             pae.result = extras;
13116             pae.structure = structure;
13117             pae.content = content;
13118             if (referrer != null) {
13119                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13120             }
13121             if (structure != null) {
13122                 structure.setHomeActivity(pae.isHome);
13123             }
13124             pae.haveResult = true;
13125             pae.notifyAll();
13126             if (pae.intent == null && pae.receiver == null) {
13127                 // Caller is just waiting for the result.
13128                 return;
13129             }
13130         }
13131         // We are now ready to launch the assist activity.
13132         IResultReceiver sendReceiver = null;
13133         Bundle sendBundle = null;
13134         synchronized (this) {
13135             buildAssistBundleLocked(pae, extras);
13136             boolean exists = mPendingAssistExtras.remove(pae);
13137             mUiHandler.removeCallbacks(pae);
13138             if (!exists) {
13139                 // Timed out.
13140                 return;
13141             }
13142             if ((sendReceiver=pae.receiver) != null) {
13143                 // Caller wants result sent back to them.
13144                 sendBundle = new Bundle();
13145                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13146                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13147                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13148                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13149                         pae.receiverExtras);
13150             }
13151         }
13152         if (sendReceiver != null) {
13153             try {
13154                 sendReceiver.send(0, sendBundle);
13155             } catch (RemoteException e) {
13156             }
13157             return;
13158         }
13159
13160         final long ident = Binder.clearCallingIdentity();
13161         try {
13162             if (TextUtils.equals(pae.intent.getAction(),
13163                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13164                 pae.intent.putExtras(pae.extras);
13165                 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13166             } else {
13167                 pae.intent.replaceExtras(pae.extras);
13168                 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13169                         | Intent.FLAG_ACTIVITY_SINGLE_TOP
13170                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13171                 closeSystemDialogs("assist");
13172
13173                 try {
13174                     mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13175                 } catch (ActivityNotFoundException e) {
13176                     Slog.w(TAG, "No activity to handle assist action.", e);
13177                 }
13178             }
13179         } finally {
13180             Binder.restoreCallingIdentity(ident);
13181         }
13182     }
13183
13184     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13185             Bundle args) {
13186         return enqueueAssistContext(requestType, intent, hint, null, null, null,
13187                 true /* focused */, true /* newSessionId */, userHandle, args,
13188                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13189     }
13190
13191     public void registerProcessObserver(IProcessObserver observer) {
13192         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13193                 "registerProcessObserver()");
13194         synchronized (this) {
13195             mProcessObservers.register(observer);
13196         }
13197     }
13198
13199     @Override
13200     public void unregisterProcessObserver(IProcessObserver observer) {
13201         synchronized (this) {
13202             mProcessObservers.unregister(observer);
13203         }
13204     }
13205
13206     @Override
13207     public int getUidProcessState(int uid, String callingPackage) {
13208         if (!hasUsageStatsPermission(callingPackage)) {
13209             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13210                     "getUidProcessState");
13211         }
13212
13213         synchronized (this) {
13214             UidRecord uidRec = mActiveUids.get(uid);
13215             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13216         }
13217     }
13218
13219     @Override
13220     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13221             String callingPackage) {
13222         if (!hasUsageStatsPermission(callingPackage)) {
13223             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13224                     "registerUidObserver");
13225         }
13226         synchronized (this) {
13227             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13228                     callingPackage, which, cutpoint));
13229         }
13230     }
13231
13232     @Override
13233     public void unregisterUidObserver(IUidObserver observer) {
13234         synchronized (this) {
13235             mUidObservers.unregister(observer);
13236         }
13237     }
13238
13239     @Override
13240     public boolean convertFromTranslucent(IBinder token) {
13241         final long origId = Binder.clearCallingIdentity();
13242         try {
13243             synchronized (this) {
13244                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13245                 if (r == null) {
13246                     return false;
13247                 }
13248                 final boolean translucentChanged = r.changeWindowTranslucency(true);
13249                 if (translucentChanged) {
13250                     r.getStack().releaseBackgroundResources(r);
13251                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13252                 }
13253                 mWindowManager.setAppFullscreen(token, true);
13254                 return translucentChanged;
13255             }
13256         } finally {
13257             Binder.restoreCallingIdentity(origId);
13258         }
13259     }
13260
13261     @Override
13262     public boolean convertToTranslucent(IBinder token, Bundle options) {
13263         final long origId = Binder.clearCallingIdentity();
13264         try {
13265             synchronized (this) {
13266                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13267                 if (r == null) {
13268                     return false;
13269                 }
13270                 final TaskRecord task = r.getTask();
13271                 int index = task.mActivities.lastIndexOf(r);
13272                 if (index > 0) {
13273                     ActivityRecord under = task.mActivities.get(index - 1);
13274                     under.returningOptions = ActivityOptions.fromBundle(options);
13275                 }
13276                 final boolean translucentChanged = r.changeWindowTranslucency(false);
13277                 if (translucentChanged) {
13278                     r.getStack().convertActivityToTranslucent(r);
13279                 }
13280                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13281                 mWindowManager.setAppFullscreen(token, false);
13282                 return translucentChanged;
13283             }
13284         } finally {
13285             Binder.restoreCallingIdentity(origId);
13286         }
13287     }
13288
13289     @Override
13290     public boolean requestVisibleBehind(IBinder token, boolean visible) {
13291         final long origId = Binder.clearCallingIdentity();
13292         try {
13293             synchronized (this) {
13294                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13295                 if (r != null) {
13296                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13297                 }
13298             }
13299             return false;
13300         } finally {
13301             Binder.restoreCallingIdentity(origId);
13302         }
13303     }
13304
13305     @Override
13306     public boolean isBackgroundVisibleBehind(IBinder token) {
13307         final long origId = Binder.clearCallingIdentity();
13308         try {
13309             synchronized (this) {
13310                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
13311                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13312                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13313                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13314                 return visible;
13315             }
13316         } finally {
13317             Binder.restoreCallingIdentity(origId);
13318         }
13319     }
13320
13321     @Override
13322     public Bundle getActivityOptions(IBinder token) {
13323         final long origId = Binder.clearCallingIdentity();
13324         try {
13325             synchronized (this) {
13326                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13327                 if (r != null) {
13328                     final ActivityOptions activityOptions = r.pendingOptions;
13329                     r.pendingOptions = null;
13330                     return activityOptions == null ? null : activityOptions.toBundle();
13331                 }
13332                 return null;
13333             }
13334         } finally {
13335             Binder.restoreCallingIdentity(origId);
13336         }
13337     }
13338
13339     @Override
13340     public void setImmersive(IBinder token, boolean immersive) {
13341         synchronized(this) {
13342             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13343             if (r == null) {
13344                 throw new IllegalArgumentException();
13345             }
13346             r.immersive = immersive;
13347
13348             // update associated state if we're frontmost
13349             if (r == mStackSupervisor.getResumedActivityLocked()) {
13350                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13351                 applyUpdateLockStateLocked(r);
13352             }
13353         }
13354     }
13355
13356     @Override
13357     public boolean isImmersive(IBinder token) {
13358         synchronized (this) {
13359             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13360             if (r == null) {
13361                 throw new IllegalArgumentException();
13362             }
13363             return r.immersive;
13364         }
13365     }
13366
13367     @Override
13368     public void setVrThread(int tid) {
13369         enforceSystemHasVrFeature();
13370         synchronized (this) {
13371             synchronized (mPidsSelfLocked) {
13372                 final int pid = Binder.getCallingPid();
13373                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13374                 mVrController.setVrThreadLocked(tid, pid, proc);
13375             }
13376         }
13377     }
13378
13379     @Override
13380     public void setPersistentVrThread(int tid) {
13381         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13382             final String msg = "Permission Denial: setPersistentVrThread() from pid="
13383                     + Binder.getCallingPid()
13384                     + ", uid=" + Binder.getCallingUid()
13385                     + " requires " + permission.RESTRICTED_VR_ACCESS;
13386             Slog.w(TAG, msg);
13387             throw new SecurityException(msg);
13388         }
13389         enforceSystemHasVrFeature();
13390         synchronized (this) {
13391             synchronized (mPidsSelfLocked) {
13392                 final int pid = Binder.getCallingPid();
13393                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13394                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13395             }
13396         }
13397     }
13398
13399     /**
13400      * Schedule the given thread a normal scheduling priority.
13401      *
13402      * @param newTid the tid of the thread to adjust the scheduling of.
13403      * @param suppressLogs {@code true} if any error logging should be disabled.
13404      *
13405      * @return {@code true} if this succeeded.
13406      */
13407     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13408         try {
13409             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13410             return true;
13411         } catch (IllegalArgumentException e) {
13412             if (!suppressLogs) {
13413                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13414             }
13415         }
13416         return false;
13417     }
13418
13419     /**
13420      * Schedule the given thread an FIFO scheduling priority.
13421      *
13422      * @param newTid the tid of the thread to adjust the scheduling of.
13423      * @param suppressLogs {@code true} if any error logging should be disabled.
13424      *
13425      * @return {@code true} if this succeeded.
13426      */
13427     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13428         try {
13429             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13430             return true;
13431         } catch (IllegalArgumentException e) {
13432             if (!suppressLogs) {
13433                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13434             }
13435         }
13436         return false;
13437     }
13438
13439     /**
13440      * Check that we have the features required for VR-related API calls, and throw an exception if
13441      * not.
13442      */
13443     private void enforceSystemHasVrFeature() {
13444         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13445             throw new UnsupportedOperationException("VR mode not supported on this device!");
13446         }
13447     }
13448
13449     @Override
13450     public void setRenderThread(int tid) {
13451         synchronized (this) {
13452             ProcessRecord proc;
13453             int pid = Binder.getCallingPid();
13454             if (pid == Process.myPid()) {
13455                 demoteSystemServerRenderThread(tid);
13456                 return;
13457             }
13458             synchronized (mPidsSelfLocked) {
13459                 proc = mPidsSelfLocked.get(pid);
13460                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13461                     // ensure the tid belongs to the process
13462                     if (!isThreadInProcess(pid, tid)) {
13463                         throw new IllegalArgumentException(
13464                             "Render thread does not belong to process");
13465                     }
13466                     proc.renderThreadTid = tid;
13467                     if (DEBUG_OOM_ADJ) {
13468                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13469                     }
13470                     // promote to FIFO now
13471                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13472                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13473                         if (mUseFifoUiScheduling) {
13474                             setThreadScheduler(proc.renderThreadTid,
13475                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13476                         } else {
13477                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13478                         }
13479                     }
13480                 } else {
13481                     if (DEBUG_OOM_ADJ) {
13482                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13483                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
13484                                mUseFifoUiScheduling);
13485                     }
13486                 }
13487             }
13488         }
13489     }
13490
13491     /**
13492      * We only use RenderThread in system_server to store task snapshots to the disk, which should
13493      * happen in the background. Thus, demote render thread from system_server to a lower priority.
13494      *
13495      * @param tid the tid of the RenderThread
13496      */
13497     private void demoteSystemServerRenderThread(int tid) {
13498         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13499     }
13500
13501     @Override
13502     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13503         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13504             throw new UnsupportedOperationException("VR mode not supported on this device!");
13505         }
13506
13507         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13508
13509         ActivityRecord r;
13510         synchronized (this) {
13511             r = ActivityRecord.isInStackLocked(token);
13512         }
13513
13514         if (r == null) {
13515             throw new IllegalArgumentException();
13516         }
13517
13518         int err;
13519         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13520                 VrManagerInternal.NO_ERROR) {
13521             return err;
13522         }
13523
13524         synchronized(this) {
13525             r.requestedVrComponent = (enabled) ? packageName : null;
13526
13527             // Update associated state if this activity is currently focused
13528             if (r == mStackSupervisor.getResumedActivityLocked()) {
13529                 applyUpdateVrModeLocked(r);
13530             }
13531             return 0;
13532         }
13533     }
13534
13535     @Override
13536     public boolean isVrModePackageEnabled(ComponentName packageName) {
13537         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13538             throw new UnsupportedOperationException("VR mode not supported on this device!");
13539         }
13540
13541         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13542
13543         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13544                 VrManagerInternal.NO_ERROR;
13545     }
13546
13547     public boolean isTopActivityImmersive() {
13548         enforceNotIsolatedCaller("startActivity");
13549         synchronized (this) {
13550             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13551             return (r != null) ? r.immersive : false;
13552         }
13553     }
13554
13555     /**
13556      * @return whether the system should disable UI modes incompatible with VR mode.
13557      */
13558     boolean shouldDisableNonVrUiLocked() {
13559         return mVrController.shouldDisableNonVrUiLocked();
13560     }
13561
13562     @Override
13563     public boolean isTopOfTask(IBinder token) {
13564         synchronized (this) {
13565             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13566             if (r == null) {
13567                 throw new IllegalArgumentException();
13568             }
13569             return r.getTask().getTopActivity() == r;
13570         }
13571     }
13572
13573     @Override
13574     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13575         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13576             String msg = "Permission Denial: setHasTopUi() from pid="
13577                     + Binder.getCallingPid()
13578                     + ", uid=" + Binder.getCallingUid()
13579                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13580             Slog.w(TAG, msg);
13581             throw new SecurityException(msg);
13582         }
13583         final int pid = Binder.getCallingPid();
13584         final long origId = Binder.clearCallingIdentity();
13585         try {
13586             synchronized (this) {
13587                 boolean changed = false;
13588                 ProcessRecord pr;
13589                 synchronized (mPidsSelfLocked) {
13590                     pr = mPidsSelfLocked.get(pid);
13591                     if (pr == null) {
13592                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13593                         return;
13594                     }
13595                     if (pr.hasTopUi != hasTopUi) {
13596                         if (DEBUG_OOM_ADJ) {
13597                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13598                         }
13599                         pr.hasTopUi = hasTopUi;
13600                         changed = true;
13601                     }
13602                 }
13603                 if (changed) {
13604                     updateOomAdjLocked(pr, true);
13605                 }
13606             }
13607         } finally {
13608             Binder.restoreCallingIdentity(origId);
13609         }
13610     }
13611
13612     public final void enterSafeMode() {
13613         synchronized(this) {
13614             // It only makes sense to do this before the system is ready
13615             // and started launching other packages.
13616             if (!mSystemReady) {
13617                 try {
13618                     AppGlobals.getPackageManager().enterSafeMode();
13619                 } catch (RemoteException e) {
13620                 }
13621             }
13622
13623             mSafeMode = true;
13624         }
13625     }
13626
13627     public final void showSafeModeOverlay() {
13628         View v = LayoutInflater.from(mContext).inflate(
13629                 com.android.internal.R.layout.safe_mode, null);
13630         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13631         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13632         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13633         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13634         lp.gravity = Gravity.BOTTOM | Gravity.START;
13635         lp.format = v.getBackground().getOpacity();
13636         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13637                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13638         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13639         ((WindowManager)mContext.getSystemService(
13640                 Context.WINDOW_SERVICE)).addView(v, lp);
13641     }
13642
13643     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13644         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13645             return;
13646         }
13647         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13648         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13649         synchronized (stats) {
13650             if (mBatteryStatsService.isOnBattery()) {
13651                 mBatteryStatsService.enforceCallingPermission();
13652                 int MY_UID = Binder.getCallingUid();
13653                 final int uid;
13654                 if (sender == null) {
13655                     uid = sourceUid;
13656                 } else {
13657                     uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13658                 }
13659                 BatteryStatsImpl.Uid.Pkg pkg =
13660                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13661                             sourcePkg != null ? sourcePkg : rec.key.packageName);
13662                 pkg.noteWakeupAlarmLocked(tag);
13663             }
13664         }
13665     }
13666
13667     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13668         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13669             return;
13670         }
13671         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13672         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13673         synchronized (stats) {
13674             mBatteryStatsService.enforceCallingPermission();
13675             int MY_UID = Binder.getCallingUid();
13676             final int uid;
13677             if (sender == null) {
13678                 uid = sourceUid;
13679             } else {
13680                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13681             }
13682             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13683         }
13684     }
13685
13686     public void noteAlarmFinish(IIntentSender sender, int sourceUid, 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             mBatteryStatsService.enforceCallingPermission();
13694             int MY_UID = Binder.getCallingUid();
13695             final int uid;
13696             if (sender == null) {
13697                 uid = sourceUid;
13698             } else {
13699                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13700             }
13701             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13702         }
13703     }
13704
13705     public boolean killPids(int[] pids, String pReason, boolean secure) {
13706         if (Binder.getCallingUid() != SYSTEM_UID) {
13707             throw new SecurityException("killPids only available to the system");
13708         }
13709         String reason = (pReason == null) ? "Unknown" : pReason;
13710         // XXX Note: don't acquire main activity lock here, because the window
13711         // manager calls in with its locks held.
13712
13713         boolean killed = false;
13714         synchronized (mPidsSelfLocked) {
13715             int worstType = 0;
13716             for (int i=0; i<pids.length; i++) {
13717                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13718                 if (proc != null) {
13719                     int type = proc.setAdj;
13720                     if (type > worstType) {
13721                         worstType = type;
13722                     }
13723                 }
13724             }
13725
13726             // If the worst oom_adj is somewhere in the cached proc LRU range,
13727             // then constrain it so we will kill all cached procs.
13728             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13729                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13730                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13731             }
13732
13733             // If this is not a secure call, don't let it kill processes that
13734             // are important.
13735             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13736                 worstType = ProcessList.SERVICE_ADJ;
13737             }
13738
13739             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13740             for (int i=0; i<pids.length; i++) {
13741                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13742                 if (proc == null) {
13743                     continue;
13744                 }
13745                 int adj = proc.setAdj;
13746                 if (adj >= worstType && !proc.killedByAm) {
13747                     proc.kill(reason, true);
13748                     killed = true;
13749                 }
13750             }
13751         }
13752         return killed;
13753     }
13754
13755     @Override
13756     public void killUid(int appId, int userId, String reason) {
13757         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13758         synchronized (this) {
13759             final long identity = Binder.clearCallingIdentity();
13760             try {
13761                 killPackageProcessesLocked(null, appId, userId,
13762                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13763                         reason != null ? reason : "kill uid");
13764             } finally {
13765                 Binder.restoreCallingIdentity(identity);
13766             }
13767         }
13768     }
13769
13770     @Override
13771     public boolean killProcessesBelowForeground(String reason) {
13772         if (Binder.getCallingUid() != SYSTEM_UID) {
13773             throw new SecurityException("killProcessesBelowForeground() only available to system");
13774         }
13775
13776         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13777     }
13778
13779     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13780         if (Binder.getCallingUid() != SYSTEM_UID) {
13781             throw new SecurityException("killProcessesBelowAdj() only available to system");
13782         }
13783
13784         boolean killed = false;
13785         synchronized (mPidsSelfLocked) {
13786             final int size = mPidsSelfLocked.size();
13787             for (int i = 0; i < size; i++) {
13788                 final int pid = mPidsSelfLocked.keyAt(i);
13789                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13790                 if (proc == null) continue;
13791
13792                 final int adj = proc.setAdj;
13793                 if (adj > belowAdj && !proc.killedByAm) {
13794                     proc.kill(reason, true);
13795                     killed = true;
13796                 }
13797             }
13798         }
13799         return killed;
13800     }
13801
13802     @Override
13803     public void hang(final IBinder who, boolean allowRestart) {
13804         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13805                 != PackageManager.PERMISSION_GRANTED) {
13806             throw new SecurityException("Requires permission "
13807                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13808         }
13809
13810         final IBinder.DeathRecipient death = new DeathRecipient() {
13811             @Override
13812             public void binderDied() {
13813                 synchronized (this) {
13814                     notifyAll();
13815                 }
13816             }
13817         };
13818
13819         try {
13820             who.linkToDeath(death, 0);
13821         } catch (RemoteException e) {
13822             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13823             return;
13824         }
13825
13826         synchronized (this) {
13827             Watchdog.getInstance().setAllowRestart(allowRestart);
13828             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13829             synchronized (death) {
13830                 while (who.isBinderAlive()) {
13831                     try {
13832                         death.wait();
13833                     } catch (InterruptedException e) {
13834                     }
13835                 }
13836             }
13837             Watchdog.getInstance().setAllowRestart(true);
13838         }
13839     }
13840
13841     @Override
13842     public void restart() {
13843         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13844                 != PackageManager.PERMISSION_GRANTED) {
13845             throw new SecurityException("Requires permission "
13846                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13847         }
13848
13849         Log.i(TAG, "Sending shutdown broadcast...");
13850
13851         BroadcastReceiver br = new BroadcastReceiver() {
13852             @Override public void onReceive(Context context, Intent intent) {
13853                 // Now the broadcast is done, finish up the low-level shutdown.
13854                 Log.i(TAG, "Shutting down activity manager...");
13855                 shutdown(10000);
13856                 Log.i(TAG, "Shutdown complete, restarting!");
13857                 killProcess(myPid());
13858                 System.exit(10);
13859             }
13860         };
13861
13862         // First send the high-level shut down broadcast.
13863         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13864         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13865         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13866         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13867         mContext.sendOrderedBroadcastAsUser(intent,
13868                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13869         */
13870         br.onReceive(mContext, intent);
13871     }
13872
13873     private long getLowRamTimeSinceIdle(long now) {
13874         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13875     }
13876
13877     @Override
13878     public void performIdleMaintenance() {
13879         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13880                 != PackageManager.PERMISSION_GRANTED) {
13881             throw new SecurityException("Requires permission "
13882                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13883         }
13884
13885         synchronized (this) {
13886             final long now = SystemClock.uptimeMillis();
13887             final long timeSinceLastIdle = now - mLastIdleTime;
13888             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13889             mLastIdleTime = now;
13890             mLowRamTimeSinceLastIdle = 0;
13891             if (mLowRamStartTime != 0) {
13892                 mLowRamStartTime = now;
13893             }
13894
13895             StringBuilder sb = new StringBuilder(128);
13896             sb.append("Idle maintenance over ");
13897             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13898             sb.append(" low RAM for ");
13899             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13900             Slog.i(TAG, sb.toString());
13901
13902             // If at least 1/3 of our time since the last idle period has been spent
13903             // with RAM low, then we want to kill processes.
13904             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13905
13906             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13907                 ProcessRecord proc = mLruProcesses.get(i);
13908                 if (proc.notCachedSinceIdle) {
13909                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13910                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13911                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13912                         if (doKilling && proc.initialIdlePss != 0
13913                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13914                             sb = new StringBuilder(128);
13915                             sb.append("Kill");
13916                             sb.append(proc.processName);
13917                             sb.append(" in idle maint: pss=");
13918                             sb.append(proc.lastPss);
13919                             sb.append(", swapPss=");
13920                             sb.append(proc.lastSwapPss);
13921                             sb.append(", initialPss=");
13922                             sb.append(proc.initialIdlePss);
13923                             sb.append(", period=");
13924                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13925                             sb.append(", lowRamPeriod=");
13926                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13927                             Slog.wtfQuiet(TAG, sb.toString());
13928                             proc.kill("idle maint (pss " + proc.lastPss
13929                                     + " from " + proc.initialIdlePss + ")", true);
13930                         }
13931                     }
13932                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13933                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13934                     proc.notCachedSinceIdle = true;
13935                     proc.initialIdlePss = 0;
13936                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13937                             mTestPssMode, isSleepingLocked(), now);
13938                 }
13939             }
13940
13941             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13942             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13943         }
13944     }
13945
13946     @Override
13947     public void sendIdleJobTrigger() {
13948         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13949                 != PackageManager.PERMISSION_GRANTED) {
13950             throw new SecurityException("Requires permission "
13951                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13952         }
13953
13954         final long ident = Binder.clearCallingIdentity();
13955         try {
13956             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13957                     .setPackage("android")
13958                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13959             broadcastIntent(null, intent, null, null, 0, null, null, null,
13960                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13961         } finally {
13962             Binder.restoreCallingIdentity(ident);
13963         }
13964     }
13965
13966     private void retrieveSettings() {
13967         final ContentResolver resolver = mContext.getContentResolver();
13968         final boolean freeformWindowManagement =
13969                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13970                         || Settings.Global.getInt(
13971                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13972         final boolean supportsPictureInPicture =
13973                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13974
13975         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
13976         final boolean supportsSplitScreenMultiWindow =
13977                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
13978         final boolean supportsMultiDisplay = mContext.getPackageManager()
13979                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
13980         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13981         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13982         final boolean alwaysFinishActivities =
13983                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13984         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13985         final boolean forceResizable = Settings.Global.getInt(
13986                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13987         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
13988                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
13989         final boolean supportsLeanbackOnly =
13990                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13991
13992         // Transfer any global setting for forcing RTL layout, into a System Property
13993         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13994
13995         final Configuration configuration = new Configuration();
13996         Settings.System.getConfiguration(resolver, configuration);
13997         if (forceRtl) {
13998             // This will take care of setting the correct layout direction flags
13999             configuration.setLayoutDirection(configuration.locale);
14000         }
14001
14002         synchronized (this) {
14003             mDebugApp = mOrigDebugApp = debugApp;
14004             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14005             mAlwaysFinishActivities = alwaysFinishActivities;
14006             mSupportsLeanbackOnly = supportsLeanbackOnly;
14007             mForceResizableActivities = forceResizable;
14008             final boolean multiWindowFormEnabled = freeformWindowManagement
14009                     || supportsSplitScreenMultiWindow
14010                     || supportsPictureInPicture
14011                     || supportsMultiDisplay;
14012             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14013                 mSupportsMultiWindow = true;
14014                 mSupportsFreeformWindowManagement = freeformWindowManagement;
14015                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14016                 mSupportsPictureInPicture = supportsPictureInPicture;
14017                 mSupportsMultiDisplay = supportsMultiDisplay;
14018             } else {
14019                 mSupportsMultiWindow = false;
14020                 mSupportsFreeformWindowManagement = false;
14021                 mSupportsSplitScreenMultiWindow = false;
14022                 mSupportsPictureInPicture = false;
14023                 mSupportsMultiDisplay = false;
14024             }
14025             mWindowManager.setForceResizableTasks(mForceResizableActivities);
14026             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14027             // This happens before any activities are started, so we can change global configuration
14028             // in-place.
14029             updateConfigurationLocked(configuration, null, true);
14030             final Configuration globalConfig = getGlobalConfiguration();
14031             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14032
14033             // Load resources only after the current configuration has been set.
14034             final Resources res = mContext.getResources();
14035             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14036             mThumbnailWidth = res.getDimensionPixelSize(
14037                     com.android.internal.R.dimen.thumbnail_width);
14038             mThumbnailHeight = res.getDimensionPixelSize(
14039                     com.android.internal.R.dimen.thumbnail_height);
14040             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14041                     com.android.internal.R.string.config_appsNotReportingCrashes));
14042             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14043                     com.android.internal.R.bool.config_customUserSwitchUi);
14044             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14045                 mFullscreenThumbnailScale = (float) res
14046                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14047                     (float) globalConfig.screenWidthDp;
14048             } else {
14049                 mFullscreenThumbnailScale = res.getFraction(
14050                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14051             }
14052             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14053         }
14054     }
14055
14056     public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
14057         traceLog.traceBegin("PhaseActivityManagerReady");
14058         synchronized(this) {
14059             if (mSystemReady) {
14060                 // If we're done calling all the receivers, run the next "boot phase" passed in
14061                 // by the SystemServer
14062                 if (goingCallback != null) {
14063                     goingCallback.run();
14064                 }
14065                 return;
14066             }
14067
14068             mLocalDeviceIdleController
14069                     = LocalServices.getService(DeviceIdleController.LocalService.class);
14070             mAssistUtils = new AssistUtils(mContext);
14071             mVrController.onSystemReady();
14072             // Make sure we have the current profile info, since it is needed for security checks.
14073             mUserController.onSystemReady();
14074             mRecentTasks.onSystemReadyLocked();
14075             mAppOpsService.systemReady();
14076             mSystemReady = true;
14077         }
14078
14079         ArrayList<ProcessRecord> procsToKill = null;
14080         synchronized(mPidsSelfLocked) {
14081             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14082                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14083                 if (!isAllowedWhileBooting(proc.info)){
14084                     if (procsToKill == null) {
14085                         procsToKill = new ArrayList<ProcessRecord>();
14086                     }
14087                     procsToKill.add(proc);
14088                 }
14089             }
14090         }
14091
14092         synchronized(this) {
14093             if (procsToKill != null) {
14094                 for (int i=procsToKill.size()-1; i>=0; i--) {
14095                     ProcessRecord proc = procsToKill.get(i);
14096                     Slog.i(TAG, "Removing system update proc: " + proc);
14097                     removeProcessLocked(proc, true, false, "system update done");
14098                 }
14099             }
14100
14101             // Now that we have cleaned up any update processes, we
14102             // are ready to start launching real processes and know that
14103             // we won't trample on them any more.
14104             mProcessesReady = true;
14105         }
14106
14107         Slog.i(TAG, "System now ready");
14108         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14109             SystemClock.uptimeMillis());
14110
14111         synchronized(this) {
14112             // Make sure we have no pre-ready processes sitting around.
14113
14114             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14115                 ResolveInfo ri = mContext.getPackageManager()
14116                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14117                                 STOCK_PM_FLAGS);
14118                 CharSequence errorMsg = null;
14119                 if (ri != null) {
14120                     ActivityInfo ai = ri.activityInfo;
14121                     ApplicationInfo app = ai.applicationInfo;
14122                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14123                         mTopAction = Intent.ACTION_FACTORY_TEST;
14124                         mTopData = null;
14125                         mTopComponent = new ComponentName(app.packageName,
14126                                 ai.name);
14127                     } else {
14128                         errorMsg = mContext.getResources().getText(
14129                                 com.android.internal.R.string.factorytest_not_system);
14130                     }
14131                 } else {
14132                     errorMsg = mContext.getResources().getText(
14133                             com.android.internal.R.string.factorytest_no_action);
14134                 }
14135                 if (errorMsg != null) {
14136                     mTopAction = null;
14137                     mTopData = null;
14138                     mTopComponent = null;
14139                     Message msg = Message.obtain();
14140                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14141                     msg.getData().putCharSequence("msg", errorMsg);
14142                     mUiHandler.sendMessage(msg);
14143                 }
14144             }
14145         }
14146
14147         retrieveSettings();
14148         final int currentUserId;
14149         synchronized (this) {
14150             currentUserId = mUserController.getCurrentUserIdLocked();
14151             readGrantedUriPermissionsLocked();
14152         }
14153
14154         if (goingCallback != null) goingCallback.run();
14155         traceLog.traceBegin("ActivityManagerStartApps");
14156         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14157                 Integer.toString(currentUserId), currentUserId);
14158         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14159                 Integer.toString(currentUserId), currentUserId);
14160         mSystemServiceManager.startUser(currentUserId);
14161
14162         synchronized (this) {
14163             // Only start up encryption-aware persistent apps; once user is
14164             // unlocked we'll come back around and start unaware apps
14165             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14166
14167             // Start up initial activity.
14168             mBooting = true;
14169             // Enable home activity for system user, so that the system can always boot. We don't
14170             // do this when the system user is not setup since the setup wizard should be the one
14171             // to handle home activity in this case.
14172             if (UserManager.isSplitSystemUser() &&
14173                     Settings.Secure.getInt(mContext.getContentResolver(),
14174                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14175                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14176                 try {
14177                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14178                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14179                             UserHandle.USER_SYSTEM);
14180                 } catch (RemoteException e) {
14181                     throw e.rethrowAsRuntimeException();
14182                 }
14183             }
14184             startHomeActivityLocked(currentUserId, "systemReady");
14185
14186             try {
14187                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14188                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14189                             + " data partition or your device will be unstable.");
14190                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14191                 }
14192             } catch (RemoteException e) {
14193             }
14194
14195             if (!Build.isBuildConsistent()) {
14196                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14197                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14198             }
14199
14200             long ident = Binder.clearCallingIdentity();
14201             try {
14202                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14203                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14204                         | Intent.FLAG_RECEIVER_FOREGROUND);
14205                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14206                 broadcastIntentLocked(null, null, intent,
14207                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14208                         null, false, false, MY_PID, SYSTEM_UID,
14209                         currentUserId);
14210                 intent = new Intent(Intent.ACTION_USER_STARTING);
14211                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14212                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14213                 broadcastIntentLocked(null, null, intent,
14214                         null, new IIntentReceiver.Stub() {
14215                             @Override
14216                             public void performReceive(Intent intent, int resultCode, String data,
14217                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14218                                     throws RemoteException {
14219                             }
14220                         }, 0, null, null,
14221                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14222                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14223             } catch (Throwable t) {
14224                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14225             } finally {
14226                 Binder.restoreCallingIdentity(ident);
14227             }
14228             mStackSupervisor.resumeFocusedStackTopActivityLocked();
14229             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14230             traceLog.traceEnd(); // ActivityManagerStartApps
14231             traceLog.traceEnd(); // PhaseActivityManagerReady
14232         }
14233     }
14234
14235     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14236         synchronized (this) {
14237             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14238         }
14239     }
14240
14241     void skipCurrentReceiverLocked(ProcessRecord app) {
14242         for (BroadcastQueue queue : mBroadcastQueues) {
14243             queue.skipCurrentReceiverLocked(app);
14244         }
14245     }
14246
14247     /**
14248      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14249      * The application process will exit immediately after this call returns.
14250      * @param app object of the crashing app, null for the system server
14251      * @param crashInfo describing the exception
14252      */
14253     public void handleApplicationCrash(IBinder app,
14254             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14255         ProcessRecord r = findAppProcess(app, "Crash");
14256         final String processName = app == null ? "system_server"
14257                 : (r == null ? "unknown" : r.processName);
14258
14259         handleApplicationCrashInner("crash", r, processName, crashInfo);
14260     }
14261
14262     /* Native crash reporting uses this inner version because it needs to be somewhat
14263      * decoupled from the AM-managed cleanup lifecycle
14264      */
14265     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14266             ApplicationErrorReport.CrashInfo crashInfo) {
14267         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14268                 UserHandle.getUserId(Binder.getCallingUid()), processName,
14269                 r == null ? -1 : r.info.flags,
14270                 crashInfo.exceptionClassName,
14271                 crashInfo.exceptionMessage,
14272                 crashInfo.throwFileName,
14273                 crashInfo.throwLineNumber);
14274
14275         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14276
14277         mAppErrors.crashApplication(r, crashInfo);
14278     }
14279
14280     public void handleApplicationStrictModeViolation(
14281             IBinder app,
14282             int violationMask,
14283             StrictMode.ViolationInfo info) {
14284         ProcessRecord r = findAppProcess(app, "StrictMode");
14285         if (r == null) {
14286             return;
14287         }
14288
14289         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14290             Integer stackFingerprint = info.hashCode();
14291             boolean logIt = true;
14292             synchronized (mAlreadyLoggedViolatedStacks) {
14293                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14294                     logIt = false;
14295                     // TODO: sub-sample into EventLog for these, with
14296                     // the info.durationMillis?  Then we'd get
14297                     // the relative pain numbers, without logging all
14298                     // the stack traces repeatedly.  We'd want to do
14299                     // likewise in the client code, which also does
14300                     // dup suppression, before the Binder call.
14301                 } else {
14302                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14303                         mAlreadyLoggedViolatedStacks.clear();
14304                     }
14305                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14306                 }
14307             }
14308             if (logIt) {
14309                 logStrictModeViolationToDropBox(r, info);
14310             }
14311         }
14312
14313         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14314             AppErrorResult result = new AppErrorResult();
14315             synchronized (this) {
14316                 final long origId = Binder.clearCallingIdentity();
14317
14318                 Message msg = Message.obtain();
14319                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14320                 HashMap<String, Object> data = new HashMap<String, Object>();
14321                 data.put("result", result);
14322                 data.put("app", r);
14323                 data.put("violationMask", violationMask);
14324                 data.put("info", info);
14325                 msg.obj = data;
14326                 mUiHandler.sendMessage(msg);
14327
14328                 Binder.restoreCallingIdentity(origId);
14329             }
14330             int res = result.get();
14331             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14332         }
14333     }
14334
14335     // Depending on the policy in effect, there could be a bunch of
14336     // these in quick succession so we try to batch these together to
14337     // minimize disk writes, number of dropbox entries, and maximize
14338     // compression, by having more fewer, larger records.
14339     private void logStrictModeViolationToDropBox(
14340             ProcessRecord process,
14341             StrictMode.ViolationInfo info) {
14342         if (info == null) {
14343             return;
14344         }
14345         final boolean isSystemApp = process == null ||
14346                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14347                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14348         final String processName = process == null ? "unknown" : process.processName;
14349         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14350         final DropBoxManager dbox = (DropBoxManager)
14351                 mContext.getSystemService(Context.DROPBOX_SERVICE);
14352
14353         // Exit early if the dropbox isn't configured to accept this report type.
14354         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14355
14356         boolean bufferWasEmpty;
14357         boolean needsFlush;
14358         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14359         synchronized (sb) {
14360             bufferWasEmpty = sb.length() == 0;
14361             appendDropBoxProcessHeaders(process, processName, sb);
14362             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14363             sb.append("System-App: ").append(isSystemApp).append("\n");
14364             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14365             if (info.violationNumThisLoop != 0) {
14366                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14367             }
14368             if (info.numAnimationsRunning != 0) {
14369                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14370             }
14371             if (info.broadcastIntentAction != null) {
14372                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14373             }
14374             if (info.durationMillis != -1) {
14375                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14376             }
14377             if (info.numInstances != -1) {
14378                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14379             }
14380             if (info.tags != null) {
14381                 for (String tag : info.tags) {
14382                     sb.append("Span-Tag: ").append(tag).append("\n");
14383                 }
14384             }
14385             sb.append("\n");
14386             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14387                 sb.append(info.crashInfo.stackTrace);
14388                 sb.append("\n");
14389             }
14390             if (info.message != null) {
14391                 sb.append(info.message);
14392                 sb.append("\n");
14393             }
14394
14395             // Only buffer up to ~64k.  Various logging bits truncate
14396             // things at 128k.
14397             needsFlush = (sb.length() > 64 * 1024);
14398         }
14399
14400         // Flush immediately if the buffer's grown too large, or this
14401         // is a non-system app.  Non-system apps are isolated with a
14402         // different tag & policy and not batched.
14403         //
14404         // Batching is useful during internal testing with
14405         // StrictMode settings turned up high.  Without batching,
14406         // thousands of separate files could be created on boot.
14407         if (!isSystemApp || needsFlush) {
14408             new Thread("Error dump: " + dropboxTag) {
14409                 @Override
14410                 public void run() {
14411                     String report;
14412                     synchronized (sb) {
14413                         report = sb.toString();
14414                         sb.delete(0, sb.length());
14415                         sb.trimToSize();
14416                     }
14417                     if (report.length() != 0) {
14418                         dbox.addText(dropboxTag, report);
14419                     }
14420                 }
14421             }.start();
14422             return;
14423         }
14424
14425         // System app batching:
14426         if (!bufferWasEmpty) {
14427             // An existing dropbox-writing thread is outstanding, so
14428             // we don't need to start it up.  The existing thread will
14429             // catch the buffer appends we just did.
14430             return;
14431         }
14432
14433         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14434         // (After this point, we shouldn't access AMS internal data structures.)
14435         new Thread("Error dump: " + dropboxTag) {
14436             @Override
14437             public void run() {
14438                 // 5 second sleep to let stacks arrive and be batched together
14439                 try {
14440                     Thread.sleep(5000);  // 5 seconds
14441                 } catch (InterruptedException e) {}
14442
14443                 String errorReport;
14444                 synchronized (mStrictModeBuffer) {
14445                     errorReport = mStrictModeBuffer.toString();
14446                     if (errorReport.length() == 0) {
14447                         return;
14448                     }
14449                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14450                     mStrictModeBuffer.trimToSize();
14451                 }
14452                 dbox.addText(dropboxTag, errorReport);
14453             }
14454         }.start();
14455     }
14456
14457     /**
14458      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14459      * @param app object of the crashing app, null for the system server
14460      * @param tag reported by the caller
14461      * @param system whether this wtf is coming from the system
14462      * @param crashInfo describing the context of the error
14463      * @return true if the process should exit immediately (WTF is fatal)
14464      */
14465     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14466             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14467         final int callingUid = Binder.getCallingUid();
14468         final int callingPid = Binder.getCallingPid();
14469
14470         if (system) {
14471             // If this is coming from the system, we could very well have low-level
14472             // system locks held, so we want to do this all asynchronously.  And we
14473             // never want this to become fatal, so there is that too.
14474             mHandler.post(new Runnable() {
14475                 @Override public void run() {
14476                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14477                 }
14478             });
14479             return false;
14480         }
14481
14482         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14483                 crashInfo);
14484
14485         final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14486                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14487         final boolean isSystem = (r == null) || r.persistent;
14488
14489         if (isFatal && !isSystem) {
14490             mAppErrors.crashApplication(r, crashInfo);
14491             return true;
14492         } else {
14493             return false;
14494         }
14495     }
14496
14497     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14498             final ApplicationErrorReport.CrashInfo crashInfo) {
14499         final ProcessRecord r = findAppProcess(app, "WTF");
14500         final String processName = app == null ? "system_server"
14501                 : (r == null ? "unknown" : r.processName);
14502
14503         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14504                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14505
14506         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14507
14508         return r;
14509     }
14510
14511     /**
14512      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14513      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14514      */
14515     private ProcessRecord findAppProcess(IBinder app, String reason) {
14516         if (app == null) {
14517             return null;
14518         }
14519
14520         synchronized (this) {
14521             final int NP = mProcessNames.getMap().size();
14522             for (int ip=0; ip<NP; ip++) {
14523                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14524                 final int NA = apps.size();
14525                 for (int ia=0; ia<NA; ia++) {
14526                     ProcessRecord p = apps.valueAt(ia);
14527                     if (p.thread != null && p.thread.asBinder() == app) {
14528                         return p;
14529                     }
14530                 }
14531             }
14532
14533             Slog.w(TAG, "Can't find mystery application for " + reason
14534                     + " from pid=" + Binder.getCallingPid()
14535                     + " uid=" + Binder.getCallingUid() + ": " + app);
14536             return null;
14537         }
14538     }
14539
14540     /**
14541      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14542      * to append various headers to the dropbox log text.
14543      */
14544     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14545             StringBuilder sb) {
14546         // Watchdog thread ends up invoking this function (with
14547         // a null ProcessRecord) to add the stack file to dropbox.
14548         // Do not acquire a lock on this (am) in such cases, as it
14549         // could cause a potential deadlock, if and when watchdog
14550         // is invoked due to unavailability of lock on am and it
14551         // would prevent watchdog from killing system_server.
14552         if (process == null) {
14553             sb.append("Process: ").append(processName).append("\n");
14554             return;
14555         }
14556         // Note: ProcessRecord 'process' is guarded by the service
14557         // instance.  (notably process.pkgList, which could otherwise change
14558         // concurrently during execution of this method)
14559         synchronized (this) {
14560             sb.append("Process: ").append(processName).append("\n");
14561             sb.append("PID: ").append(process.pid).append("\n");
14562             int flags = process.info.flags;
14563             IPackageManager pm = AppGlobals.getPackageManager();
14564             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14565             for (int ip=0; ip<process.pkgList.size(); ip++) {
14566                 String pkg = process.pkgList.keyAt(ip);
14567                 sb.append("Package: ").append(pkg);
14568                 try {
14569                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14570                     if (pi != null) {
14571                         sb.append(" v").append(pi.versionCode);
14572                         if (pi.versionName != null) {
14573                             sb.append(" (").append(pi.versionName).append(")");
14574                         }
14575                     }
14576                 } catch (RemoteException e) {
14577                     Slog.e(TAG, "Error getting package info: " + pkg, e);
14578                 }
14579                 sb.append("\n");
14580             }
14581         }
14582     }
14583
14584     private static String processClass(ProcessRecord process) {
14585         if (process == null || process.pid == MY_PID) {
14586             return "system_server";
14587         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14588             return "system_app";
14589         } else {
14590             return "data_app";
14591         }
14592     }
14593
14594     private volatile long mWtfClusterStart;
14595     private volatile int mWtfClusterCount;
14596
14597     /**
14598      * Write a description of an error (crash, WTF, ANR) to the drop box.
14599      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14600      * @param process which caused the error, null means the system server
14601      * @param activity which triggered the error, null if unknown
14602      * @param parent activity related to the error, null if unknown
14603      * @param subject line related to the error, null if absent
14604      * @param report in long form describing the error, null if absent
14605      * @param dataFile text file to include in the report, null if none
14606      * @param crashInfo giving an application stack trace, null if absent
14607      */
14608     public void addErrorToDropBox(String eventType,
14609             ProcessRecord process, String processName, ActivityRecord activity,
14610             ActivityRecord parent, String subject,
14611             final String report, final File dataFile,
14612             final ApplicationErrorReport.CrashInfo crashInfo) {
14613         // NOTE -- this must never acquire the ActivityManagerService lock,
14614         // otherwise the watchdog may be prevented from resetting the system.
14615
14616         // Bail early if not published yet
14617         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14618         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14619
14620         // Exit early if the dropbox isn't configured to accept this report type.
14621         final String dropboxTag = processClass(process) + "_" + eventType;
14622         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14623
14624         // Rate-limit how often we're willing to do the heavy lifting below to
14625         // collect and record logs; currently 5 logs per 10 second period.
14626         final long now = SystemClock.elapsedRealtime();
14627         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14628             mWtfClusterStart = now;
14629             mWtfClusterCount = 1;
14630         } else {
14631             if (mWtfClusterCount++ >= 5) return;
14632         }
14633
14634         final StringBuilder sb = new StringBuilder(1024);
14635         appendDropBoxProcessHeaders(process, processName, sb);
14636         if (process != null) {
14637             sb.append("Foreground: ")
14638                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14639                     .append("\n");
14640         }
14641         if (activity != null) {
14642             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14643         }
14644         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14645             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14646         }
14647         if (parent != null && parent != activity) {
14648             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14649         }
14650         if (subject != null) {
14651             sb.append("Subject: ").append(subject).append("\n");
14652         }
14653         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14654         if (Debug.isDebuggerConnected()) {
14655             sb.append("Debugger: Connected\n");
14656         }
14657         sb.append("\n");
14658
14659         // Do the rest in a worker thread to avoid blocking the caller on I/O
14660         // (After this point, we shouldn't access AMS internal data structures.)
14661         Thread worker = new Thread("Error dump: " + dropboxTag) {
14662             @Override
14663             public void run() {
14664                 if (report != null) {
14665                     sb.append(report);
14666                 }
14667
14668                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14669                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14670                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14671                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14672
14673                 if (dataFile != null && maxDataFileSize > 0) {
14674                     try {
14675                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14676                                     "\n\n[[TRUNCATED]]"));
14677                     } catch (IOException e) {
14678                         Slog.e(TAG, "Error reading " + dataFile, e);
14679                     }
14680                 }
14681                 if (crashInfo != null && crashInfo.stackTrace != null) {
14682                     sb.append(crashInfo.stackTrace);
14683                 }
14684
14685                 if (lines > 0) {
14686                     sb.append("\n");
14687
14688                     // Merge several logcat streams, and take the last N lines
14689                     InputStreamReader input = null;
14690                     try {
14691                         java.lang.Process logcat = new ProcessBuilder(
14692                                 "/system/bin/timeout", "-k", "15s", "10s",
14693                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14694                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14695                                         .redirectErrorStream(true).start();
14696
14697                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
14698                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
14699                         input = new InputStreamReader(logcat.getInputStream());
14700
14701                         int num;
14702                         char[] buf = new char[8192];
14703                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14704                     } catch (IOException e) {
14705                         Slog.e(TAG, "Error running logcat", e);
14706                     } finally {
14707                         if (input != null) try { input.close(); } catch (IOException e) {}
14708                     }
14709                 }
14710
14711                 dbox.addText(dropboxTag, sb.toString());
14712             }
14713         };
14714
14715         if (process == null) {
14716             // If process is null, we are being called from some internal code
14717             // and may be about to die -- run this synchronously.
14718             worker.run();
14719         } else {
14720             worker.start();
14721         }
14722     }
14723
14724     @Override
14725     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14726         enforceNotIsolatedCaller("getProcessesInErrorState");
14727         // assume our apps are happy - lazy create the list
14728         List<ActivityManager.ProcessErrorStateInfo> errList = null;
14729
14730         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14731                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14732         int userId = UserHandle.getUserId(Binder.getCallingUid());
14733
14734         synchronized (this) {
14735
14736             // iterate across all processes
14737             for (int i=mLruProcesses.size()-1; i>=0; i--) {
14738                 ProcessRecord app = mLruProcesses.get(i);
14739                 if (!allUsers && app.userId != userId) {
14740                     continue;
14741                 }
14742                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14743                     // This one's in trouble, so we'll generate a report for it
14744                     // crashes are higher priority (in case there's a crash *and* an anr)
14745                     ActivityManager.ProcessErrorStateInfo report = null;
14746                     if (app.crashing) {
14747                         report = app.crashingReport;
14748                     } else if (app.notResponding) {
14749                         report = app.notRespondingReport;
14750                     }
14751
14752                     if (report != null) {
14753                         if (errList == null) {
14754                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14755                         }
14756                         errList.add(report);
14757                     } else {
14758                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
14759                                 " crashing = " + app.crashing +
14760                                 " notResponding = " + app.notResponding);
14761                     }
14762                 }
14763             }
14764         }
14765
14766         return errList;
14767     }
14768
14769     static int procStateToImportance(int procState, int memAdj,
14770             ActivityManager.RunningAppProcessInfo currApp,
14771             int clientTargetSdk) {
14772         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14773                 procState, clientTargetSdk);
14774         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14775             currApp.lru = memAdj;
14776         } else {
14777             currApp.lru = 0;
14778         }
14779         return imp;
14780     }
14781
14782     private void fillInProcMemInfo(ProcessRecord app,
14783             ActivityManager.RunningAppProcessInfo outInfo,
14784             int clientTargetSdk) {
14785         outInfo.pid = app.pid;
14786         outInfo.uid = app.info.uid;
14787         if (mHeavyWeightProcess == app) {
14788             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14789         }
14790         if (app.persistent) {
14791             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14792         }
14793         if (app.activities.size() > 0) {
14794             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14795         }
14796         outInfo.lastTrimLevel = app.trimMemoryLevel;
14797         int adj = app.curAdj;
14798         int procState = app.curProcState;
14799         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14800         outInfo.importanceReasonCode = app.adjTypeCode;
14801         outInfo.processState = app.curProcState;
14802     }
14803
14804     @Override
14805     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14806         enforceNotIsolatedCaller("getRunningAppProcesses");
14807
14808         final int callingUid = Binder.getCallingUid();
14809         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14810
14811         // Lazy instantiation of list
14812         List<ActivityManager.RunningAppProcessInfo> runList = null;
14813         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14814                 callingUid) == PackageManager.PERMISSION_GRANTED;
14815         final int userId = UserHandle.getUserId(callingUid);
14816         final boolean allUids = isGetTasksAllowed(
14817                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14818
14819         synchronized (this) {
14820             // Iterate across all processes
14821             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14822                 ProcessRecord app = mLruProcesses.get(i);
14823                 if ((!allUsers && app.userId != userId)
14824                         || (!allUids && app.uid != callingUid)) {
14825                     continue;
14826                 }
14827                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14828                     // Generate process state info for running application
14829                     ActivityManager.RunningAppProcessInfo currApp =
14830                         new ActivityManager.RunningAppProcessInfo(app.processName,
14831                                 app.pid, app.getPackageList());
14832                     fillInProcMemInfo(app, currApp, clientTargetSdk);
14833                     if (app.adjSource instanceof ProcessRecord) {
14834                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14835                         currApp.importanceReasonImportance =
14836                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14837                                         app.adjSourceProcState);
14838                     } else if (app.adjSource instanceof ActivityRecord) {
14839                         ActivityRecord r = (ActivityRecord)app.adjSource;
14840                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14841                     }
14842                     if (app.adjTarget instanceof ComponentName) {
14843                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14844                     }
14845                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14846                     //        + " lru=" + currApp.lru);
14847                     if (runList == null) {
14848                         runList = new ArrayList<>();
14849                     }
14850                     runList.add(currApp);
14851                 }
14852             }
14853         }
14854         return runList;
14855     }
14856
14857     @Override
14858     public List<ApplicationInfo> getRunningExternalApplications() {
14859         enforceNotIsolatedCaller("getRunningExternalApplications");
14860         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14861         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14862         if (runningApps != null && runningApps.size() > 0) {
14863             Set<String> extList = new HashSet<String>();
14864             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14865                 if (app.pkgList != null) {
14866                     for (String pkg : app.pkgList) {
14867                         extList.add(pkg);
14868                     }
14869                 }
14870             }
14871             IPackageManager pm = AppGlobals.getPackageManager();
14872             for (String pkg : extList) {
14873                 try {
14874                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14875                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14876                         retList.add(info);
14877                     }
14878                 } catch (RemoteException e) {
14879                 }
14880             }
14881         }
14882         return retList;
14883     }
14884
14885     @Override
14886     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14887         enforceNotIsolatedCaller("getMyMemoryState");
14888
14889         final int callingUid = Binder.getCallingUid();
14890         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14891
14892         synchronized (this) {
14893             ProcessRecord proc;
14894             synchronized (mPidsSelfLocked) {
14895                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14896             }
14897             fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14898         }
14899     }
14900
14901     @Override
14902     public int getMemoryTrimLevel() {
14903         enforceNotIsolatedCaller("getMyMemoryState");
14904         synchronized (this) {
14905             return mLastMemoryLevel;
14906         }
14907     }
14908
14909     @Override
14910     public void onShellCommand(FileDescriptor in, FileDescriptor out,
14911             FileDescriptor err, String[] args, ShellCallback callback,
14912             ResultReceiver resultReceiver) {
14913         (new ActivityManagerShellCommand(this, false)).exec(
14914                 this, in, out, err, args, callback, resultReceiver);
14915     }
14916
14917     @Override
14918     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14919         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14920
14921         boolean dumpAll = false;
14922         boolean dumpClient = false;
14923         boolean dumpCheckin = false;
14924         boolean dumpCheckinFormat = false;
14925         boolean dumpVisibleStacksOnly = false;
14926         boolean dumpFocusedStackOnly = false;
14927         String dumpPackage = null;
14928
14929         int opti = 0;
14930         while (opti < args.length) {
14931             String opt = args[opti];
14932             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14933                 break;
14934             }
14935             opti++;
14936             if ("-a".equals(opt)) {
14937                 dumpAll = true;
14938             } else if ("-c".equals(opt)) {
14939                 dumpClient = true;
14940             } else if ("-v".equals(opt)) {
14941                 dumpVisibleStacksOnly = true;
14942             } else if ("-f".equals(opt)) {
14943                 dumpFocusedStackOnly = true;
14944             } else if ("-p".equals(opt)) {
14945                 if (opti < args.length) {
14946                     dumpPackage = args[opti];
14947                     opti++;
14948                 } else {
14949                     pw.println("Error: -p option requires package argument");
14950                     return;
14951                 }
14952                 dumpClient = true;
14953             } else if ("--checkin".equals(opt)) {
14954                 dumpCheckin = dumpCheckinFormat = true;
14955             } else if ("-C".equals(opt)) {
14956                 dumpCheckinFormat = true;
14957             } else if ("-h".equals(opt)) {
14958                 ActivityManagerShellCommand.dumpHelp(pw, true);
14959                 return;
14960             } else {
14961                 pw.println("Unknown argument: " + opt + "; use -h for help");
14962             }
14963         }
14964
14965         long origId = Binder.clearCallingIdentity();
14966         boolean more = false;
14967         // Is the caller requesting to dump a particular piece of data?
14968         if (opti < args.length) {
14969             String cmd = args[opti];
14970             opti++;
14971             if ("activities".equals(cmd) || "a".equals(cmd)) {
14972                 synchronized (this) {
14973                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14974                 }
14975             } else if ("lastanr".equals(cmd)) {
14976                 synchronized (this) {
14977                     dumpLastANRLocked(pw);
14978                 }
14979             } else if ("starter".equals(cmd)) {
14980                 synchronized (this) {
14981                     dumpActivityStarterLocked(pw);
14982                 }
14983             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14984                 synchronized (this) {
14985                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14986                 }
14987             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14988                 String[] newArgs;
14989                 String name;
14990                 if (opti >= args.length) {
14991                     name = null;
14992                     newArgs = EMPTY_STRING_ARRAY;
14993                 } else {
14994                     dumpPackage = args[opti];
14995                     opti++;
14996                     newArgs = new String[args.length - opti];
14997                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14998                             args.length - opti);
14999                 }
15000                 synchronized (this) {
15001                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15002                 }
15003             } else if ("broadcast-stats".equals(cmd)) {
15004                 String[] newArgs;
15005                 String name;
15006                 if (opti >= args.length) {
15007                     name = null;
15008                     newArgs = EMPTY_STRING_ARRAY;
15009                 } else {
15010                     dumpPackage = args[opti];
15011                     opti++;
15012                     newArgs = new String[args.length - opti];
15013                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15014                             args.length - opti);
15015                 }
15016                 synchronized (this) {
15017                     if (dumpCheckinFormat) {
15018                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15019                                 dumpPackage);
15020                     } else {
15021                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15022                     }
15023                 }
15024             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15025                 String[] newArgs;
15026                 String name;
15027                 if (opti >= args.length) {
15028                     name = null;
15029                     newArgs = EMPTY_STRING_ARRAY;
15030                 } else {
15031                     dumpPackage = args[opti];
15032                     opti++;
15033                     newArgs = new String[args.length - opti];
15034                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15035                             args.length - opti);
15036                 }
15037                 synchronized (this) {
15038                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15039                 }
15040             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15041                 String[] newArgs;
15042                 String name;
15043                 if (opti >= args.length) {
15044                     name = null;
15045                     newArgs = EMPTY_STRING_ARRAY;
15046                 } else {
15047                     dumpPackage = args[opti];
15048                     opti++;
15049                     newArgs = new String[args.length - opti];
15050                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15051                             args.length - opti);
15052                 }
15053                 synchronized (this) {
15054                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15055                 }
15056             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15057                 synchronized (this) {
15058                     dumpOomLocked(fd, pw, args, opti, true);
15059                 }
15060             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15061                 synchronized (this) {
15062                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
15063                 }
15064             } else if ("provider".equals(cmd)) {
15065                 String[] newArgs;
15066                 String name;
15067                 if (opti >= args.length) {
15068                     name = null;
15069                     newArgs = EMPTY_STRING_ARRAY;
15070                 } else {
15071                     name = args[opti];
15072                     opti++;
15073                     newArgs = new String[args.length - opti];
15074                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15075                 }
15076                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15077                     pw.println("No providers match: " + name);
15078                     pw.println("Use -h for help.");
15079                 }
15080             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15081                 synchronized (this) {
15082                     dumpProvidersLocked(fd, pw, args, opti, true, null);
15083                 }
15084             } else if ("service".equals(cmd)) {
15085                 String[] newArgs;
15086                 String name;
15087                 if (opti >= args.length) {
15088                     name = null;
15089                     newArgs = EMPTY_STRING_ARRAY;
15090                 } else {
15091                     name = args[opti];
15092                     opti++;
15093                     newArgs = new String[args.length - opti];
15094                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15095                             args.length - opti);
15096                 }
15097                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15098                     pw.println("No services match: " + name);
15099                     pw.println("Use -h for help.");
15100                 }
15101             } else if ("package".equals(cmd)) {
15102                 String[] newArgs;
15103                 if (opti >= args.length) {
15104                     pw.println("package: no package name specified");
15105                     pw.println("Use -h for help.");
15106                 } else {
15107                     dumpPackage = args[opti];
15108                     opti++;
15109                     newArgs = new String[args.length - opti];
15110                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15111                             args.length - opti);
15112                     args = newArgs;
15113                     opti = 0;
15114                     more = true;
15115                 }
15116             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15117                 synchronized (this) {
15118                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15119                 }
15120             } else if ("settings".equals(cmd)) {
15121                 synchronized (this) {
15122                     mConstants.dump(pw);
15123                 }
15124             } else if ("services".equals(cmd) || "s".equals(cmd)) {
15125                 if (dumpClient) {
15126                     ActiveServices.ServiceDumper dumper;
15127                     synchronized (this) {
15128                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15129                                 dumpPackage);
15130                     }
15131                     dumper.dumpWithClient();
15132                 } else {
15133                     synchronized (this) {
15134                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15135                                 dumpPackage).dumpLocked();
15136                     }
15137                 }
15138             } else if ("locks".equals(cmd)) {
15139                 LockGuard.dump(fd, pw, args);
15140             } else {
15141                 // Dumping a single activity?
15142                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15143                         dumpFocusedStackOnly)) {
15144                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15145                     int res = shell.exec(this, null, fd, null, args, null,
15146                             new ResultReceiver(null));
15147                     if (res < 0) {
15148                         pw.println("Bad activity command, or no activities match: " + cmd);
15149                         pw.println("Use -h for help.");
15150                     }
15151                 }
15152             }
15153             if (!more) {
15154                 Binder.restoreCallingIdentity(origId);
15155                 return;
15156             }
15157         }
15158
15159         // No piece of data specified, dump everything.
15160         if (dumpCheckinFormat) {
15161             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15162         } else if (dumpClient) {
15163             ActiveServices.ServiceDumper sdumper;
15164             synchronized (this) {
15165                 mConstants.dump(pw);
15166                 pw.println();
15167                 if (dumpAll) {
15168                     pw.println("-------------------------------------------------------------------------------");
15169                 }
15170                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15171                 pw.println();
15172                 if (dumpAll) {
15173                     pw.println("-------------------------------------------------------------------------------");
15174                 }
15175                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15176                 pw.println();
15177                 if (dumpAll) {
15178                     pw.println("-------------------------------------------------------------------------------");
15179                 }
15180                 if (dumpAll || dumpPackage != null) {
15181                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15182                     pw.println();
15183                     if (dumpAll) {
15184                         pw.println("-------------------------------------------------------------------------------");
15185                     }
15186                 }
15187                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15188                 pw.println();
15189                 if (dumpAll) {
15190                     pw.println("-------------------------------------------------------------------------------");
15191                 }
15192                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15193                 pw.println();
15194                 if (dumpAll) {
15195                     pw.println("-------------------------------------------------------------------------------");
15196                 }
15197                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15198                         dumpPackage);
15199             }
15200             sdumper.dumpWithClient();
15201             pw.println();
15202             synchronized (this) {
15203                 if (dumpAll) {
15204                     pw.println("-------------------------------------------------------------------------------");
15205                 }
15206                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15207                 pw.println();
15208                 if (dumpAll) {
15209                     pw.println("-------------------------------------------------------------------------------");
15210                 }
15211                 dumpLastANRLocked(pw);
15212                 pw.println();
15213                 if (dumpAll) {
15214                     pw.println("-------------------------------------------------------------------------------");
15215                 }
15216                 dumpActivityStarterLocked(pw);
15217                 pw.println();
15218                 if (dumpAll) {
15219                     pw.println("-------------------------------------------------------------------------------");
15220                 }
15221                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15222                 if (mAssociations.size() > 0) {
15223                     pw.println();
15224                     if (dumpAll) {
15225                         pw.println("-------------------------------------------------------------------------------");
15226                     }
15227                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15228                 }
15229                 pw.println();
15230                 if (dumpAll) {
15231                     pw.println("-------------------------------------------------------------------------------");
15232                 }
15233                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15234             }
15235
15236         } else {
15237             synchronized (this) {
15238                 mConstants.dump(pw);
15239                 pw.println();
15240                 if (dumpAll) {
15241                     pw.println("-------------------------------------------------------------------------------");
15242                 }
15243                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15244                 pw.println();
15245                 if (dumpAll) {
15246                     pw.println("-------------------------------------------------------------------------------");
15247                 }
15248                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15249                 pw.println();
15250                 if (dumpAll) {
15251                     pw.println("-------------------------------------------------------------------------------");
15252                 }
15253                 if (dumpAll || dumpPackage != null) {
15254                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15255                     pw.println();
15256                     if (dumpAll) {
15257                         pw.println("-------------------------------------------------------------------------------");
15258                     }
15259                 }
15260                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15261                 pw.println();
15262                 if (dumpAll) {
15263                     pw.println("-------------------------------------------------------------------------------");
15264                 }
15265                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15266                 pw.println();
15267                 if (dumpAll) {
15268                     pw.println("-------------------------------------------------------------------------------");
15269                 }
15270                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15271                         .dumpLocked();
15272                 pw.println();
15273                 if (dumpAll) {
15274                     pw.println("-------------------------------------------------------------------------------");
15275                 }
15276                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15277                 pw.println();
15278                 if (dumpAll) {
15279                     pw.println("-------------------------------------------------------------------------------");
15280                 }
15281                 dumpLastANRLocked(pw);
15282                 pw.println();
15283                 if (dumpAll) {
15284                     pw.println("-------------------------------------------------------------------------------");
15285                 }
15286                 dumpActivityStarterLocked(pw);
15287                 pw.println();
15288                 if (dumpAll) {
15289                     pw.println("-------------------------------------------------------------------------------");
15290                 }
15291                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15292                 if (mAssociations.size() > 0) {
15293                     pw.println();
15294                     if (dumpAll) {
15295                         pw.println("-------------------------------------------------------------------------------");
15296                     }
15297                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15298                 }
15299                 pw.println();
15300                 if (dumpAll) {
15301                     pw.println("-------------------------------------------------------------------------------");
15302                 }
15303                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15304             }
15305         }
15306         Binder.restoreCallingIdentity(origId);
15307     }
15308
15309     private void dumpLastANRLocked(PrintWriter pw) {
15310         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
15311         if (mLastANRState == null) {
15312             pw.println("  <no ANR has occurred since boot>");
15313         } else {
15314             pw.println(mLastANRState);
15315         }
15316     }
15317
15318     private void dumpActivityStarterLocked(PrintWriter pw) {
15319         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)");
15320         mActivityStarter.dump(pw, "");
15321     }
15322
15323     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15324             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15325         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15326                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15327     }
15328
15329     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15330             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15331         pw.println(header);
15332
15333         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15334                 dumpPackage);
15335         boolean needSep = printedAnything;
15336
15337         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15338                 mStackSupervisor.getResumedActivityLocked(),
15339                 dumpPackage, needSep, "  ResumedActivity: ");
15340         if (printed) {
15341             printedAnything = true;
15342             needSep = false;
15343         }
15344
15345         if (dumpPackage == null) {
15346             if (needSep) {
15347                 pw.println();
15348             }
15349             printedAnything = true;
15350             mStackSupervisor.dump(pw, "  ");
15351         }
15352
15353         if (!printedAnything) {
15354             pw.println("  (nothing)");
15355         }
15356     }
15357
15358     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15359             int opti, boolean dumpAll, String dumpPackage) {
15360         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15361
15362         boolean printedAnything = false;
15363
15364         if (mRecentTasks != null && mRecentTasks.size() > 0) {
15365             boolean printedHeader = false;
15366
15367             final int N = mRecentTasks.size();
15368             for (int i=0; i<N; i++) {
15369                 TaskRecord tr = mRecentTasks.get(i);
15370                 if (dumpPackage != null) {
15371                     if (tr.realActivity == null ||
15372                             !dumpPackage.equals(tr.realActivity.getPackageName())) {
15373                         continue;
15374                     }
15375                 }
15376                 if (!printedHeader) {
15377                     pw.println("  Recent tasks:");
15378                     printedHeader = true;
15379                     printedAnything = true;
15380                 }
15381                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15382                         pw.println(tr);
15383                 if (dumpAll) {
15384                     mRecentTasks.get(i).dump(pw, "    ");
15385                 }
15386             }
15387         }
15388
15389         if (!printedAnything) {
15390             pw.println("  (nothing)");
15391         }
15392     }
15393
15394     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15395             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15396         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15397
15398         int dumpUid = 0;
15399         if (dumpPackage != null) {
15400             IPackageManager pm = AppGlobals.getPackageManager();
15401             try {
15402                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15403             } catch (RemoteException e) {
15404             }
15405         }
15406
15407         boolean printedAnything = false;
15408
15409         final long now = SystemClock.uptimeMillis();
15410
15411         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15412             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15413                     = mAssociations.valueAt(i1);
15414             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15415                 SparseArray<ArrayMap<String, Association>> sourceUids
15416                         = targetComponents.valueAt(i2);
15417                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15418                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15419                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15420                         Association ass = sourceProcesses.valueAt(i4);
15421                         if (dumpPackage != null) {
15422                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15423                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15424                                 continue;
15425                             }
15426                         }
15427                         printedAnything = true;
15428                         pw.print("  ");
15429                         pw.print(ass.mTargetProcess);
15430                         pw.print("/");
15431                         UserHandle.formatUid(pw, ass.mTargetUid);
15432                         pw.print(" <- ");
15433                         pw.print(ass.mSourceProcess);
15434                         pw.print("/");
15435                         UserHandle.formatUid(pw, ass.mSourceUid);
15436                         pw.println();
15437                         pw.print("    via ");
15438                         pw.print(ass.mTargetComponent.flattenToShortString());
15439                         pw.println();
15440                         pw.print("    ");
15441                         long dur = ass.mTime;
15442                         if (ass.mNesting > 0) {
15443                             dur += now - ass.mStartTime;
15444                         }
15445                         TimeUtils.formatDuration(dur, pw);
15446                         pw.print(" (");
15447                         pw.print(ass.mCount);
15448                         pw.print(" times)");
15449                         pw.print("  ");
15450                         for (int i=0; i<ass.mStateTimes.length; i++) {
15451                             long amt = ass.mStateTimes[i];
15452                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15453                                 amt += now - ass.mLastStateUptime;
15454                             }
15455                             if (amt != 0) {
15456                                 pw.print(" ");
15457                                 pw.print(ProcessList.makeProcStateString(
15458                                             i + ActivityManager.MIN_PROCESS_STATE));
15459                                 pw.print("=");
15460                                 TimeUtils.formatDuration(amt, pw);
15461                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15462                                     pw.print("*");
15463                                 }
15464                             }
15465                         }
15466                         pw.println();
15467                         if (ass.mNesting > 0) {
15468                             pw.print("    Currently active: ");
15469                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
15470                             pw.println();
15471                         }
15472                     }
15473                 }
15474             }
15475
15476         }
15477
15478         if (!printedAnything) {
15479             pw.println("  (nothing)");
15480         }
15481     }
15482
15483     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15484             String header, boolean needSep) {
15485         boolean printed = false;
15486         int whichAppId = -1;
15487         if (dumpPackage != null) {
15488             try {
15489                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15490                         dumpPackage, 0);
15491                 whichAppId = UserHandle.getAppId(info.uid);
15492             } catch (NameNotFoundException e) {
15493                 e.printStackTrace();
15494             }
15495         }
15496         for (int i=0; i<uids.size(); i++) {
15497             UidRecord uidRec = uids.valueAt(i);
15498             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15499                 continue;
15500             }
15501             if (!printed) {
15502                 printed = true;
15503                 if (needSep) {
15504                     pw.println();
15505                 }
15506                 pw.print("  ");
15507                 pw.println(header);
15508                 needSep = true;
15509             }
15510             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15511             pw.print(": "); pw.println(uidRec);
15512         }
15513         return printed;
15514     }
15515
15516     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15517             int opti, boolean dumpAll, String dumpPackage) {
15518         boolean needSep = false;
15519         boolean printedAnything = false;
15520         int numPers = 0;
15521
15522         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15523
15524         if (dumpAll) {
15525             final int NP = mProcessNames.getMap().size();
15526             for (int ip=0; ip<NP; ip++) {
15527                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15528                 final int NA = procs.size();
15529                 for (int ia=0; ia<NA; ia++) {
15530                     ProcessRecord r = procs.valueAt(ia);
15531                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15532                         continue;
15533                     }
15534                     if (!needSep) {
15535                         pw.println("  All known processes:");
15536                         needSep = true;
15537                         printedAnything = true;
15538                     }
15539                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15540                         pw.print(" UID "); pw.print(procs.keyAt(ia));
15541                         pw.print(" "); pw.println(r);
15542                     r.dump(pw, "    ");
15543                     if (r.persistent) {
15544                         numPers++;
15545                     }
15546                 }
15547             }
15548         }
15549
15550         if (mIsolatedProcesses.size() > 0) {
15551             boolean printed = false;
15552             for (int i=0; i<mIsolatedProcesses.size(); i++) {
15553                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15554                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15555                     continue;
15556                 }
15557                 if (!printed) {
15558                     if (needSep) {
15559                         pw.println();
15560                     }
15561                     pw.println("  Isolated process list (sorted by uid):");
15562                     printedAnything = true;
15563                     printed = true;
15564                     needSep = true;
15565                 }
15566                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15567                 pw.println(r);
15568             }
15569         }
15570
15571         if (mActiveInstrumentation.size() > 0) {
15572             boolean printed = false;
15573             for (int i=0; i<mActiveInstrumentation.size(); i++) {
15574                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15575                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15576                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15577                     continue;
15578                 }
15579                 if (!printed) {
15580                     if (needSep) {
15581                         pw.println();
15582                     }
15583                     pw.println("  Active instrumentation:");
15584                     printedAnything = true;
15585                     printed = true;
15586                     needSep = true;
15587                 }
15588                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15589                 pw.println(ai);
15590                 ai.dump(pw, "      ");
15591             }
15592         }
15593
15594         if (mActiveUids.size() > 0) {
15595             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15596                 printedAnything = needSep = true;
15597             }
15598         }
15599         if (dumpAll) {
15600             if (mValidateUids.size() > 0) {
15601                 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15602                     printedAnything = needSep = true;
15603                 }
15604             }
15605         }
15606
15607         if (mLruProcesses.size() > 0) {
15608             if (needSep) {
15609                 pw.println();
15610             }
15611             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15612                     pw.print(" total, non-act at ");
15613                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15614                     pw.print(", non-svc at ");
15615                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15616                     pw.println("):");
15617             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15618             needSep = true;
15619             printedAnything = true;
15620         }
15621
15622         if (dumpAll || dumpPackage != null) {
15623             synchronized (mPidsSelfLocked) {
15624                 boolean printed = false;
15625                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15626                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
15627                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15628                         continue;
15629                     }
15630                     if (!printed) {
15631                         if (needSep) pw.println();
15632                         needSep = true;
15633                         pw.println("  PID mappings:");
15634                         printed = true;
15635                         printedAnything = true;
15636                     }
15637                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15638                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15639                 }
15640             }
15641         }
15642
15643         if (mImportantProcesses.size() > 0) {
15644             synchronized (mPidsSelfLocked) {
15645                 boolean printed = false;
15646                 for (int i = 0; i< mImportantProcesses.size(); i++) {
15647                     ProcessRecord r = mPidsSelfLocked.get(
15648                             mImportantProcesses.valueAt(i).pid);
15649                     if (dumpPackage != null && (r == null
15650                             || !r.pkgList.containsKey(dumpPackage))) {
15651                         continue;
15652                     }
15653                     if (!printed) {
15654                         if (needSep) pw.println();
15655                         needSep = true;
15656                         pw.println("  Foreground Processes:");
15657                         printed = true;
15658                         printedAnything = true;
15659                     }
15660                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15661                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15662                 }
15663             }
15664         }
15665
15666         if (mPersistentStartingProcesses.size() > 0) {
15667             if (needSep) pw.println();
15668             needSep = true;
15669             printedAnything = true;
15670             pw.println("  Persisent processes that are starting:");
15671             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15672                     "Starting Norm", "Restarting PERS", dumpPackage);
15673         }
15674
15675         if (mRemovedProcesses.size() > 0) {
15676             if (needSep) pw.println();
15677             needSep = true;
15678             printedAnything = true;
15679             pw.println("  Processes that are being removed:");
15680             dumpProcessList(pw, this, mRemovedProcesses, "    ",
15681                     "Removed Norm", "Removed PERS", dumpPackage);
15682         }
15683
15684         if (mProcessesOnHold.size() > 0) {
15685             if (needSep) pw.println();
15686             needSep = true;
15687             printedAnything = true;
15688             pw.println("  Processes that are on old until the system is ready:");
15689             dumpProcessList(pw, this, mProcessesOnHold, "    ",
15690                     "OnHold Norm", "OnHold PERS", dumpPackage);
15691         }
15692
15693         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15694
15695         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15696         if (needSep) {
15697             printedAnything = true;
15698         }
15699
15700         if (dumpPackage == null) {
15701             pw.println();
15702             needSep = false;
15703             mUserController.dump(pw, dumpAll);
15704         }
15705         if (mHomeProcess != null && (dumpPackage == null
15706                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15707             if (needSep) {
15708                 pw.println();
15709                 needSep = false;
15710             }
15711             pw.println("  mHomeProcess: " + mHomeProcess);
15712         }
15713         if (mPreviousProcess != null && (dumpPackage == null
15714                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15715             if (needSep) {
15716                 pw.println();
15717                 needSep = false;
15718             }
15719             pw.println("  mPreviousProcess: " + mPreviousProcess);
15720         }
15721         if (dumpAll) {
15722             StringBuilder sb = new StringBuilder(128);
15723             sb.append("  mPreviousProcessVisibleTime: ");
15724             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15725             pw.println(sb);
15726         }
15727         if (mHeavyWeightProcess != null && (dumpPackage == null
15728                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15729             if (needSep) {
15730                 pw.println();
15731                 needSep = false;
15732             }
15733             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15734         }
15735         if (dumpPackage == null) {
15736             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15737             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15738         }
15739         if (dumpAll) {
15740             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15741             if (mCompatModePackages.getPackages().size() > 0) {
15742                 boolean printed = false;
15743                 for (Map.Entry<String, Integer> entry
15744                         : mCompatModePackages.getPackages().entrySet()) {
15745                     String pkg = entry.getKey();
15746                     int mode = entry.getValue();
15747                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15748                         continue;
15749                     }
15750                     if (!printed) {
15751                         pw.println("  mScreenCompatPackages:");
15752                         printed = true;
15753                     }
15754                     pw.print("    "); pw.print(pkg); pw.print(": ");
15755                             pw.print(mode); pw.println();
15756                 }
15757             }
15758             final int NI = mUidObservers.getRegisteredCallbackCount();
15759             boolean printed = false;
15760             for (int i=0; i<NI; i++) {
15761                 final UidObserverRegistration reg = (UidObserverRegistration)
15762                         mUidObservers.getRegisteredCallbackCookie(i);
15763                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15764                     if (!printed) {
15765                         pw.println("  mUidObservers:");
15766                         printed = true;
15767                     }
15768                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15769                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
15770                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15771                         pw.print(" IDLE");
15772                     }
15773                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15774                         pw.print(" ACT" );
15775                     }
15776                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15777                         pw.print(" GONE");
15778                     }
15779                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15780                         pw.print(" STATE");
15781                         pw.print(" (cut="); pw.print(reg.cutpoint);
15782                         pw.print(")");
15783                     }
15784                     pw.println();
15785                     if (reg.lastProcStates != null) {
15786                         final int NJ = reg.lastProcStates.size();
15787                         for (int j=0; j<NJ; j++) {
15788                             pw.print("      Last ");
15789                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15790                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15791                         }
15792                     }
15793                 }
15794             }
15795             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15796             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15797             if (mPendingTempWhitelist.size() > 0) {
15798                 pw.println("  mPendingTempWhitelist:");
15799                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15800                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15801                     pw.print("    ");
15802                     UserHandle.formatUid(pw, ptw.targetUid);
15803                     pw.print(": ");
15804                     TimeUtils.formatDuration(ptw.duration, pw);
15805                     pw.print(" ");
15806                     pw.println(ptw.tag);
15807                 }
15808             }
15809         }
15810         if (dumpPackage == null) {
15811             pw.println("  mWakefulness="
15812                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
15813             pw.println("  mSleepTokens=" + mSleepTokens);
15814             pw.println("  mSleeping=" + mSleeping);
15815             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15816             if (mRunningVoice != null) {
15817                 pw.println("  mRunningVoice=" + mRunningVoice);
15818                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15819             }
15820         }
15821         pw.println("  mVrController=" + mVrController);
15822         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15823                 || mOrigWaitForDebugger) {
15824             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15825                     || dumpPackage.equals(mOrigDebugApp)) {
15826                 if (needSep) {
15827                     pw.println();
15828                     needSep = false;
15829                 }
15830                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15831                         + " mDebugTransient=" + mDebugTransient
15832                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15833             }
15834         }
15835         if (mCurAppTimeTracker != null) {
15836             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15837         }
15838         if (mMemWatchProcesses.getMap().size() > 0) {
15839             pw.println("  Mem watch processes:");
15840             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15841                     = mMemWatchProcesses.getMap();
15842             for (int i=0; i<procs.size(); i++) {
15843                 final String proc = procs.keyAt(i);
15844                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15845                 for (int j=0; j<uids.size(); j++) {
15846                     if (needSep) {
15847                         pw.println();
15848                         needSep = false;
15849                     }
15850                     StringBuilder sb = new StringBuilder();
15851                     sb.append("    ").append(proc).append('/');
15852                     UserHandle.formatUid(sb, uids.keyAt(j));
15853                     Pair<Long, String> val = uids.valueAt(j);
15854                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15855                     if (val.second != null) {
15856                         sb.append(", report to ").append(val.second);
15857                     }
15858                     pw.println(sb.toString());
15859                 }
15860             }
15861             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15862             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15863             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15864                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15865         }
15866         if (mTrackAllocationApp != null) {
15867             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15868                 if (needSep) {
15869                     pw.println();
15870                     needSep = false;
15871                 }
15872                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15873             }
15874         }
15875         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15876                 || mProfileFd != null) {
15877             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15878                 if (needSep) {
15879                     pw.println();
15880                     needSep = false;
15881                 }
15882                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15883                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15884                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15885                         + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15886                 pw.println("  mProfileType=" + mProfileType);
15887             }
15888         }
15889         if (mNativeDebuggingApp != null) {
15890             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15891                 if (needSep) {
15892                     pw.println();
15893                     needSep = false;
15894                 }
15895                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15896             }
15897         }
15898         if (dumpPackage == null) {
15899             if (mAlwaysFinishActivities) {
15900                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15901             }
15902             if (mController != null) {
15903                 pw.println("  mController=" + mController
15904                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15905             }
15906             if (dumpAll) {
15907                 pw.println("  Total persistent processes: " + numPers);
15908                 pw.println("  mProcessesReady=" + mProcessesReady
15909                         + " mSystemReady=" + mSystemReady
15910                         + " mBooted=" + mBooted
15911                         + " mFactoryTest=" + mFactoryTest);
15912                 pw.println("  mBooting=" + mBooting
15913                         + " mCallFinishBooting=" + mCallFinishBooting
15914                         + " mBootAnimationComplete=" + mBootAnimationComplete);
15915                 pw.print("  mLastPowerCheckRealtime=");
15916                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15917                         pw.println("");
15918                 pw.print("  mLastPowerCheckUptime=");
15919                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15920                         pw.println("");
15921                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15922                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15923                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15924                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15925                         + " (" + mLruProcesses.size() + " total)"
15926                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15927                         + " mNumServiceProcs=" + mNumServiceProcs
15928                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15929                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15930                         + " mLastMemoryLevel=" + mLastMemoryLevel
15931                         + " mLastNumProcesses=" + mLastNumProcesses);
15932                 long now = SystemClock.uptimeMillis();
15933                 pw.print("  mLastIdleTime=");
15934                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
15935                         pw.print(" mLowRamSinceLastIdle=");
15936                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15937                         pw.println();
15938             }
15939         }
15940
15941         if (!printedAnything) {
15942             pw.println("  (nothing)");
15943         }
15944     }
15945
15946     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15947             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15948         if (mProcessesToGc.size() > 0) {
15949             boolean printed = false;
15950             long now = SystemClock.uptimeMillis();
15951             for (int i=0; i<mProcessesToGc.size(); i++) {
15952                 ProcessRecord proc = mProcessesToGc.get(i);
15953                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15954                     continue;
15955                 }
15956                 if (!printed) {
15957                     if (needSep) pw.println();
15958                     needSep = true;
15959                     pw.println("  Processes that are waiting to GC:");
15960                     printed = true;
15961                 }
15962                 pw.print("    Process "); pw.println(proc);
15963                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15964                         pw.print(", last gced=");
15965                         pw.print(now-proc.lastRequestedGc);
15966                         pw.print(" ms ago, last lowMem=");
15967                         pw.print(now-proc.lastLowMemory);
15968                         pw.println(" ms ago");
15969
15970             }
15971         }
15972         return needSep;
15973     }
15974
15975     void printOomLevel(PrintWriter pw, String name, int adj) {
15976         pw.print("    ");
15977         if (adj >= 0) {
15978             pw.print(' ');
15979             if (adj < 10) pw.print(' ');
15980         } else {
15981             if (adj > -10) pw.print(' ');
15982         }
15983         pw.print(adj);
15984         pw.print(": ");
15985         pw.print(name);
15986         pw.print(" (");
15987         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15988         pw.println(")");
15989     }
15990
15991     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15992             int opti, boolean dumpAll) {
15993         boolean needSep = false;
15994
15995         if (mLruProcesses.size() > 0) {
15996             if (needSep) pw.println();
15997             needSep = true;
15998             pw.println("  OOM levels:");
15999             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16000             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16001             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16002             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16003             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16004             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16005             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16006             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16007             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16008             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16009             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16010             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16011             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16012             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16013
16014             if (needSep) pw.println();
16015             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16016                     pw.print(" total, non-act at ");
16017                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16018                     pw.print(", non-svc at ");
16019                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16020                     pw.println("):");
16021             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16022             needSep = true;
16023         }
16024
16025         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16026
16027         pw.println();
16028         pw.println("  mHomeProcess: " + mHomeProcess);
16029         pw.println("  mPreviousProcess: " + mPreviousProcess);
16030         if (mHeavyWeightProcess != null) {
16031             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16032         }
16033
16034         return true;
16035     }
16036
16037     /**
16038      * There are three ways to call this:
16039      *  - no provider specified: dump all the providers
16040      *  - a flattened component name that matched an existing provider was specified as the
16041      *    first arg: dump that one provider
16042      *  - the first arg isn't the flattened component name of an existing provider:
16043      *    dump all providers whose component contains the first arg as a substring
16044      */
16045     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16046             int opti, boolean dumpAll) {
16047         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16048     }
16049
16050     static class ItemMatcher {
16051         ArrayList<ComponentName> components;
16052         ArrayList<String> strings;
16053         ArrayList<Integer> objects;
16054         boolean all;
16055
16056         ItemMatcher() {
16057             all = true;
16058         }
16059
16060         void build(String name) {
16061             ComponentName componentName = ComponentName.unflattenFromString(name);
16062             if (componentName != null) {
16063                 if (components == null) {
16064                     components = new ArrayList<ComponentName>();
16065                 }
16066                 components.add(componentName);
16067                 all = false;
16068             } else {
16069                 int objectId = 0;
16070                 // Not a '/' separated full component name; maybe an object ID?
16071                 try {
16072                     objectId = Integer.parseInt(name, 16);
16073                     if (objects == null) {
16074                         objects = new ArrayList<Integer>();
16075                     }
16076                     objects.add(objectId);
16077                     all = false;
16078                 } catch (RuntimeException e) {
16079                     // Not an integer; just do string match.
16080                     if (strings == null) {
16081                         strings = new ArrayList<String>();
16082                     }
16083                     strings.add(name);
16084                     all = false;
16085                 }
16086             }
16087         }
16088
16089         int build(String[] args, int opti) {
16090             for (; opti<args.length; opti++) {
16091                 String name = args[opti];
16092                 if ("--".equals(name)) {
16093                     return opti+1;
16094                 }
16095                 build(name);
16096             }
16097             return opti;
16098         }
16099
16100         boolean match(Object object, ComponentName comp) {
16101             if (all) {
16102                 return true;
16103             }
16104             if (components != null) {
16105                 for (int i=0; i<components.size(); i++) {
16106                     if (components.get(i).equals(comp)) {
16107                         return true;
16108                     }
16109                 }
16110             }
16111             if (objects != null) {
16112                 for (int i=0; i<objects.size(); i++) {
16113                     if (System.identityHashCode(object) == objects.get(i)) {
16114                         return true;
16115                     }
16116                 }
16117             }
16118             if (strings != null) {
16119                 String flat = comp.flattenToString();
16120                 for (int i=0; i<strings.size(); i++) {
16121                     if (flat.contains(strings.get(i))) {
16122                         return true;
16123                     }
16124                 }
16125             }
16126             return false;
16127         }
16128     }
16129
16130     /**
16131      * There are three things that cmd can be:
16132      *  - a flattened component name that matches an existing activity
16133      *  - the cmd arg isn't the flattened component name of an existing activity:
16134      *    dump all activity whose component contains the cmd as a substring
16135      *  - A hex number of the ActivityRecord object instance.
16136      *
16137      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16138      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16139      */
16140     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16141             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16142         ArrayList<ActivityRecord> activities;
16143
16144         synchronized (this) {
16145             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16146                     dumpFocusedStackOnly);
16147         }
16148
16149         if (activities.size() <= 0) {
16150             return false;
16151         }
16152
16153         String[] newArgs = new String[args.length - opti];
16154         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16155
16156         TaskRecord lastTask = null;
16157         boolean needSep = false;
16158         for (int i=activities.size()-1; i>=0; i--) {
16159             ActivityRecord r = activities.get(i);
16160             if (needSep) {
16161                 pw.println();
16162             }
16163             needSep = true;
16164             synchronized (this) {
16165                 final TaskRecord task = r.getTask();
16166                 if (lastTask != task) {
16167                     lastTask = task;
16168                     pw.print("TASK "); pw.print(lastTask.affinity);
16169                             pw.print(" id="); pw.print(lastTask.taskId);
16170                             pw.print(" userId="); pw.println(lastTask.userId);
16171                     if (dumpAll) {
16172                         lastTask.dump(pw, "  ");
16173                     }
16174                 }
16175             }
16176             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16177         }
16178         return true;
16179     }
16180
16181     /**
16182      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16183      * there is a thread associated with the activity.
16184      */
16185     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16186             final ActivityRecord r, String[] args, boolean dumpAll) {
16187         String innerPrefix = prefix + "  ";
16188         synchronized (this) {
16189             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16190                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16191                     pw.print(" pid=");
16192                     if (r.app != null) pw.println(r.app.pid);
16193                     else pw.println("(not running)");
16194             if (dumpAll) {
16195                 r.dump(pw, innerPrefix);
16196             }
16197         }
16198         if (r.app != null && r.app.thread != null) {
16199             // flush anything that is already in the PrintWriter since the thread is going
16200             // to write to the file descriptor directly
16201             pw.flush();
16202             try {
16203                 TransferPipe tp = new TransferPipe();
16204                 try {
16205                     r.app.thread.dumpActivity(tp.getWriteFd(),
16206                             r.appToken, innerPrefix, args);
16207                     tp.go(fd);
16208                 } finally {
16209                     tp.kill();
16210                 }
16211             } catch (IOException e) {
16212                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16213             } catch (RemoteException e) {
16214                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16215             }
16216         }
16217     }
16218
16219     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16220             int opti, boolean dumpAll, String dumpPackage) {
16221         boolean needSep = false;
16222         boolean onlyHistory = false;
16223         boolean printedAnything = false;
16224
16225         if ("history".equals(dumpPackage)) {
16226             if (opti < args.length && "-s".equals(args[opti])) {
16227                 dumpAll = false;
16228             }
16229             onlyHistory = true;
16230             dumpPackage = null;
16231         }
16232
16233         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16234         if (!onlyHistory && dumpAll) {
16235             if (mRegisteredReceivers.size() > 0) {
16236                 boolean printed = false;
16237                 Iterator it = mRegisteredReceivers.values().iterator();
16238                 while (it.hasNext()) {
16239                     ReceiverList r = (ReceiverList)it.next();
16240                     if (dumpPackage != null && (r.app == null ||
16241                             !dumpPackage.equals(r.app.info.packageName))) {
16242                         continue;
16243                     }
16244                     if (!printed) {
16245                         pw.println("  Registered Receivers:");
16246                         needSep = true;
16247                         printed = true;
16248                         printedAnything = true;
16249                     }
16250                     pw.print("  * "); pw.println(r);
16251                     r.dump(pw, "    ");
16252                 }
16253             }
16254
16255             if (mReceiverResolver.dump(pw, needSep ?
16256                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16257                     "    ", dumpPackage, false, false)) {
16258                 needSep = true;
16259                 printedAnything = true;
16260             }
16261         }
16262
16263         for (BroadcastQueue q : mBroadcastQueues) {
16264             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16265             printedAnything |= needSep;
16266         }
16267
16268         needSep = true;
16269
16270         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16271             for (int user=0; user<mStickyBroadcasts.size(); user++) {
16272                 if (needSep) {
16273                     pw.println();
16274                 }
16275                 needSep = true;
16276                 printedAnything = true;
16277                 pw.print("  Sticky broadcasts for user ");
16278                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16279                 StringBuilder sb = new StringBuilder(128);
16280                 for (Map.Entry<String, ArrayList<Intent>> ent
16281                         : mStickyBroadcasts.valueAt(user).entrySet()) {
16282                     pw.print("  * Sticky action "); pw.print(ent.getKey());
16283                     if (dumpAll) {
16284                         pw.println(":");
16285                         ArrayList<Intent> intents = ent.getValue();
16286                         final int N = intents.size();
16287                         for (int i=0; i<N; i++) {
16288                             sb.setLength(0);
16289                             sb.append("    Intent: ");
16290                             intents.get(i).toShortString(sb, false, true, false, false);
16291                             pw.println(sb.toString());
16292                             Bundle bundle = intents.get(i).getExtras();
16293                             if (bundle != null) {
16294                                 pw.print("      ");
16295                                 pw.println(bundle.toString());
16296                             }
16297                         }
16298                     } else {
16299                         pw.println("");
16300                     }
16301                 }
16302             }
16303         }
16304
16305         if (!onlyHistory && dumpAll) {
16306             pw.println();
16307             for (BroadcastQueue queue : mBroadcastQueues) {
16308                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16309                         + queue.mBroadcastsScheduled);
16310             }
16311             pw.println("  mHandler:");
16312             mHandler.dump(new PrintWriterPrinter(pw), "    ");
16313             needSep = true;
16314             printedAnything = true;
16315         }
16316
16317         if (!printedAnything) {
16318             pw.println("  (nothing)");
16319         }
16320     }
16321
16322     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16323             int opti, boolean dumpAll, String dumpPackage) {
16324         if (mCurBroadcastStats == null) {
16325             return;
16326         }
16327
16328         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16329         final long now = SystemClock.elapsedRealtime();
16330         if (mLastBroadcastStats != null) {
16331             pw.print("  Last stats (from ");
16332             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16333             pw.print(" to ");
16334             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16335             pw.print(", ");
16336             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16337                     - mLastBroadcastStats.mStartUptime, pw);
16338             pw.println(" uptime):");
16339             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16340                 pw.println("    (nothing)");
16341             }
16342             pw.println();
16343         }
16344         pw.print("  Current stats (from ");
16345         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16346         pw.print(" to now, ");
16347         TimeUtils.formatDuration(SystemClock.uptimeMillis()
16348                 - mCurBroadcastStats.mStartUptime, pw);
16349         pw.println(" uptime):");
16350         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16351             pw.println("    (nothing)");
16352         }
16353     }
16354
16355     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16356             int opti, boolean fullCheckin, String dumpPackage) {
16357         if (mCurBroadcastStats == null) {
16358             return;
16359         }
16360
16361         if (mLastBroadcastStats != null) {
16362             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16363             if (fullCheckin) {
16364                 mLastBroadcastStats = null;
16365                 return;
16366             }
16367         }
16368         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16369         if (fullCheckin) {
16370             mCurBroadcastStats = null;
16371         }
16372     }
16373
16374     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16375             int opti, boolean dumpAll, String dumpPackage) {
16376         boolean needSep;
16377         boolean printedAnything = false;
16378
16379         ItemMatcher matcher = new ItemMatcher();
16380         matcher.build(args, opti);
16381
16382         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16383
16384         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16385         printedAnything |= needSep;
16386
16387         if (mLaunchingProviders.size() > 0) {
16388             boolean printed = false;
16389             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16390                 ContentProviderRecord r = mLaunchingProviders.get(i);
16391                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16392                     continue;
16393                 }
16394                 if (!printed) {
16395                     if (needSep) pw.println();
16396                     needSep = true;
16397                     pw.println("  Launching content providers:");
16398                     printed = true;
16399                     printedAnything = true;
16400                 }
16401                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
16402                         pw.println(r);
16403             }
16404         }
16405
16406         if (!printedAnything) {
16407             pw.println("  (nothing)");
16408         }
16409     }
16410
16411     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16412             int opti, boolean dumpAll, String dumpPackage) {
16413         boolean needSep = false;
16414         boolean printedAnything = false;
16415
16416         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16417
16418         if (mGrantedUriPermissions.size() > 0) {
16419             boolean printed = false;
16420             int dumpUid = -2;
16421             if (dumpPackage != null) {
16422                 try {
16423                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16424                             MATCH_ANY_USER, 0);
16425                 } catch (NameNotFoundException e) {
16426                     dumpUid = -1;
16427                 }
16428             }
16429             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16430                 int uid = mGrantedUriPermissions.keyAt(i);
16431                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16432                     continue;
16433                 }
16434                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16435                 if (!printed) {
16436                     if (needSep) pw.println();
16437                     needSep = true;
16438                     pw.println("  Granted Uri Permissions:");
16439                     printed = true;
16440                     printedAnything = true;
16441                 }
16442                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16443                 for (UriPermission perm : perms.values()) {
16444                     pw.print("    "); pw.println(perm);
16445                     if (dumpAll) {
16446                         perm.dump(pw, "      ");
16447                     }
16448                 }
16449             }
16450         }
16451
16452         if (!printedAnything) {
16453             pw.println("  (nothing)");
16454         }
16455     }
16456
16457     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16458             int opti, boolean dumpAll, String dumpPackage) {
16459         boolean printed = false;
16460
16461         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16462
16463         if (mIntentSenderRecords.size() > 0) {
16464             // Organize these by package name, so they are easier to read.
16465             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16466             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16467             final Iterator<WeakReference<PendingIntentRecord>> it
16468                     = mIntentSenderRecords.values().iterator();
16469             while (it.hasNext()) {
16470                 WeakReference<PendingIntentRecord> ref = it.next();
16471                 PendingIntentRecord rec = ref != null ? ref.get() : null;
16472                 if (rec == null) {
16473                     weakRefs.add(ref);
16474                     continue;
16475                 }
16476                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16477                     continue;
16478                 }
16479                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16480                 if (list == null) {
16481                     list = new ArrayList<>();
16482                     byPackage.put(rec.key.packageName, list);
16483                 }
16484                 list.add(rec);
16485             }
16486             for (int i = 0; i < byPackage.size(); i++) {
16487                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16488                 printed = true;
16489                 pw.print("  * "); pw.print(byPackage.keyAt(i));
16490                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16491                 for (int j = 0; j < intents.size(); j++) {
16492                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16493                     if (dumpAll) {
16494                         intents.get(j).dump(pw, "      ");
16495                     }
16496                 }
16497             }
16498             if (weakRefs.size() > 0) {
16499                 printed = true;
16500                 pw.println("  * WEAK REFS:");
16501                 for (int i = 0; i < weakRefs.size(); i++) {
16502                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16503                 }
16504             }
16505         }
16506
16507         if (!printed) {
16508             pw.println("  (nothing)");
16509         }
16510     }
16511
16512     private static final int dumpProcessList(PrintWriter pw,
16513             ActivityManagerService service, List list,
16514             String prefix, String normalLabel, String persistentLabel,
16515             String dumpPackage) {
16516         int numPers = 0;
16517         final int N = list.size()-1;
16518         for (int i=N; i>=0; i--) {
16519             ProcessRecord r = (ProcessRecord)list.get(i);
16520             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16521                 continue;
16522             }
16523             pw.println(String.format("%s%s #%2d: %s",
16524                     prefix, (r.persistent ? persistentLabel : normalLabel),
16525                     i, r.toString()));
16526             if (r.persistent) {
16527                 numPers++;
16528             }
16529         }
16530         return numPers;
16531     }
16532
16533     private static final boolean dumpProcessOomList(PrintWriter pw,
16534             ActivityManagerService service, List<ProcessRecord> origList,
16535             String prefix, String normalLabel, String persistentLabel,
16536             boolean inclDetails, String dumpPackage) {
16537
16538         ArrayList<Pair<ProcessRecord, Integer>> list
16539                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16540         for (int i=0; i<origList.size(); i++) {
16541             ProcessRecord r = origList.get(i);
16542             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16543                 continue;
16544             }
16545             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16546         }
16547
16548         if (list.size() <= 0) {
16549             return false;
16550         }
16551
16552         Comparator<Pair<ProcessRecord, Integer>> comparator
16553                 = new Comparator<Pair<ProcessRecord, Integer>>() {
16554             @Override
16555             public int compare(Pair<ProcessRecord, Integer> object1,
16556                     Pair<ProcessRecord, Integer> object2) {
16557                 if (object1.first.setAdj != object2.first.setAdj) {
16558                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16559                 }
16560                 if (object1.first.setProcState != object2.first.setProcState) {
16561                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16562                 }
16563                 if (object1.second.intValue() != object2.second.intValue()) {
16564                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16565                 }
16566                 return 0;
16567             }
16568         };
16569
16570         Collections.sort(list, comparator);
16571
16572         final long curRealtime = SystemClock.elapsedRealtime();
16573         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16574         final long curUptime = SystemClock.uptimeMillis();
16575         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16576
16577         for (int i=list.size()-1; i>=0; i--) {
16578             ProcessRecord r = list.get(i).first;
16579             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16580             char schedGroup;
16581             switch (r.setSchedGroup) {
16582                 case ProcessList.SCHED_GROUP_BACKGROUND:
16583                     schedGroup = 'B';
16584                     break;
16585                 case ProcessList.SCHED_GROUP_DEFAULT:
16586                     schedGroup = 'F';
16587                     break;
16588                 case ProcessList.SCHED_GROUP_TOP_APP:
16589                     schedGroup = 'T';
16590                     break;
16591                 default:
16592                     schedGroup = '?';
16593                     break;
16594             }
16595             char foreground;
16596             if (r.foregroundActivities) {
16597                 foreground = 'A';
16598             } else if (r.foregroundServices) {
16599                 foreground = 'S';
16600             } else {
16601                 foreground = ' ';
16602             }
16603             String procState = ProcessList.makeProcStateString(r.curProcState);
16604             pw.print(prefix);
16605             pw.print(r.persistent ? persistentLabel : normalLabel);
16606             pw.print(" #");
16607             int num = (origList.size()-1)-list.get(i).second;
16608             if (num < 10) pw.print(' ');
16609             pw.print(num);
16610             pw.print(": ");
16611             pw.print(oomAdj);
16612             pw.print(' ');
16613             pw.print(schedGroup);
16614             pw.print('/');
16615             pw.print(foreground);
16616             pw.print('/');
16617             pw.print(procState);
16618             pw.print(" trm:");
16619             if (r.trimMemoryLevel < 10) pw.print(' ');
16620             pw.print(r.trimMemoryLevel);
16621             pw.print(' ');
16622             pw.print(r.toShortString());
16623             pw.print(" (");
16624             pw.print(r.adjType);
16625             pw.println(')');
16626             if (r.adjSource != null || r.adjTarget != null) {
16627                 pw.print(prefix);
16628                 pw.print("    ");
16629                 if (r.adjTarget instanceof ComponentName) {
16630                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16631                 } else if (r.adjTarget != null) {
16632                     pw.print(r.adjTarget.toString());
16633                 } else {
16634                     pw.print("{null}");
16635                 }
16636                 pw.print("<=");
16637                 if (r.adjSource instanceof ProcessRecord) {
16638                     pw.print("Proc{");
16639                     pw.print(((ProcessRecord)r.adjSource).toShortString());
16640                     pw.println("}");
16641                 } else if (r.adjSource != null) {
16642                     pw.println(r.adjSource.toString());
16643                 } else {
16644                     pw.println("{null}");
16645                 }
16646             }
16647             if (inclDetails) {
16648                 pw.print(prefix);
16649                 pw.print("    ");
16650                 pw.print("oom: max="); pw.print(r.maxAdj);
16651                 pw.print(" curRaw="); pw.print(r.curRawAdj);
16652                 pw.print(" setRaw="); pw.print(r.setRawAdj);
16653                 pw.print(" cur="); pw.print(r.curAdj);
16654                 pw.print(" set="); pw.println(r.setAdj);
16655                 pw.print(prefix);
16656                 pw.print("    ");
16657                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16658                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16659                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16660                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16661                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16662                 pw.println();
16663                 pw.print(prefix);
16664                 pw.print("    ");
16665                 pw.print("cached="); pw.print(r.cached);
16666                 pw.print(" empty="); pw.print(r.empty);
16667                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16668
16669                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16670                     if (r.lastWakeTime != 0) {
16671                         long wtime;
16672                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16673                         synchronized (stats) {
16674                             wtime = stats.getProcessWakeTime(r.info.uid,
16675                                     r.pid, curRealtime);
16676                         }
16677                         long timeUsed = wtime - r.lastWakeTime;
16678                         pw.print(prefix);
16679                         pw.print("    ");
16680                         pw.print("keep awake over ");
16681                         TimeUtils.formatDuration(realtimeSince, pw);
16682                         pw.print(" used ");
16683                         TimeUtils.formatDuration(timeUsed, pw);
16684                         pw.print(" (");
16685                         pw.print((timeUsed*100)/realtimeSince);
16686                         pw.println("%)");
16687                     }
16688                     if (r.lastCpuTime != 0) {
16689                         long timeUsed = r.curCpuTime - r.lastCpuTime;
16690                         pw.print(prefix);
16691                         pw.print("    ");
16692                         pw.print("run cpu over ");
16693                         TimeUtils.formatDuration(uptimeSince, pw);
16694                         pw.print(" used ");
16695                         TimeUtils.formatDuration(timeUsed, pw);
16696                         pw.print(" (");
16697                         pw.print((timeUsed*100)/uptimeSince);
16698                         pw.println("%)");
16699                     }
16700                 }
16701             }
16702         }
16703         return true;
16704     }
16705
16706     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16707             String[] args) {
16708         ArrayList<ProcessRecord> procs;
16709         synchronized (this) {
16710             if (args != null && args.length > start
16711                     && args[start].charAt(0) != '-') {
16712                 procs = new ArrayList<ProcessRecord>();
16713                 int pid = -1;
16714                 try {
16715                     pid = Integer.parseInt(args[start]);
16716                 } catch (NumberFormatException e) {
16717                 }
16718                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16719                     ProcessRecord proc = mLruProcesses.get(i);
16720                     if (proc.pid == pid) {
16721                         procs.add(proc);
16722                     } else if (allPkgs && proc.pkgList != null
16723                             && proc.pkgList.containsKey(args[start])) {
16724                         procs.add(proc);
16725                     } else if (proc.processName.equals(args[start])) {
16726                         procs.add(proc);
16727                     }
16728                 }
16729                 if (procs.size() <= 0) {
16730                     return null;
16731                 }
16732             } else {
16733                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16734             }
16735         }
16736         return procs;
16737     }
16738
16739     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16740             PrintWriter pw, String[] args) {
16741         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16742         if (procs == null) {
16743             pw.println("No process found for: " + args[0]);
16744             return;
16745         }
16746
16747         long uptime = SystemClock.uptimeMillis();
16748         long realtime = SystemClock.elapsedRealtime();
16749         pw.println("Applications Graphics Acceleration Info:");
16750         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16751
16752         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16753             ProcessRecord r = procs.get(i);
16754             if (r.thread != null) {
16755                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16756                 pw.flush();
16757                 try {
16758                     TransferPipe tp = new TransferPipe();
16759                     try {
16760                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16761                         tp.go(fd);
16762                     } finally {
16763                         tp.kill();
16764                     }
16765                 } catch (IOException e) {
16766                     pw.println("Failure while dumping the app: " + r);
16767                     pw.flush();
16768                 } catch (RemoteException e) {
16769                     pw.println("Got a RemoteException while dumping the app " + r);
16770                     pw.flush();
16771                 }
16772             }
16773         }
16774     }
16775
16776     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16777         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16778         if (procs == null) {
16779             pw.println("No process found for: " + args[0]);
16780             return;
16781         }
16782
16783         pw.println("Applications Database Info:");
16784
16785         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16786             ProcessRecord r = procs.get(i);
16787             if (r.thread != null) {
16788                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16789                 pw.flush();
16790                 try {
16791                     TransferPipe tp = new TransferPipe();
16792                     try {
16793                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
16794                         tp.go(fd);
16795                     } finally {
16796                         tp.kill();
16797                     }
16798                 } catch (IOException e) {
16799                     pw.println("Failure while dumping the app: " + r);
16800                     pw.flush();
16801                 } catch (RemoteException e) {
16802                     pw.println("Got a RemoteException while dumping the app " + r);
16803                     pw.flush();
16804                 }
16805             }
16806         }
16807     }
16808
16809     final static class MemItem {
16810         final boolean isProc;
16811         final String label;
16812         final String shortLabel;
16813         final long pss;
16814         final long swapPss;
16815         final int id;
16816         final boolean hasActivities;
16817         ArrayList<MemItem> subitems;
16818
16819         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16820                 boolean _hasActivities) {
16821             isProc = true;
16822             label = _label;
16823             shortLabel = _shortLabel;
16824             pss = _pss;
16825             swapPss = _swapPss;
16826             id = _id;
16827             hasActivities = _hasActivities;
16828         }
16829
16830         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16831             isProc = false;
16832             label = _label;
16833             shortLabel = _shortLabel;
16834             pss = _pss;
16835             swapPss = _swapPss;
16836             id = _id;
16837             hasActivities = false;
16838         }
16839     }
16840
16841     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16842             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16843         if (sort && !isCompact) {
16844             Collections.sort(items, new Comparator<MemItem>() {
16845                 @Override
16846                 public int compare(MemItem lhs, MemItem rhs) {
16847                     if (lhs.pss < rhs.pss) {
16848                         return 1;
16849                     } else if (lhs.pss > rhs.pss) {
16850                         return -1;
16851                     }
16852                     return 0;
16853                 }
16854             });
16855         }
16856
16857         for (int i=0; i<items.size(); i++) {
16858             MemItem mi = items.get(i);
16859             if (!isCompact) {
16860                 if (dumpSwapPss) {
16861                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16862                             mi.label, stringifyKBSize(mi.swapPss));
16863                 } else {
16864                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16865                 }
16866             } else if (mi.isProc) {
16867                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16868                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16869                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16870                 pw.println(mi.hasActivities ? ",a" : ",e");
16871             } else {
16872                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16873                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16874             }
16875             if (mi.subitems != null) {
16876                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16877                         true, isCompact, dumpSwapPss);
16878             }
16879         }
16880     }
16881
16882     // These are in KB.
16883     static final long[] DUMP_MEM_BUCKETS = new long[] {
16884         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16885         120*1024, 160*1024, 200*1024,
16886         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16887         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16888     };
16889
16890     static final void appendMemBucket(StringBuilder out, long memKB, String label,
16891             boolean stackLike) {
16892         int start = label.lastIndexOf('.');
16893         if (start >= 0) start++;
16894         else start = 0;
16895         int end = label.length();
16896         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16897             if (DUMP_MEM_BUCKETS[i] >= memKB) {
16898                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16899                 out.append(bucket);
16900                 out.append(stackLike ? "MB." : "MB ");
16901                 out.append(label, start, end);
16902                 return;
16903             }
16904         }
16905         out.append(memKB/1024);
16906         out.append(stackLike ? "MB." : "MB ");
16907         out.append(label, start, end);
16908     }
16909
16910     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16911             ProcessList.NATIVE_ADJ,
16912             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16913             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16914             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16915             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16916             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16917             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16918     };
16919     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16920             "Native",
16921             "System", "Persistent", "Persistent Service", "Foreground",
16922             "Visible", "Perceptible",
16923             "Heavy Weight", "Backup",
16924             "A Services", "Home",
16925             "Previous", "B Services", "Cached"
16926     };
16927     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16928             "native",
16929             "sys", "pers", "persvc", "fore",
16930             "vis", "percept",
16931             "heavy", "backup",
16932             "servicea", "home",
16933             "prev", "serviceb", "cached"
16934     };
16935
16936     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16937             long realtime, boolean isCheckinRequest, boolean isCompact) {
16938         if (isCompact) {
16939             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16940         }
16941         if (isCheckinRequest || isCompact) {
16942             // short checkin version
16943             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16944         } else {
16945             pw.println("Applications Memory Usage (in Kilobytes):");
16946             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16947         }
16948     }
16949
16950     private static final int KSM_SHARED = 0;
16951     private static final int KSM_SHARING = 1;
16952     private static final int KSM_UNSHARED = 2;
16953     private static final int KSM_VOLATILE = 3;
16954
16955     private final long[] getKsmInfo() {
16956         long[] longOut = new long[4];
16957         final int[] SINGLE_LONG_FORMAT = new int[] {
16958             PROC_SPACE_TERM| PROC_OUT_LONG
16959         };
16960         long[] longTmp = new long[1];
16961         readProcFile("/sys/kernel/mm/ksm/pages_shared",
16962                 SINGLE_LONG_FORMAT, null, longTmp, null);
16963         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16964         longTmp[0] = 0;
16965         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16966                 SINGLE_LONG_FORMAT, null, longTmp, null);
16967         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16968         longTmp[0] = 0;
16969         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16970                 SINGLE_LONG_FORMAT, null, longTmp, null);
16971         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16972         longTmp[0] = 0;
16973         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16974                 SINGLE_LONG_FORMAT, null, longTmp, null);
16975         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16976         return longOut;
16977     }
16978
16979     private static String stringifySize(long size, int order) {
16980         Locale locale = Locale.US;
16981         switch (order) {
16982             case 1:
16983                 return String.format(locale, "%,13d", size);
16984             case 1024:
16985                 return String.format(locale, "%,9dK", size / 1024);
16986             case 1024 * 1024:
16987                 return String.format(locale, "%,5dM", size / 1024 / 1024);
16988             case 1024 * 1024 * 1024:
16989                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16990             default:
16991                 throw new IllegalArgumentException("Invalid size order");
16992         }
16993     }
16994
16995     private static String stringifyKBSize(long size) {
16996         return stringifySize(size * 1024, 1024);
16997     }
16998
16999     // Update this version number in case you change the 'compact' format
17000     private static final int MEMINFO_COMPACT_VERSION = 1;
17001
17002     final void dumpApplicationMemoryUsage(FileDescriptor fd,
17003             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17004         boolean dumpDetails = false;
17005         boolean dumpFullDetails = false;
17006         boolean dumpDalvik = false;
17007         boolean dumpSummaryOnly = false;
17008         boolean dumpUnreachable = false;
17009         boolean oomOnly = false;
17010         boolean isCompact = false;
17011         boolean localOnly = false;
17012         boolean packages = false;
17013         boolean isCheckinRequest = false;
17014         boolean dumpSwapPss = false;
17015
17016         int opti = 0;
17017         while (opti < args.length) {
17018             String opt = args[opti];
17019             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17020                 break;
17021             }
17022             opti++;
17023             if ("-a".equals(opt)) {
17024                 dumpDetails = true;
17025                 dumpFullDetails = true;
17026                 dumpDalvik = true;
17027                 dumpSwapPss = true;
17028             } else if ("-d".equals(opt)) {
17029                 dumpDalvik = true;
17030             } else if ("-c".equals(opt)) {
17031                 isCompact = true;
17032             } else if ("-s".equals(opt)) {
17033                 dumpDetails = true;
17034                 dumpSummaryOnly = true;
17035             } else if ("-S".equals(opt)) {
17036                 dumpSwapPss = true;
17037             } else if ("--unreachable".equals(opt)) {
17038                 dumpUnreachable = true;
17039             } else if ("--oom".equals(opt)) {
17040                 oomOnly = true;
17041             } else if ("--local".equals(opt)) {
17042                 localOnly = true;
17043             } else if ("--package".equals(opt)) {
17044                 packages = true;
17045             } else if ("--checkin".equals(opt)) {
17046                 isCheckinRequest = true;
17047
17048             } else if ("-h".equals(opt)) {
17049                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17050                 pw.println("  -a: include all available information for each process.");
17051                 pw.println("  -d: include dalvik details.");
17052                 pw.println("  -c: dump in a compact machine-parseable representation.");
17053                 pw.println("  -s: dump only summary of application memory usage.");
17054                 pw.println("  -S: dump also SwapPss.");
17055                 pw.println("  --oom: only show processes organized by oom adj.");
17056                 pw.println("  --local: only collect details locally, don't call process.");
17057                 pw.println("  --package: interpret process arg as package, dumping all");
17058                 pw.println("             processes that have loaded that package.");
17059                 pw.println("  --checkin: dump data for a checkin");
17060                 pw.println("If [process] is specified it can be the name or ");
17061                 pw.println("pid of a specific process to dump.");
17062                 return;
17063             } else {
17064                 pw.println("Unknown argument: " + opt + "; use -h for help");
17065             }
17066         }
17067
17068         long uptime = SystemClock.uptimeMillis();
17069         long realtime = SystemClock.elapsedRealtime();
17070         final long[] tmpLong = new long[1];
17071
17072         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17073         if (procs == null) {
17074             // No Java processes.  Maybe they want to print a native process.
17075             if (args != null && args.length > opti
17076                     && args[opti].charAt(0) != '-') {
17077                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17078                         = new ArrayList<ProcessCpuTracker.Stats>();
17079                 updateCpuStatsNow();
17080                 int findPid = -1;
17081                 try {
17082                     findPid = Integer.parseInt(args[opti]);
17083                 } catch (NumberFormatException e) {
17084                 }
17085                 synchronized (mProcessCpuTracker) {
17086                     final int N = mProcessCpuTracker.countStats();
17087                     for (int i=0; i<N; i++) {
17088                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17089                         if (st.pid == findPid || (st.baseName != null
17090                                 && st.baseName.equals(args[opti]))) {
17091                             nativeProcs.add(st);
17092                         }
17093                     }
17094                 }
17095                 if (nativeProcs.size() > 0) {
17096                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17097                             isCompact);
17098                     Debug.MemoryInfo mi = null;
17099                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17100                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17101                         final int pid = r.pid;
17102                         if (!isCheckinRequest && dumpDetails) {
17103                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17104                         }
17105                         if (mi == null) {
17106                             mi = new Debug.MemoryInfo();
17107                         }
17108                         if (dumpDetails || (!brief && !oomOnly)) {
17109                             Debug.getMemoryInfo(pid, mi);
17110                         } else {
17111                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17112                             mi.dalvikPrivateDirty = (int)tmpLong[0];
17113                         }
17114                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17115                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17116                         if (isCheckinRequest) {
17117                             pw.println();
17118                         }
17119                     }
17120                     return;
17121                 }
17122             }
17123             pw.println("No process found for: " + args[opti]);
17124             return;
17125         }
17126
17127         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17128             dumpDetails = true;
17129         }
17130
17131         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17132
17133         String[] innerArgs = new String[args.length-opti];
17134         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17135
17136         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17137         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17138         long nativePss = 0;
17139         long nativeSwapPss = 0;
17140         long dalvikPss = 0;
17141         long dalvikSwapPss = 0;
17142         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17143                 EmptyArray.LONG;
17144         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17145                 EmptyArray.LONG;
17146         long otherPss = 0;
17147         long otherSwapPss = 0;
17148         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17149         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17150
17151         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17152         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17153         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17154                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17155
17156         long totalPss = 0;
17157         long totalSwapPss = 0;
17158         long cachedPss = 0;
17159         long cachedSwapPss = 0;
17160         boolean hasSwapPss = false;
17161
17162         Debug.MemoryInfo mi = null;
17163         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17164             final ProcessRecord r = procs.get(i);
17165             final IApplicationThread thread;
17166             final int pid;
17167             final int oomAdj;
17168             final boolean hasActivities;
17169             synchronized (this) {
17170                 thread = r.thread;
17171                 pid = r.pid;
17172                 oomAdj = r.getSetAdjWithServices();
17173                 hasActivities = r.activities.size() > 0;
17174             }
17175             if (thread != null) {
17176                 if (!isCheckinRequest && dumpDetails) {
17177                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17178                 }
17179                 if (mi == null) {
17180                     mi = new Debug.MemoryInfo();
17181                 }
17182                 if (dumpDetails || (!brief && !oomOnly)) {
17183                     Debug.getMemoryInfo(pid, mi);
17184                     hasSwapPss = mi.hasSwappedOutPss;
17185                 } else {
17186                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17187                     mi.dalvikPrivateDirty = (int)tmpLong[0];
17188                 }
17189                 if (dumpDetails) {
17190                     if (localOnly) {
17191                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17192                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17193                         if (isCheckinRequest) {
17194                             pw.println();
17195                         }
17196                     } else {
17197                         pw.flush();
17198                         try {
17199                             TransferPipe tp = new TransferPipe();
17200                             try {
17201                                 thread.dumpMemInfo(tp.getWriteFd(),
17202                                         mi, isCheckinRequest, dumpFullDetails,
17203                                         dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17204                                 tp.go(fd);
17205                             } finally {
17206                                 tp.kill();
17207                             }
17208                         } catch (IOException e) {
17209                             if (!isCheckinRequest) {
17210                                 pw.println("Got IoException!");
17211                                 pw.flush();
17212                             }
17213                         } catch (RemoteException e) {
17214                             if (!isCheckinRequest) {
17215                                 pw.println("Got RemoteException!");
17216                                 pw.flush();
17217                             }
17218                         }
17219                     }
17220                 }
17221
17222                 final long myTotalPss = mi.getTotalPss();
17223                 final long myTotalUss = mi.getTotalUss();
17224                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17225
17226                 synchronized (this) {
17227                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17228                         // Record this for posterity if the process has been stable.
17229                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17230                     }
17231                 }
17232
17233                 if (!isCheckinRequest && mi != null) {
17234                     totalPss += myTotalPss;
17235                     totalSwapPss += myTotalSwapPss;
17236                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17237                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17238                             myTotalSwapPss, pid, hasActivities);
17239                     procMems.add(pssItem);
17240                     procMemsMap.put(pid, pssItem);
17241
17242                     nativePss += mi.nativePss;
17243                     nativeSwapPss += mi.nativeSwappedOutPss;
17244                     dalvikPss += mi.dalvikPss;
17245                     dalvikSwapPss += mi.dalvikSwappedOutPss;
17246                     for (int j=0; j<dalvikSubitemPss.length; j++) {
17247                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17248                         dalvikSubitemSwapPss[j] +=
17249                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17250                     }
17251                     otherPss += mi.otherPss;
17252                     otherSwapPss += mi.otherSwappedOutPss;
17253                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17254                         long mem = mi.getOtherPss(j);
17255                         miscPss[j] += mem;
17256                         otherPss -= mem;
17257                         mem = mi.getOtherSwappedOutPss(j);
17258                         miscSwapPss[j] += mem;
17259                         otherSwapPss -= mem;
17260                     }
17261
17262                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17263                         cachedPss += myTotalPss;
17264                         cachedSwapPss += myTotalSwapPss;
17265                     }
17266
17267                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17268                         if (oomIndex == (oomPss.length - 1)
17269                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17270                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17271                             oomPss[oomIndex] += myTotalPss;
17272                             oomSwapPss[oomIndex] += myTotalSwapPss;
17273                             if (oomProcs[oomIndex] == null) {
17274                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
17275                             }
17276                             oomProcs[oomIndex].add(pssItem);
17277                             break;
17278                         }
17279                     }
17280                 }
17281             }
17282         }
17283
17284         long nativeProcTotalPss = 0;
17285
17286         if (!isCheckinRequest && procs.size() > 1 && !packages) {
17287             // If we are showing aggregations, also look for native processes to
17288             // include so that our aggregations are more accurate.
17289             updateCpuStatsNow();
17290             mi = null;
17291             synchronized (mProcessCpuTracker) {
17292                 final int N = mProcessCpuTracker.countStats();
17293                 for (int i=0; i<N; i++) {
17294                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17295                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17296                         if (mi == null) {
17297                             mi = new Debug.MemoryInfo();
17298                         }
17299                         if (!brief && !oomOnly) {
17300                             Debug.getMemoryInfo(st.pid, mi);
17301                         } else {
17302                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17303                             mi.nativePrivateDirty = (int)tmpLong[0];
17304                         }
17305
17306                         final long myTotalPss = mi.getTotalPss();
17307                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17308                         totalPss += myTotalPss;
17309                         nativeProcTotalPss += myTotalPss;
17310
17311                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17312                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17313                         procMems.add(pssItem);
17314
17315                         nativePss += mi.nativePss;
17316                         nativeSwapPss += mi.nativeSwappedOutPss;
17317                         dalvikPss += mi.dalvikPss;
17318                         dalvikSwapPss += mi.dalvikSwappedOutPss;
17319                         for (int j=0; j<dalvikSubitemPss.length; j++) {
17320                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17321                             dalvikSubitemSwapPss[j] +=
17322                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17323                         }
17324                         otherPss += mi.otherPss;
17325                         otherSwapPss += mi.otherSwappedOutPss;
17326                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17327                             long mem = mi.getOtherPss(j);
17328                             miscPss[j] += mem;
17329                             otherPss -= mem;
17330                             mem = mi.getOtherSwappedOutPss(j);
17331                             miscSwapPss[j] += mem;
17332                             otherSwapPss -= mem;
17333                         }
17334                         oomPss[0] += myTotalPss;
17335                         oomSwapPss[0] += myTotalSwapPss;
17336                         if (oomProcs[0] == null) {
17337                             oomProcs[0] = new ArrayList<MemItem>();
17338                         }
17339                         oomProcs[0].add(pssItem);
17340                     }
17341                 }
17342             }
17343
17344             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17345
17346             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17347             final MemItem dalvikItem =
17348                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17349             if (dalvikSubitemPss.length > 0) {
17350                 dalvikItem.subitems = new ArrayList<MemItem>();
17351                 for (int j=0; j<dalvikSubitemPss.length; j++) {
17352                     final String name = Debug.MemoryInfo.getOtherLabel(
17353                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
17354                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17355                                     dalvikSubitemSwapPss[j], j));
17356                 }
17357             }
17358             catMems.add(dalvikItem);
17359             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17360             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17361                 String label = Debug.MemoryInfo.getOtherLabel(j);
17362                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17363             }
17364
17365             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17366             for (int j=0; j<oomPss.length; j++) {
17367                 if (oomPss[j] != 0) {
17368                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17369                             : DUMP_MEM_OOM_LABEL[j];
17370                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17371                             DUMP_MEM_OOM_ADJ[j]);
17372                     item.subitems = oomProcs[j];
17373                     oomMems.add(item);
17374                 }
17375             }
17376
17377             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17378             if (!brief && !oomOnly && !isCompact) {
17379                 pw.println();
17380                 pw.println("Total PSS by process:");
17381                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17382                 pw.println();
17383             }
17384             if (!isCompact) {
17385                 pw.println("Total PSS by OOM adjustment:");
17386             }
17387             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17388             if (!brief && !oomOnly) {
17389                 PrintWriter out = categoryPw != null ? categoryPw : pw;
17390                 if (!isCompact) {
17391                     out.println();
17392                     out.println("Total PSS by category:");
17393                 }
17394                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17395             }
17396             if (!isCompact) {
17397                 pw.println();
17398             }
17399             MemInfoReader memInfo = new MemInfoReader();
17400             memInfo.readMemInfo();
17401             if (nativeProcTotalPss > 0) {
17402                 synchronized (this) {
17403                     final long cachedKb = memInfo.getCachedSizeKb();
17404                     final long freeKb = memInfo.getFreeSizeKb();
17405                     final long zramKb = memInfo.getZramTotalSizeKb();
17406                     final long kernelKb = memInfo.getKernelUsedSizeKb();
17407                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17408                             kernelKb*1024, nativeProcTotalPss*1024);
17409                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17410                             nativeProcTotalPss);
17411                 }
17412             }
17413             if (!brief) {
17414                 if (!isCompact) {
17415                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17416                     pw.print(" (status ");
17417                     switch (mLastMemoryLevel) {
17418                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17419                             pw.println("normal)");
17420                             break;
17421                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17422                             pw.println("moderate)");
17423                             break;
17424                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
17425                             pw.println("low)");
17426                             break;
17427                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17428                             pw.println("critical)");
17429                             break;
17430                         default:
17431                             pw.print(mLastMemoryLevel);
17432                             pw.println(")");
17433                             break;
17434                     }
17435                     pw.print(" Free RAM: ");
17436                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17437                             + memInfo.getFreeSizeKb()));
17438                     pw.print(" (");
17439                     pw.print(stringifyKBSize(cachedPss));
17440                     pw.print(" cached pss + ");
17441                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17442                     pw.print(" cached kernel + ");
17443                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17444                     pw.println(" free)");
17445                 } else {
17446                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17447                     pw.print(cachedPss + memInfo.getCachedSizeKb()
17448                             + memInfo.getFreeSizeKb()); pw.print(",");
17449                     pw.println(totalPss - cachedPss);
17450                 }
17451             }
17452             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17453                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17454                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17455             if (!isCompact) {
17456                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17457                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17458                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17459                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17460                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17461             } else {
17462                 pw.print("lostram,"); pw.println(lostRAM);
17463             }
17464             if (!brief) {
17465                 if (memInfo.getZramTotalSizeKb() != 0) {
17466                     if (!isCompact) {
17467                         pw.print("     ZRAM: ");
17468                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17469                                 pw.print(" physical used for ");
17470                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17471                                         - memInfo.getSwapFreeSizeKb()));
17472                                 pw.print(" in swap (");
17473                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17474                                 pw.println(" total swap)");
17475                     } else {
17476                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17477                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17478                                 pw.println(memInfo.getSwapFreeSizeKb());
17479                     }
17480                 }
17481                 final long[] ksm = getKsmInfo();
17482                 if (!isCompact) {
17483                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17484                             || ksm[KSM_VOLATILE] != 0) {
17485                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17486                                 pw.print(" saved from shared ");
17487                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17488                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17489                                 pw.print(" unshared; ");
17490                                 pw.print(stringifyKBSize(
17491                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
17492                     }
17493                     pw.print("   Tuning: ");
17494                     pw.print(ActivityManager.staticGetMemoryClass());
17495                     pw.print(" (large ");
17496                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17497                     pw.print("), oom ");
17498                     pw.print(stringifySize(
17499                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17500                     pw.print(", restore limit ");
17501                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17502                     if (ActivityManager.isLowRamDeviceStatic()) {
17503                         pw.print(" (low-ram)");
17504                     }
17505                     if (ActivityManager.isHighEndGfx()) {
17506                         pw.print(" (high-end-gfx)");
17507                     }
17508                     pw.println();
17509                 } else {
17510                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17511                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17512                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17513                     pw.print("tuning,");
17514                     pw.print(ActivityManager.staticGetMemoryClass());
17515                     pw.print(',');
17516                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17517                     pw.print(',');
17518                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17519                     if (ActivityManager.isLowRamDeviceStatic()) {
17520                         pw.print(",low-ram");
17521                     }
17522                     if (ActivityManager.isHighEndGfx()) {
17523                         pw.print(",high-end-gfx");
17524                     }
17525                     pw.println();
17526                 }
17527             }
17528         }
17529     }
17530
17531     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17532             long memtrack, String name) {
17533         sb.append("  ");
17534         sb.append(ProcessList.makeOomAdjString(oomAdj));
17535         sb.append(' ');
17536         sb.append(ProcessList.makeProcStateString(procState));
17537         sb.append(' ');
17538         ProcessList.appendRamKb(sb, pss);
17539         sb.append(": ");
17540         sb.append(name);
17541         if (memtrack > 0) {
17542             sb.append(" (");
17543             sb.append(stringifyKBSize(memtrack));
17544             sb.append(" memtrack)");
17545         }
17546     }
17547
17548     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17549         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17550         sb.append(" (pid ");
17551         sb.append(mi.pid);
17552         sb.append(") ");
17553         sb.append(mi.adjType);
17554         sb.append('\n');
17555         if (mi.adjReason != null) {
17556             sb.append("                      ");
17557             sb.append(mi.adjReason);
17558             sb.append('\n');
17559         }
17560     }
17561
17562     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17563         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17564         for (int i=0, N=memInfos.size(); i<N; i++) {
17565             ProcessMemInfo mi = memInfos.get(i);
17566             infoMap.put(mi.pid, mi);
17567         }
17568         updateCpuStatsNow();
17569         long[] memtrackTmp = new long[1];
17570         final List<ProcessCpuTracker.Stats> stats;
17571         // Get a list of Stats that have vsize > 0
17572         synchronized (mProcessCpuTracker) {
17573             stats = mProcessCpuTracker.getStats((st) -> {
17574                 return st.vsize > 0;
17575             });
17576         }
17577         final int statsCount = stats.size();
17578         for (int i = 0; i < statsCount; i++) {
17579             ProcessCpuTracker.Stats st = stats.get(i);
17580             long pss = Debug.getPss(st.pid, null, memtrackTmp);
17581             if (pss > 0) {
17582                 if (infoMap.indexOfKey(st.pid) < 0) {
17583                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17584                             ProcessList.NATIVE_ADJ, -1, "native", null);
17585                     mi.pss = pss;
17586                     mi.memtrack = memtrackTmp[0];
17587                     memInfos.add(mi);
17588                 }
17589             }
17590         }
17591
17592         long totalPss = 0;
17593         long totalMemtrack = 0;
17594         for (int i=0, N=memInfos.size(); i<N; i++) {
17595             ProcessMemInfo mi = memInfos.get(i);
17596             if (mi.pss == 0) {
17597                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17598                 mi.memtrack = memtrackTmp[0];
17599             }
17600             totalPss += mi.pss;
17601             totalMemtrack += mi.memtrack;
17602         }
17603         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17604             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17605                 if (lhs.oomAdj != rhs.oomAdj) {
17606                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17607                 }
17608                 if (lhs.pss != rhs.pss) {
17609                     return lhs.pss < rhs.pss ? 1 : -1;
17610                 }
17611                 return 0;
17612             }
17613         });
17614
17615         StringBuilder tag = new StringBuilder(128);
17616         StringBuilder stack = new StringBuilder(128);
17617         tag.append("Low on memory -- ");
17618         appendMemBucket(tag, totalPss, "total", false);
17619         appendMemBucket(stack, totalPss, "total", true);
17620
17621         StringBuilder fullNativeBuilder = new StringBuilder(1024);
17622         StringBuilder shortNativeBuilder = new StringBuilder(1024);
17623         StringBuilder fullJavaBuilder = new StringBuilder(1024);
17624
17625         boolean firstLine = true;
17626         int lastOomAdj = Integer.MIN_VALUE;
17627         long extraNativeRam = 0;
17628         long extraNativeMemtrack = 0;
17629         long cachedPss = 0;
17630         for (int i=0, N=memInfos.size(); i<N; i++) {
17631             ProcessMemInfo mi = memInfos.get(i);
17632
17633             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17634                 cachedPss += mi.pss;
17635             }
17636
17637             if (mi.oomAdj != ProcessList.NATIVE_ADJ
17638                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
17639                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
17640                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17641                 if (lastOomAdj != mi.oomAdj) {
17642                     lastOomAdj = mi.oomAdj;
17643                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17644                         tag.append(" / ");
17645                     }
17646                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17647                         if (firstLine) {
17648                             stack.append(":");
17649                             firstLine = false;
17650                         }
17651                         stack.append("\n\t at ");
17652                     } else {
17653                         stack.append("$");
17654                     }
17655                 } else {
17656                     tag.append(" ");
17657                     stack.append("$");
17658                 }
17659                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17660                     appendMemBucket(tag, mi.pss, mi.name, false);
17661                 }
17662                 appendMemBucket(stack, mi.pss, mi.name, true);
17663                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17664                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17665                     stack.append("(");
17666                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17667                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17668                             stack.append(DUMP_MEM_OOM_LABEL[k]);
17669                             stack.append(":");
17670                             stack.append(DUMP_MEM_OOM_ADJ[k]);
17671                         }
17672                     }
17673                     stack.append(")");
17674                 }
17675             }
17676
17677             appendMemInfo(fullNativeBuilder, mi);
17678             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17679                 // The short form only has native processes that are >= 512K.
17680                 if (mi.pss >= 512) {
17681                     appendMemInfo(shortNativeBuilder, mi);
17682                 } else {
17683                     extraNativeRam += mi.pss;
17684                     extraNativeMemtrack += mi.memtrack;
17685                 }
17686             } else {
17687                 // Short form has all other details, but if we have collected RAM
17688                 // from smaller native processes let's dump a summary of that.
17689                 if (extraNativeRam > 0) {
17690                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17691                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17692                     shortNativeBuilder.append('\n');
17693                     extraNativeRam = 0;
17694                 }
17695                 appendMemInfo(fullJavaBuilder, mi);
17696             }
17697         }
17698
17699         fullJavaBuilder.append("           ");
17700         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17701         fullJavaBuilder.append(": TOTAL");
17702         if (totalMemtrack > 0) {
17703             fullJavaBuilder.append(" (");
17704             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17705             fullJavaBuilder.append(" memtrack)");
17706         } else {
17707         }
17708         fullJavaBuilder.append("\n");
17709
17710         MemInfoReader memInfo = new MemInfoReader();
17711         memInfo.readMemInfo();
17712         final long[] infos = memInfo.getRawInfo();
17713
17714         StringBuilder memInfoBuilder = new StringBuilder(1024);
17715         Debug.getMemInfo(infos);
17716         memInfoBuilder.append("  MemInfo: ");
17717         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17718         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17719         memInfoBuilder.append(stringifyKBSize(
17720                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17721         memInfoBuilder.append(stringifyKBSize(
17722                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17723         memInfoBuilder.append(stringifyKBSize(
17724                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17725         memInfoBuilder.append("           ");
17726         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17727         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17728         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17729         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17730         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17731             memInfoBuilder.append("  ZRAM: ");
17732             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17733             memInfoBuilder.append(" RAM, ");
17734             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17735             memInfoBuilder.append(" swap total, ");
17736             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17737             memInfoBuilder.append(" swap free\n");
17738         }
17739         final long[] ksm = getKsmInfo();
17740         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17741                 || ksm[KSM_VOLATILE] != 0) {
17742             memInfoBuilder.append("  KSM: ");
17743             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17744             memInfoBuilder.append(" saved from shared ");
17745             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17746             memInfoBuilder.append("\n       ");
17747             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17748             memInfoBuilder.append(" unshared; ");
17749             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17750             memInfoBuilder.append(" volatile\n");
17751         }
17752         memInfoBuilder.append("  Free RAM: ");
17753         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17754                 + memInfo.getFreeSizeKb()));
17755         memInfoBuilder.append("\n");
17756         memInfoBuilder.append("  Used RAM: ");
17757         memInfoBuilder.append(stringifyKBSize(
17758                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17759         memInfoBuilder.append("\n");
17760         memInfoBuilder.append("  Lost RAM: ");
17761         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17762                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17763                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17764         memInfoBuilder.append("\n");
17765         Slog.i(TAG, "Low on memory:");
17766         Slog.i(TAG, shortNativeBuilder.toString());
17767         Slog.i(TAG, fullJavaBuilder.toString());
17768         Slog.i(TAG, memInfoBuilder.toString());
17769
17770         StringBuilder dropBuilder = new StringBuilder(1024);
17771         /*
17772         StringWriter oomSw = new StringWriter();
17773         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17774         StringWriter catSw = new StringWriter();
17775         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17776         String[] emptyArgs = new String[] { };
17777         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17778         oomPw.flush();
17779         String oomString = oomSw.toString();
17780         */
17781         dropBuilder.append("Low on memory:");
17782         dropBuilder.append(stack);
17783         dropBuilder.append('\n');
17784         dropBuilder.append(fullNativeBuilder);
17785         dropBuilder.append(fullJavaBuilder);
17786         dropBuilder.append('\n');
17787         dropBuilder.append(memInfoBuilder);
17788         dropBuilder.append('\n');
17789         /*
17790         dropBuilder.append(oomString);
17791         dropBuilder.append('\n');
17792         */
17793         StringWriter catSw = new StringWriter();
17794         synchronized (ActivityManagerService.this) {
17795             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17796             String[] emptyArgs = new String[] { };
17797             catPw.println();
17798             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17799             catPw.println();
17800             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17801                     false, null).dumpLocked();
17802             catPw.println();
17803             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17804             catPw.flush();
17805         }
17806         dropBuilder.append(catSw.toString());
17807         addErrorToDropBox("lowmem", null, "system_server", null,
17808                 null, tag.toString(), dropBuilder.toString(), null, null);
17809         //Slog.i(TAG, "Sent to dropbox:");
17810         //Slog.i(TAG, dropBuilder.toString());
17811         synchronized (ActivityManagerService.this) {
17812             long now = SystemClock.uptimeMillis();
17813             if (mLastMemUsageReportTime < now) {
17814                 mLastMemUsageReportTime = now;
17815             }
17816         }
17817     }
17818
17819     /**
17820      * Searches array of arguments for the specified string
17821      * @param args array of argument strings
17822      * @param value value to search for
17823      * @return true if the value is contained in the array
17824      */
17825     private static boolean scanArgs(String[] args, String value) {
17826         if (args != null) {
17827             for (String arg : args) {
17828                 if (value.equals(arg)) {
17829                     return true;
17830                 }
17831             }
17832         }
17833         return false;
17834     }
17835
17836     private final boolean removeDyingProviderLocked(ProcessRecord proc,
17837             ContentProviderRecord cpr, boolean always) {
17838         final boolean inLaunching = mLaunchingProviders.contains(cpr);
17839
17840         if (!inLaunching || always) {
17841             synchronized (cpr) {
17842                 cpr.launchingApp = null;
17843                 cpr.notifyAll();
17844             }
17845             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17846             String names[] = cpr.info.authority.split(";");
17847             for (int j = 0; j < names.length; j++) {
17848                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17849             }
17850         }
17851
17852         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17853             ContentProviderConnection conn = cpr.connections.get(i);
17854             if (conn.waiting) {
17855                 // If this connection is waiting for the provider, then we don't
17856                 // need to mess with its process unless we are always removing
17857                 // or for some reason the provider is not currently launching.
17858                 if (inLaunching && !always) {
17859                     continue;
17860                 }
17861             }
17862             ProcessRecord capp = conn.client;
17863             conn.dead = true;
17864             if (conn.stableCount > 0) {
17865                 if (!capp.persistent && capp.thread != null
17866                         && capp.pid != 0
17867                         && capp.pid != MY_PID) {
17868                     capp.kill("depends on provider "
17869                             + cpr.name.flattenToShortString()
17870                             + " in dying proc " + (proc != null ? proc.processName : "??")
17871                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17872                 }
17873             } else if (capp.thread != null && conn.provider.provider != null) {
17874                 try {
17875                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17876                 } catch (RemoteException e) {
17877                 }
17878                 // In the protocol here, we don't expect the client to correctly
17879                 // clean up this connection, we'll just remove it.
17880                 cpr.connections.remove(i);
17881                 if (conn.client.conProviders.remove(conn)) {
17882                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17883                 }
17884             }
17885         }
17886
17887         if (inLaunching && always) {
17888             mLaunchingProviders.remove(cpr);
17889         }
17890         return inLaunching;
17891     }
17892
17893     /**
17894      * Main code for cleaning up a process when it has gone away.  This is
17895      * called both as a result of the process dying, or directly when stopping
17896      * a process when running in single process mode.
17897      *
17898      * @return Returns true if the given process has been restarted, so the
17899      * app that was passed in must remain on the process lists.
17900      */
17901     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17902             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17903         if (index >= 0) {
17904             removeLruProcessLocked(app);
17905             ProcessList.remove(app.pid);
17906         }
17907
17908         mProcessesToGc.remove(app);
17909         mPendingPssProcesses.remove(app);
17910
17911         // Dismiss any open dialogs.
17912         if (app.crashDialog != null && !app.forceCrashReport) {
17913             app.crashDialog.dismiss();
17914             app.crashDialog = null;
17915         }
17916         if (app.anrDialog != null) {
17917             app.anrDialog.dismiss();
17918             app.anrDialog = null;
17919         }
17920         if (app.waitDialog != null) {
17921             app.waitDialog.dismiss();
17922             app.waitDialog = null;
17923         }
17924
17925         app.crashing = false;
17926         app.notResponding = false;
17927
17928         app.resetPackageList(mProcessStats);
17929         app.unlinkDeathRecipient();
17930         app.makeInactive(mProcessStats);
17931         app.waitingToKill = null;
17932         app.forcingToImportant = null;
17933         updateProcessForegroundLocked(app, false, false);
17934         app.foregroundActivities = false;
17935         app.hasShownUi = false;
17936         app.treatLikeActivity = false;
17937         app.hasAboveClient = false;
17938         app.hasClientActivities = false;
17939
17940         mServices.killServicesLocked(app, allowRestart);
17941
17942         boolean restart = false;
17943
17944         // Remove published content providers.
17945         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17946             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17947             final boolean always = app.bad || !allowRestart;
17948             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17949             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17950                 // We left the provider in the launching list, need to
17951                 // restart it.
17952                 restart = true;
17953             }
17954
17955             cpr.provider = null;
17956             cpr.proc = null;
17957         }
17958         app.pubProviders.clear();
17959
17960         // Take care of any launching providers waiting for this process.
17961         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17962             restart = true;
17963         }
17964
17965         // Unregister from connected content providers.
17966         if (!app.conProviders.isEmpty()) {
17967             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17968                 ContentProviderConnection conn = app.conProviders.get(i);
17969                 conn.provider.connections.remove(conn);
17970                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17971                         conn.provider.name);
17972             }
17973             app.conProviders.clear();
17974         }
17975
17976         // At this point there may be remaining entries in mLaunchingProviders
17977         // where we were the only one waiting, so they are no longer of use.
17978         // Look for these and clean up if found.
17979         // XXX Commented out for now.  Trying to figure out a way to reproduce
17980         // the actual situation to identify what is actually going on.
17981         if (false) {
17982             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17983                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17984                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17985                     synchronized (cpr) {
17986                         cpr.launchingApp = null;
17987                         cpr.notifyAll();
17988                     }
17989                 }
17990             }
17991         }
17992
17993         skipCurrentReceiverLocked(app);
17994
17995         // Unregister any receivers.
17996         for (int i = app.receivers.size() - 1; i >= 0; i--) {
17997             removeReceiverLocked(app.receivers.valueAt(i));
17998         }
17999         app.receivers.clear();
18000
18001         // If the app is undergoing backup, tell the backup manager about it
18002         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18003             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18004                     + mBackupTarget.appInfo + " died during backup");
18005             mHandler.post(new Runnable() {
18006                 @Override
18007                 public void run(){
18008                     try {
18009                         IBackupManager bm = IBackupManager.Stub.asInterface(
18010                                 ServiceManager.getService(Context.BACKUP_SERVICE));
18011                         bm.agentDisconnected(app.info.packageName);
18012                     } catch (RemoteException e) {
18013                         // can't happen; backup manager is local
18014                     }
18015                 }
18016             });
18017         }
18018
18019         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18020             ProcessChangeItem item = mPendingProcessChanges.get(i);
18021             if (item.pid == app.pid) {
18022                 mPendingProcessChanges.remove(i);
18023                 mAvailProcessChanges.add(item);
18024             }
18025         }
18026         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18027                 null).sendToTarget();
18028
18029         // If the caller is restarting this app, then leave it in its
18030         // current lists and let the caller take care of it.
18031         if (restarting) {
18032             return false;
18033         }
18034
18035         if (!app.persistent || app.isolated) {
18036             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18037                     "Removing non-persistent process during cleanup: " + app);
18038             if (!replacingPid) {
18039                 removeProcessNameLocked(app.processName, app.uid, app);
18040             }
18041             if (mHeavyWeightProcess == app) {
18042                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18043                         mHeavyWeightProcess.userId, 0));
18044                 mHeavyWeightProcess = null;
18045             }
18046         } else if (!app.removed) {
18047             // This app is persistent, so we need to keep its record around.
18048             // If it is not already on the pending app list, add it there
18049             // and start a new process for it.
18050             if (mPersistentStartingProcesses.indexOf(app) < 0) {
18051                 mPersistentStartingProcesses.add(app);
18052                 restart = true;
18053             }
18054         }
18055         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18056                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18057         mProcessesOnHold.remove(app);
18058
18059         if (app == mHomeProcess) {
18060             mHomeProcess = null;
18061         }
18062         if (app == mPreviousProcess) {
18063             mPreviousProcess = null;
18064         }
18065
18066         if (restart && !app.isolated) {
18067             // We have components that still need to be running in the
18068             // process, so re-launch it.
18069             if (index < 0) {
18070                 ProcessList.remove(app.pid);
18071             }
18072             addProcessNameLocked(app);
18073             startProcessLocked(app, "restart", app.processName);
18074             return true;
18075         } else if (app.pid > 0 && app.pid != MY_PID) {
18076             // Goodbye!
18077             boolean removed;
18078             synchronized (mPidsSelfLocked) {
18079                 mPidsSelfLocked.remove(app.pid);
18080                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18081             }
18082             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18083             if (app.isolated) {
18084                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18085             }
18086             app.setPid(0);
18087         }
18088         return false;
18089     }
18090
18091     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18092         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18093             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18094             if (cpr.launchingApp == app) {
18095                 return true;
18096             }
18097         }
18098         return false;
18099     }
18100
18101     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18102         // Look through the content providers we are waiting to have launched,
18103         // and if any run in this process then either schedule a restart of
18104         // the process or kill the client waiting for it if this process has
18105         // gone bad.
18106         boolean restart = false;
18107         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18108             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18109             if (cpr.launchingApp == app) {
18110                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18111                     restart = true;
18112                 } else {
18113                     removeDyingProviderLocked(app, cpr, true);
18114                 }
18115             }
18116         }
18117         return restart;
18118     }
18119
18120     // =========================================================
18121     // SERVICES
18122     // =========================================================
18123
18124     @Override
18125     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18126             int flags) {
18127         enforceNotIsolatedCaller("getServices");
18128
18129         final int callingUid = Binder.getCallingUid();
18130         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18131             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18132         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18133             callingUid);
18134         synchronized (this) {
18135             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18136                 allowed, canInteractAcrossUsers);
18137         }
18138     }
18139
18140     @Override
18141     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18142         enforceNotIsolatedCaller("getRunningServiceControlPanel");
18143         synchronized (this) {
18144             return mServices.getRunningServiceControlPanelLocked(name);
18145         }
18146     }
18147
18148     @Override
18149     public ComponentName startService(IApplicationThread caller, Intent service,
18150             String resolvedType, boolean requireForeground, String callingPackage, int userId)
18151             throws TransactionTooLargeException {
18152         enforceNotIsolatedCaller("startService");
18153         // Refuse possible leaked file descriptors
18154         if (service != null && service.hasFileDescriptors() == true) {
18155             throw new IllegalArgumentException("File descriptors passed in Intent");
18156         }
18157
18158         if (callingPackage == null) {
18159             throw new IllegalArgumentException("callingPackage cannot be null");
18160         }
18161
18162         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18163                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18164         synchronized(this) {
18165             final int callingPid = Binder.getCallingPid();
18166             final int callingUid = Binder.getCallingUid();
18167             final long origId = Binder.clearCallingIdentity();
18168             ComponentName res;
18169             try {
18170                 res = mServices.startServiceLocked(caller, service,
18171                         resolvedType, callingPid, callingUid,
18172                         requireForeground, callingPackage, userId);
18173             } finally {
18174                 Binder.restoreCallingIdentity(origId);
18175             }
18176             return res;
18177         }
18178     }
18179
18180     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18181             boolean fgRequired, String callingPackage, int userId)
18182             throws TransactionTooLargeException {
18183         synchronized(this) {
18184             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18185                     "startServiceInPackage: " + service + " type=" + resolvedType);
18186             final long origId = Binder.clearCallingIdentity();
18187             ComponentName res;
18188             try {
18189                 res = mServices.startServiceLocked(null, service,
18190                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
18191             } finally {
18192                 Binder.restoreCallingIdentity(origId);
18193             }
18194             return res;
18195         }
18196     }
18197
18198     @Override
18199     public int stopService(IApplicationThread caller, Intent service,
18200             String resolvedType, int userId) {
18201         enforceNotIsolatedCaller("stopService");
18202         // Refuse possible leaked file descriptors
18203         if (service != null && service.hasFileDescriptors() == true) {
18204             throw new IllegalArgumentException("File descriptors passed in Intent");
18205         }
18206
18207         synchronized(this) {
18208             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18209         }
18210     }
18211
18212     @Override
18213     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18214         enforceNotIsolatedCaller("peekService");
18215         // Refuse possible leaked file descriptors
18216         if (service != null && service.hasFileDescriptors() == true) {
18217             throw new IllegalArgumentException("File descriptors passed in Intent");
18218         }
18219
18220         if (callingPackage == null) {
18221             throw new IllegalArgumentException("callingPackage cannot be null");
18222         }
18223
18224         synchronized(this) {
18225             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18226         }
18227     }
18228
18229     @Override
18230     public boolean stopServiceToken(ComponentName className, IBinder token,
18231             int startId) {
18232         synchronized(this) {
18233             return mServices.stopServiceTokenLocked(className, token, startId);
18234         }
18235     }
18236
18237     @Override
18238     public void setServiceForeground(ComponentName className, IBinder token,
18239             int id, Notification notification, int flags) {
18240         synchronized(this) {
18241             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18242         }
18243     }
18244
18245     @Override
18246     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18247             boolean requireFull, String name, String callerPackage) {
18248         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18249                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18250     }
18251
18252     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18253             String className, int flags) {
18254         boolean result = false;
18255         // For apps that don't have pre-defined UIDs, check for permission
18256         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18257             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18258                 if (ActivityManager.checkUidPermission(
18259                         INTERACT_ACROSS_USERS,
18260                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18261                     ComponentName comp = new ComponentName(aInfo.packageName, className);
18262                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
18263                             + " requests FLAG_SINGLE_USER, but app does not hold "
18264                             + INTERACT_ACROSS_USERS;
18265                     Slog.w(TAG, msg);
18266                     throw new SecurityException(msg);
18267                 }
18268                 // Permission passed
18269                 result = true;
18270             }
18271         } else if ("system".equals(componentProcessName)) {
18272             result = true;
18273         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18274             // Phone app and persistent apps are allowed to export singleuser providers.
18275             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18276                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18277         }
18278         if (DEBUG_MU) Slog.v(TAG_MU,
18279                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18280                 + Integer.toHexString(flags) + ") = " + result);
18281         return result;
18282     }
18283
18284     /**
18285      * Checks to see if the caller is in the same app as the singleton
18286      * component, or the component is in a special app. It allows special apps
18287      * to export singleton components but prevents exporting singleton
18288      * components for regular apps.
18289      */
18290     boolean isValidSingletonCall(int callingUid, int componentUid) {
18291         int componentAppId = UserHandle.getAppId(componentUid);
18292         return UserHandle.isSameApp(callingUid, componentUid)
18293                 || componentAppId == SYSTEM_UID
18294                 || componentAppId == PHONE_UID
18295                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18296                         == PackageManager.PERMISSION_GRANTED;
18297     }
18298
18299     public int bindService(IApplicationThread caller, IBinder token, Intent service,
18300             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18301             int userId) throws TransactionTooLargeException {
18302         enforceNotIsolatedCaller("bindService");
18303
18304         // Refuse possible leaked file descriptors
18305         if (service != null && service.hasFileDescriptors() == true) {
18306             throw new IllegalArgumentException("File descriptors passed in Intent");
18307         }
18308
18309         if (callingPackage == null) {
18310             throw new IllegalArgumentException("callingPackage cannot be null");
18311         }
18312
18313         synchronized(this) {
18314             return mServices.bindServiceLocked(caller, token, service,
18315                     resolvedType, connection, flags, callingPackage, userId);
18316         }
18317     }
18318
18319     public boolean unbindService(IServiceConnection connection) {
18320         synchronized (this) {
18321             return mServices.unbindServiceLocked(connection);
18322         }
18323     }
18324
18325     public void publishService(IBinder token, Intent intent, IBinder service) {
18326         // Refuse possible leaked file descriptors
18327         if (intent != null && intent.hasFileDescriptors() == true) {
18328             throw new IllegalArgumentException("File descriptors passed in Intent");
18329         }
18330
18331         synchronized(this) {
18332             if (!(token instanceof ServiceRecord)) {
18333                 throw new IllegalArgumentException("Invalid service token");
18334             }
18335             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18336         }
18337     }
18338
18339     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18340         // Refuse possible leaked file descriptors
18341         if (intent != null && intent.hasFileDescriptors() == true) {
18342             throw new IllegalArgumentException("File descriptors passed in Intent");
18343         }
18344
18345         synchronized(this) {
18346             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18347         }
18348     }
18349
18350     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18351         synchronized(this) {
18352             if (!(token instanceof ServiceRecord)) {
18353                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18354                 throw new IllegalArgumentException("Invalid service token");
18355             }
18356             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18357         }
18358     }
18359
18360     // =========================================================
18361     // BACKUP AND RESTORE
18362     // =========================================================
18363
18364     // Cause the target app to be launched if necessary and its backup agent
18365     // instantiated.  The backup agent will invoke backupAgentCreated() on the
18366     // activity manager to announce its creation.
18367     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18368         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18369         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18370
18371         IPackageManager pm = AppGlobals.getPackageManager();
18372         ApplicationInfo app = null;
18373         try {
18374             app = pm.getApplicationInfo(packageName, 0, userId);
18375         } catch (RemoteException e) {
18376             // can't happen; package manager is process-local
18377         }
18378         if (app == null) {
18379             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18380             return false;
18381         }
18382
18383         int oldBackupUid;
18384         int newBackupUid;
18385
18386         synchronized(this) {
18387             // !!! TODO: currently no check here that we're already bound
18388             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18389             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18390             synchronized (stats) {
18391                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18392             }
18393
18394             // Backup agent is now in use, its package can't be stopped.
18395             try {
18396                 AppGlobals.getPackageManager().setPackageStoppedState(
18397                         app.packageName, false, UserHandle.getUserId(app.uid));
18398             } catch (RemoteException e) {
18399             } catch (IllegalArgumentException e) {
18400                 Slog.w(TAG, "Failed trying to unstop package "
18401                         + app.packageName + ": " + e);
18402             }
18403
18404             BackupRecord r = new BackupRecord(ss, app, backupMode);
18405             ComponentName hostingName =
18406                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18407                             ? new ComponentName(app.packageName, app.backupAgentName)
18408                             : new ComponentName("android", "FullBackupAgent");
18409             // startProcessLocked() returns existing proc's record if it's already running
18410             ProcessRecord proc = startProcessLocked(app.processName, app,
18411                     false, 0, "backup", hostingName, false, false, false);
18412             if (proc == null) {
18413                 Slog.e(TAG, "Unable to start backup agent process " + r);
18414                 return false;
18415             }
18416
18417             // If the app is a regular app (uid >= 10000) and not the system server or phone
18418             // process, etc, then mark it as being in full backup so that certain calls to the
18419             // process can be blocked. This is not reset to false anywhere because we kill the
18420             // process after the full backup is done and the ProcessRecord will vaporize anyway.
18421             if (UserHandle.isApp(app.uid) &&
18422                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18423                 proc.inFullBackup = true;
18424             }
18425             r.app = proc;
18426             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18427             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18428             mBackupTarget = r;
18429             mBackupAppName = app.packageName;
18430
18431             // Try not to kill the process during backup
18432             updateOomAdjLocked(proc, true);
18433
18434             // If the process is already attached, schedule the creation of the backup agent now.
18435             // If it is not yet live, this will be done when it attaches to the framework.
18436             if (proc.thread != null) {
18437                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18438                 try {
18439                     proc.thread.scheduleCreateBackupAgent(app,
18440                             compatibilityInfoForPackageLocked(app), backupMode);
18441                 } catch (RemoteException e) {
18442                     // Will time out on the backup manager side
18443                 }
18444             } else {
18445                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18446             }
18447             // Invariants: at this point, the target app process exists and the application
18448             // is either already running or in the process of coming up.  mBackupTarget and
18449             // mBackupAppName describe the app, so that when it binds back to the AM we
18450             // know that it's scheduled for a backup-agent operation.
18451         }
18452
18453         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18454         if (oldBackupUid != -1) {
18455             js.removeBackingUpUid(oldBackupUid);
18456         }
18457         if (newBackupUid != -1) {
18458             js.addBackingUpUid(newBackupUid);
18459         }
18460
18461         return true;
18462     }
18463
18464     @Override
18465     public void clearPendingBackup() {
18466         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18467         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18468
18469         synchronized (this) {
18470             mBackupTarget = null;
18471             mBackupAppName = null;
18472         }
18473
18474         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18475         js.clearAllBackingUpUids();
18476     }
18477
18478     // A backup agent has just come up
18479     public void backupAgentCreated(String agentPackageName, IBinder agent) {
18480         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18481                 + " = " + agent);
18482
18483         synchronized(this) {
18484             if (!agentPackageName.equals(mBackupAppName)) {
18485                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18486                 return;
18487             }
18488         }
18489
18490         long oldIdent = Binder.clearCallingIdentity();
18491         try {
18492             IBackupManager bm = IBackupManager.Stub.asInterface(
18493                     ServiceManager.getService(Context.BACKUP_SERVICE));
18494             bm.agentConnected(agentPackageName, agent);
18495         } catch (RemoteException e) {
18496             // can't happen; the backup manager service is local
18497         } catch (Exception e) {
18498             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18499             e.printStackTrace();
18500         } finally {
18501             Binder.restoreCallingIdentity(oldIdent);
18502         }
18503     }
18504
18505     // done with this agent
18506     public void unbindBackupAgent(ApplicationInfo appInfo) {
18507         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18508         if (appInfo == null) {
18509             Slog.w(TAG, "unbind backup agent for null app");
18510             return;
18511         }
18512
18513         int oldBackupUid;
18514
18515         synchronized(this) {
18516             try {
18517                 if (mBackupAppName == null) {
18518                     Slog.w(TAG, "Unbinding backup agent with no active backup");
18519                     return;
18520                 }
18521
18522                 if (!mBackupAppName.equals(appInfo.packageName)) {
18523                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18524                     return;
18525                 }
18526
18527                 // Not backing this app up any more; reset its OOM adjustment
18528                 final ProcessRecord proc = mBackupTarget.app;
18529                 updateOomAdjLocked(proc, true);
18530                 proc.inFullBackup = false;
18531
18532                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18533
18534                 // If the app crashed during backup, 'thread' will be null here
18535                 if (proc.thread != null) {
18536                     try {
18537                         proc.thread.scheduleDestroyBackupAgent(appInfo,
18538                                 compatibilityInfoForPackageLocked(appInfo));
18539                     } catch (Exception e) {
18540                         Slog.e(TAG, "Exception when unbinding backup agent:");
18541                         e.printStackTrace();
18542                     }
18543                 }
18544             } finally {
18545                 mBackupTarget = null;
18546                 mBackupAppName = null;
18547             }
18548         }
18549
18550         if (oldBackupUid != -1) {
18551             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18552             js.removeBackingUpUid(oldBackupUid);
18553         }
18554     }
18555
18556     // =========================================================
18557     // BROADCASTS
18558     // =========================================================
18559
18560     private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18561         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18562             return false;
18563         }
18564         // Easy case -- we have the app's ProcessRecord.
18565         if (record != null) {
18566             return record.info.isInstantApp();
18567         }
18568         // Otherwise check with PackageManager.
18569         if (callerPackage == null) {
18570             Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18571             throw new IllegalArgumentException("Calling application did not provide package name");
18572         }
18573         mAppOpsService.checkPackage(uid, callerPackage);
18574         try {
18575             IPackageManager pm = AppGlobals.getPackageManager();
18576             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18577         } catch (RemoteException e) {
18578             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18579             return true;
18580         }
18581     }
18582
18583     boolean isPendingBroadcastProcessLocked(int pid) {
18584         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18585                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18586     }
18587
18588     void skipPendingBroadcastLocked(int pid) {
18589             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18590             for (BroadcastQueue queue : mBroadcastQueues) {
18591                 queue.skipPendingBroadcastLocked(pid);
18592             }
18593     }
18594
18595     // The app just attached; send any pending broadcasts that it should receive
18596     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18597         boolean didSomething = false;
18598         for (BroadcastQueue queue : mBroadcastQueues) {
18599             didSomething |= queue.sendPendingBroadcastsLocked(app);
18600         }
18601         return didSomething;
18602     }
18603
18604     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18605             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18606             int flags) {
18607         enforceNotIsolatedCaller("registerReceiver");
18608         ArrayList<Intent> stickyIntents = null;
18609         ProcessRecord callerApp = null;
18610         final boolean visibleToInstantApps
18611                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18612         int callingUid;
18613         int callingPid;
18614         boolean instantApp;
18615         synchronized(this) {
18616             if (caller != null) {
18617                 callerApp = getRecordForAppLocked(caller);
18618                 if (callerApp == null) {
18619                     throw new SecurityException(
18620                             "Unable to find app for caller " + caller
18621                             + " (pid=" + Binder.getCallingPid()
18622                             + ") when registering receiver " + receiver);
18623                 }
18624                 if (callerApp.info.uid != SYSTEM_UID &&
18625                         !callerApp.pkgList.containsKey(callerPackage) &&
18626                         !"android".equals(callerPackage)) {
18627                     throw new SecurityException("Given caller package " + callerPackage
18628                             + " is not running in process " + callerApp);
18629                 }
18630                 callingUid = callerApp.info.uid;
18631                 callingPid = callerApp.pid;
18632             } else {
18633                 callerPackage = null;
18634                 callingUid = Binder.getCallingUid();
18635                 callingPid = Binder.getCallingPid();
18636             }
18637
18638             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18639             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18640                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18641
18642             Iterator<String> actions = filter.actionsIterator();
18643             if (actions == null) {
18644                 ArrayList<String> noAction = new ArrayList<String>(1);
18645                 noAction.add(null);
18646                 actions = noAction.iterator();
18647             }
18648
18649             // Collect stickies of users
18650             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18651             while (actions.hasNext()) {
18652                 String action = actions.next();
18653                 for (int id : userIds) {
18654                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18655                     if (stickies != null) {
18656                         ArrayList<Intent> intents = stickies.get(action);
18657                         if (intents != null) {
18658                             if (stickyIntents == null) {
18659                                 stickyIntents = new ArrayList<Intent>();
18660                             }
18661                             stickyIntents.addAll(intents);
18662                         }
18663                     }
18664                 }
18665             }
18666         }
18667
18668         ArrayList<Intent> allSticky = null;
18669         if (stickyIntents != null) {
18670             final ContentResolver resolver = mContext.getContentResolver();
18671             // Look for any matching sticky broadcasts...
18672             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18673                 Intent intent = stickyIntents.get(i);
18674                 // Don't provided intents that aren't available to instant apps.
18675                 if (instantApp &&
18676                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18677                     continue;
18678                 }
18679                 // If intent has scheme "content", it will need to acccess
18680                 // provider that needs to lock mProviderMap in ActivityThread
18681                 // and also it may need to wait application response, so we
18682                 // cannot lock ActivityManagerService here.
18683                 if (filter.match(resolver, intent, true, TAG) >= 0) {
18684                     if (allSticky == null) {
18685                         allSticky = new ArrayList<Intent>();
18686                     }
18687                     allSticky.add(intent);
18688                 }
18689             }
18690         }
18691
18692         // The first sticky in the list is returned directly back to the client.
18693         Intent sticky = allSticky != null ? allSticky.get(0) : null;
18694         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18695         if (receiver == null) {
18696             return sticky;
18697         }
18698
18699         synchronized (this) {
18700             if (callerApp != null && (callerApp.thread == null
18701                     || callerApp.thread.asBinder() != caller.asBinder())) {
18702                 // Original caller already died
18703                 return null;
18704             }
18705             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18706             if (rl == null) {
18707                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18708                         userId, receiver);
18709                 if (rl.app != null) {
18710                     rl.app.receivers.add(rl);
18711                 } else {
18712                     try {
18713                         receiver.asBinder().linkToDeath(rl, 0);
18714                     } catch (RemoteException e) {
18715                         return sticky;
18716                     }
18717                     rl.linkedToDeath = true;
18718                 }
18719                 mRegisteredReceivers.put(receiver.asBinder(), rl);
18720             } else if (rl.uid != callingUid) {
18721                 throw new IllegalArgumentException(
18722                         "Receiver requested to register for uid " + callingUid
18723                         + " was previously registered for uid " + rl.uid
18724                         + " callerPackage is " + callerPackage);
18725             } else if (rl.pid != callingPid) {
18726                 throw new IllegalArgumentException(
18727                         "Receiver requested to register for pid " + callingPid
18728                         + " was previously registered for pid " + rl.pid
18729                         + " callerPackage is " + callerPackage);
18730             } else if (rl.userId != userId) {
18731                 throw new IllegalArgumentException(
18732                         "Receiver requested to register for user " + userId
18733                         + " was previously registered for user " + rl.userId
18734                         + " callerPackage is " + callerPackage);
18735             }
18736             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18737                     permission, callingUid, userId, instantApp, visibleToInstantApps);
18738             rl.add(bf);
18739             if (!bf.debugCheck()) {
18740                 Slog.w(TAG, "==> For Dynamic broadcast");
18741             }
18742             mReceiverResolver.addFilter(bf);
18743
18744             // Enqueue broadcasts for all existing stickies that match
18745             // this filter.
18746             if (allSticky != null) {
18747                 ArrayList receivers = new ArrayList();
18748                 receivers.add(bf);
18749
18750                 final int stickyCount = allSticky.size();
18751                 for (int i = 0; i < stickyCount; i++) {
18752                     Intent intent = allSticky.get(i);
18753                     BroadcastQueue queue = broadcastQueueForIntent(intent);
18754                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18755                             null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18756                             null, 0, null, null, false, true, true, -1);
18757                     queue.enqueueParallelBroadcastLocked(r);
18758                     queue.scheduleBroadcastsLocked();
18759                 }
18760             }
18761
18762             return sticky;
18763         }
18764     }
18765
18766     public void unregisterReceiver(IIntentReceiver receiver) {
18767         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18768
18769         final long origId = Binder.clearCallingIdentity();
18770         try {
18771             boolean doTrim = false;
18772
18773             synchronized(this) {
18774                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18775                 if (rl != null) {
18776                     final BroadcastRecord r = rl.curBroadcast;
18777                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18778                         final boolean doNext = r.queue.finishReceiverLocked(
18779                                 r, r.resultCode, r.resultData, r.resultExtras,
18780                                 r.resultAbort, false);
18781                         if (doNext) {
18782                             doTrim = true;
18783                             r.queue.processNextBroadcast(false);
18784                         }
18785                     }
18786
18787                     if (rl.app != null) {
18788                         rl.app.receivers.remove(rl);
18789                     }
18790                     removeReceiverLocked(rl);
18791                     if (rl.linkedToDeath) {
18792                         rl.linkedToDeath = false;
18793                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
18794                     }
18795                 }
18796             }
18797
18798             // If we actually concluded any broadcasts, we might now be able
18799             // to trim the recipients' apps from our working set
18800             if (doTrim) {
18801                 trimApplications();
18802                 return;
18803             }
18804
18805         } finally {
18806             Binder.restoreCallingIdentity(origId);
18807         }
18808     }
18809
18810     void removeReceiverLocked(ReceiverList rl) {
18811         mRegisteredReceivers.remove(rl.receiver.asBinder());
18812         for (int i = rl.size() - 1; i >= 0; i--) {
18813             mReceiverResolver.removeFilter(rl.get(i));
18814         }
18815     }
18816
18817     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18818         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18819             ProcessRecord r = mLruProcesses.get(i);
18820             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18821                 try {
18822                     r.thread.dispatchPackageBroadcast(cmd, packages);
18823                 } catch (RemoteException ex) {
18824                 }
18825             }
18826         }
18827     }
18828
18829     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18830             int callingUid, int[] users) {
18831         // TODO: come back and remove this assumption to triage all broadcasts
18832         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18833
18834         List<ResolveInfo> receivers = null;
18835         try {
18836             HashSet<ComponentName> singleUserReceivers = null;
18837             boolean scannedFirstReceivers = false;
18838             for (int user : users) {
18839                 // Skip users that have Shell restrictions, with exception of always permitted
18840                 // Shell broadcasts
18841                 if (callingUid == SHELL_UID
18842                         && mUserController.hasUserRestriction(
18843                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18844                         && !isPermittedShellBroadcast(intent)) {
18845                     continue;
18846                 }
18847                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18848                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18849                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18850                     // If this is not the system user, we need to check for
18851                     // any receivers that should be filtered out.
18852                     for (int i=0; i<newReceivers.size(); i++) {
18853                         ResolveInfo ri = newReceivers.get(i);
18854                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18855                             newReceivers.remove(i);
18856                             i--;
18857                         }
18858                     }
18859                 }
18860                 if (newReceivers != null && newReceivers.size() == 0) {
18861                     newReceivers = null;
18862                 }
18863                 if (receivers == null) {
18864                     receivers = newReceivers;
18865                 } else if (newReceivers != null) {
18866                     // We need to concatenate the additional receivers
18867                     // found with what we have do far.  This would be easy,
18868                     // but we also need to de-dup any receivers that are
18869                     // singleUser.
18870                     if (!scannedFirstReceivers) {
18871                         // Collect any single user receivers we had already retrieved.
18872                         scannedFirstReceivers = true;
18873                         for (int i=0; i<receivers.size(); i++) {
18874                             ResolveInfo ri = receivers.get(i);
18875                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18876                                 ComponentName cn = new ComponentName(
18877                                         ri.activityInfo.packageName, ri.activityInfo.name);
18878                                 if (singleUserReceivers == null) {
18879                                     singleUserReceivers = new HashSet<ComponentName>();
18880                                 }
18881                                 singleUserReceivers.add(cn);
18882                             }
18883                         }
18884                     }
18885                     // Add the new results to the existing results, tracking
18886                     // and de-dupping single user receivers.
18887                     for (int i=0; i<newReceivers.size(); i++) {
18888                         ResolveInfo ri = newReceivers.get(i);
18889                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18890                             ComponentName cn = new ComponentName(
18891                                     ri.activityInfo.packageName, ri.activityInfo.name);
18892                             if (singleUserReceivers == null) {
18893                                 singleUserReceivers = new HashSet<ComponentName>();
18894                             }
18895                             if (!singleUserReceivers.contains(cn)) {
18896                                 singleUserReceivers.add(cn);
18897                                 receivers.add(ri);
18898                             }
18899                         } else {
18900                             receivers.add(ri);
18901                         }
18902                     }
18903                 }
18904             }
18905         } catch (RemoteException ex) {
18906             // pm is in same process, this will never happen.
18907         }
18908         return receivers;
18909     }
18910
18911     private boolean isPermittedShellBroadcast(Intent intent) {
18912         // remote bugreport should always be allowed to be taken
18913         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18914     }
18915
18916     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18917             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18918         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18919             // Don't yell about broadcasts sent via shell
18920             return;
18921         }
18922
18923         final String action = intent.getAction();
18924         if (isProtectedBroadcast
18925                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18926                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18927                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
18928                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18929                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18930                 || Intent.ACTION_MASTER_CLEAR.equals(action)
18931                 || Intent.ACTION_FACTORY_RESET.equals(action)
18932                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18933                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18934                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18935                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18936                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18937                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18938                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18939             // Broadcast is either protected, or it's a public action that
18940             // we've relaxed, so it's fine for system internals to send.
18941             return;
18942         }
18943
18944         // This broadcast may be a problem...  but there are often system components that
18945         // want to send an internal broadcast to themselves, which is annoying to have to
18946         // explicitly list each action as a protected broadcast, so we will check for that
18947         // one safe case and allow it: an explicit broadcast, only being received by something
18948         // that has protected itself.
18949         if (receivers != null && receivers.size() > 0
18950                 && (intent.getPackage() != null || intent.getComponent() != null)) {
18951             boolean allProtected = true;
18952             for (int i = receivers.size()-1; i >= 0; i--) {
18953                 Object target = receivers.get(i);
18954                 if (target instanceof ResolveInfo) {
18955                     ResolveInfo ri = (ResolveInfo)target;
18956                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18957                         allProtected = false;
18958                         break;
18959                     }
18960                 } else {
18961                     BroadcastFilter bf = (BroadcastFilter)target;
18962                     if (bf.requiredPermission == null) {
18963                         allProtected = false;
18964                         break;
18965                     }
18966                 }
18967             }
18968             if (allProtected) {
18969                 // All safe!
18970                 return;
18971             }
18972         }
18973
18974         // The vast majority of broadcasts sent from system internals
18975         // should be protected to avoid security holes, so yell loudly
18976         // to ensure we examine these cases.
18977         if (callerApp != null) {
18978             Log.wtf(TAG, "Sending non-protected broadcast " + action
18979                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18980                     new Throwable());
18981         } else {
18982             Log.wtf(TAG, "Sending non-protected broadcast " + action
18983                             + " from system uid " + UserHandle.formatUid(callingUid)
18984                             + " pkg " + callerPackage,
18985                     new Throwable());
18986         }
18987     }
18988
18989     final int broadcastIntentLocked(ProcessRecord callerApp,
18990             String callerPackage, Intent intent, String resolvedType,
18991             IIntentReceiver resultTo, int resultCode, String resultData,
18992             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18993             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18994         intent = new Intent(intent);
18995
18996         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
18997         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
18998         if (callerInstantApp) {
18999             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19000         }
19001
19002         // By default broadcasts do not go to stopped apps.
19003         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19004
19005         // If we have not finished booting, don't allow this to launch new processes.
19006         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19007             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19008         }
19009
19010         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19011                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19012                 + " ordered=" + ordered + " userid=" + userId);
19013         if ((resultTo != null) && !ordered) {
19014             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19015         }
19016
19017         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19018                 ALLOW_NON_FULL, "broadcast", callerPackage);
19019
19020         // Make sure that the user who is receiving this broadcast is running.
19021         // If not, we will just skip it. Make an exception for shutdown broadcasts
19022         // and upgrade steps.
19023
19024         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19025             if ((callingUid != SYSTEM_UID
19026                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19027                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19028                 Slog.w(TAG, "Skipping broadcast of " + intent
19029                         + ": user " + userId + " is stopped");
19030                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19031             }
19032         }
19033
19034         BroadcastOptions brOptions = null;
19035         if (bOptions != null) {
19036             brOptions = new BroadcastOptions(bOptions);
19037             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19038                 // See if the caller is allowed to do this.  Note we are checking against
19039                 // the actual real caller (not whoever provided the operation as say a
19040                 // PendingIntent), because that who is actually supplied the arguments.
19041                 if (checkComponentPermission(
19042                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19043                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19044                         != PackageManager.PERMISSION_GRANTED) {
19045                     String msg = "Permission Denial: " + intent.getAction()
19046                             + " broadcast from " + callerPackage + " (pid=" + callingPid
19047                             + ", uid=" + callingUid + ")"
19048                             + " requires "
19049                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19050                     Slog.w(TAG, msg);
19051                     throw new SecurityException(msg);
19052                 }
19053             }
19054         }
19055
19056         // Verify that protected broadcasts are only being sent by system code,
19057         // and that system code is only sending protected broadcasts.
19058         final String action = intent.getAction();
19059         final boolean isProtectedBroadcast;
19060         try {
19061             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19062         } catch (RemoteException e) {
19063             Slog.w(TAG, "Remote exception", e);
19064             return ActivityManager.BROADCAST_SUCCESS;
19065         }
19066
19067         final boolean isCallerSystem;
19068         switch (UserHandle.getAppId(callingUid)) {
19069             case ROOT_UID:
19070             case SYSTEM_UID:
19071             case PHONE_UID:
19072             case BLUETOOTH_UID:
19073             case NFC_UID:
19074                 isCallerSystem = true;
19075                 break;
19076             default:
19077                 isCallerSystem = (callerApp != null) && callerApp.persistent;
19078                 break;
19079         }
19080
19081         // First line security check before anything else: stop non-system apps from
19082         // sending protected broadcasts.
19083         if (!isCallerSystem) {
19084             if (isProtectedBroadcast) {
19085                 String msg = "Permission Denial: not allowed to send broadcast "
19086                         + action + " from pid="
19087                         + callingPid + ", uid=" + callingUid;
19088                 Slog.w(TAG, msg);
19089                 throw new SecurityException(msg);
19090
19091             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19092                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19093                 // Special case for compatibility: we don't want apps to send this,
19094                 // but historically it has not been protected and apps may be using it
19095                 // to poke their own app widget.  So, instead of making it protected,
19096                 // just limit it to the caller.
19097                 if (callerPackage == null) {
19098                     String msg = "Permission Denial: not allowed to send broadcast "
19099                             + action + " from unknown caller.";
19100                     Slog.w(TAG, msg);
19101                     throw new SecurityException(msg);
19102                 } else if (intent.getComponent() != null) {
19103                     // They are good enough to send to an explicit component...  verify
19104                     // it is being sent to the calling app.
19105                     if (!intent.getComponent().getPackageName().equals(
19106                             callerPackage)) {
19107                         String msg = "Permission Denial: not allowed to send broadcast "
19108                                 + action + " to "
19109                                 + intent.getComponent().getPackageName() + " from "
19110                                 + callerPackage;
19111                         Slog.w(TAG, msg);
19112                         throw new SecurityException(msg);
19113                     }
19114                 } else {
19115                     // Limit broadcast to their own package.
19116                     intent.setPackage(callerPackage);
19117                 }
19118             }
19119         }
19120
19121         if (action != null) {
19122             if (getBackgroundLaunchBroadcasts().contains(action)) {
19123                 if (DEBUG_BACKGROUND_CHECK) {
19124                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19125                 }
19126                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19127             }
19128
19129             switch (action) {
19130                 case Intent.ACTION_UID_REMOVED:
19131                 case Intent.ACTION_PACKAGE_REMOVED:
19132                 case Intent.ACTION_PACKAGE_CHANGED:
19133                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19134                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19135                 case Intent.ACTION_PACKAGES_SUSPENDED:
19136                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19137                     // Handle special intents: if this broadcast is from the package
19138                     // manager about a package being removed, we need to remove all of
19139                     // its activities from the history stack.
19140                     if (checkComponentPermission(
19141                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19142                             callingPid, callingUid, -1, true)
19143                             != PackageManager.PERMISSION_GRANTED) {
19144                         String msg = "Permission Denial: " + intent.getAction()
19145                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
19146                                 + ", uid=" + callingUid + ")"
19147                                 + " requires "
19148                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19149                         Slog.w(TAG, msg);
19150                         throw new SecurityException(msg);
19151                     }
19152                     switch (action) {
19153                         case Intent.ACTION_UID_REMOVED:
19154                             final int uid = getUidFromIntent(intent);
19155                             if (uid >= 0) {
19156                                 mBatteryStatsService.removeUid(uid);
19157                                 mAppOpsService.uidRemoved(uid);
19158                             }
19159                             break;
19160                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19161                             // If resources are unavailable just force stop all those packages
19162                             // and flush the attribute cache as well.
19163                             String list[] =
19164                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19165                             if (list != null && list.length > 0) {
19166                                 for (int i = 0; i < list.length; i++) {
19167                                     forceStopPackageLocked(list[i], -1, false, true, true,
19168                                             false, false, userId, "storage unmount");
19169                                 }
19170                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19171                                 sendPackageBroadcastLocked(
19172                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19173                                         list, userId);
19174                             }
19175                             break;
19176                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19177                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19178                             break;
19179                         case Intent.ACTION_PACKAGE_REMOVED:
19180                         case Intent.ACTION_PACKAGE_CHANGED:
19181                             Uri data = intent.getData();
19182                             String ssp;
19183                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19184                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19185                                 final boolean replacing =
19186                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19187                                 final boolean killProcess =
19188                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19189                                 final boolean fullUninstall = removed && !replacing;
19190                                 if (removed) {
19191                                     if (killProcess) {
19192                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
19193                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19194                                                 false, true, true, false, fullUninstall, userId,
19195                                                 removed ? "pkg removed" : "pkg changed");
19196                                     }
19197                                     final int cmd = killProcess
19198                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
19199                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19200                                     sendPackageBroadcastLocked(cmd,
19201                                             new String[] {ssp}, userId);
19202                                     if (fullUninstall) {
19203                                         mAppOpsService.packageRemoved(
19204                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19205
19206                                         // Remove all permissions granted from/to this package
19207                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
19208
19209                                         removeTasksByPackageNameLocked(ssp, userId);
19210
19211                                         mServices.forceStopPackageLocked(ssp, userId);
19212
19213                                         // Hide the "unsupported display" dialog if necessary.
19214                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19215                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19216                                             mUnsupportedDisplaySizeDialog.dismiss();
19217                                             mUnsupportedDisplaySizeDialog = null;
19218                                         }
19219                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
19220                                         mBatteryStatsService.notePackageUninstalled(ssp);
19221                                     }
19222                                 } else {
19223                                     if (killProcess) {
19224                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
19225                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19226                                                 userId, ProcessList.INVALID_ADJ,
19227                                                 false, true, true, false, "change " + ssp);
19228                                     }
19229                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19230                                             intent.getStringArrayExtra(
19231                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19232                                 }
19233                             }
19234                             break;
19235                         case Intent.ACTION_PACKAGES_SUSPENDED:
19236                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
19237                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19238                                     intent.getAction());
19239                             final String[] packageNames = intent.getStringArrayExtra(
19240                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
19241                             final int userHandle = intent.getIntExtra(
19242                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19243
19244                             synchronized(ActivityManagerService.this) {
19245                                 mRecentTasks.onPackagesSuspendedChanged(
19246                                         packageNames, suspended, userHandle);
19247                             }
19248                             break;
19249                     }
19250                     break;
19251                 case Intent.ACTION_PACKAGE_REPLACED:
19252                 {
19253                     final Uri data = intent.getData();
19254                     final String ssp;
19255                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19256                         ApplicationInfo aInfo = null;
19257                         try {
19258                             aInfo = AppGlobals.getPackageManager()
19259                                     .getApplicationInfo(ssp, 0 /*flags*/, userId);
19260                         } catch (RemoteException ignore) {}
19261                         if (aInfo == null) {
19262                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19263                                     + " ssp=" + ssp + " data=" + data);
19264                             return ActivityManager.BROADCAST_SUCCESS;
19265                         }
19266                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19267                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19268                                 new String[] {ssp}, userId);
19269                     }
19270                     break;
19271                 }
19272                 case Intent.ACTION_PACKAGE_ADDED:
19273                 {
19274                     // Special case for adding a package: by default turn on compatibility mode.
19275                     Uri data = intent.getData();
19276                     String ssp;
19277                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19278                         final boolean replacing =
19279                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19280                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19281
19282                         try {
19283                             ApplicationInfo ai = AppGlobals.getPackageManager().
19284                                     getApplicationInfo(ssp, 0, 0);
19285                             mBatteryStatsService.notePackageInstalled(ssp,
19286                                     ai != null ? ai.versionCode : 0);
19287                         } catch (RemoteException e) {
19288                         }
19289                     }
19290                     break;
19291                 }
19292                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19293                 {
19294                     Uri data = intent.getData();
19295                     String ssp;
19296                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19297                         // Hide the "unsupported display" dialog if necessary.
19298                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19299                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19300                             mUnsupportedDisplaySizeDialog.dismiss();
19301                             mUnsupportedDisplaySizeDialog = null;
19302                         }
19303                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
19304                     }
19305                     break;
19306                 }
19307                 case Intent.ACTION_TIMEZONE_CHANGED:
19308                     // If this is the time zone changed action, queue up a message that will reset
19309                     // the timezone of all currently running processes. This message will get
19310                     // queued up before the broadcast happens.
19311                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19312                     break;
19313                 case Intent.ACTION_TIME_CHANGED:
19314                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19315                     // the tri-state value it may contain and "unknown".
19316                     // For convenience we re-use the Intent extra values.
19317                     final int NO_EXTRA_VALUE_FOUND = -1;
19318                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19319                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19320                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
19321                     // Only send a message if the time preference is available.
19322                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19323                         Message updateTimePreferenceMsg =
19324                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19325                                         timeFormatPreferenceMsgValue, 0);
19326                         mHandler.sendMessage(updateTimePreferenceMsg);
19327                     }
19328                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19329                     synchronized (stats) {
19330                         stats.noteCurrentTimeChangedLocked();
19331                     }
19332                     break;
19333                 case Intent.ACTION_CLEAR_DNS_CACHE:
19334                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19335                     break;
19336                 case Proxy.PROXY_CHANGE_ACTION:
19337                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19338                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19339                     break;
19340                 case android.hardware.Camera.ACTION_NEW_PICTURE:
19341                 case android.hardware.Camera.ACTION_NEW_VIDEO:
19342                     // In N we just turned these off; in O we are turing them back on partly,
19343                     // only for registered receivers.  This will still address the main problem
19344                     // (a spam of apps waking up when a picture is taken putting significant
19345                     // memory pressure on the system at a bad point), while still allowing apps
19346                     // that are already actively running to know about this happening.
19347                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19348                     break;
19349                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19350                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19351                     break;
19352                 case "com.android.launcher.action.INSTALL_SHORTCUT":
19353                     // As of O, we no longer support this broadcasts, even for pre-O apps.
19354                     // Apps should now be using ShortcutManager.pinRequestShortcut().
19355                     Log.w(TAG, "Broadcast " + action
19356                             + " no longer supported. It will not be delivered.");
19357                     return ActivityManager.BROADCAST_SUCCESS;
19358             }
19359
19360             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19361                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19362                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19363                 final int uid = getUidFromIntent(intent);
19364                 if (uid != -1) {
19365                     final UidRecord uidRec = mActiveUids.get(uid);
19366                     if (uidRec != null) {
19367                         uidRec.updateHasInternetPermission();
19368                     }
19369                 }
19370             }
19371         }
19372
19373         // Add to the sticky list if requested.
19374         if (sticky) {
19375             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19376                     callingPid, callingUid)
19377                     != PackageManager.PERMISSION_GRANTED) {
19378                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19379                         + callingPid + ", uid=" + callingUid
19380                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19381                 Slog.w(TAG, msg);
19382                 throw new SecurityException(msg);
19383             }
19384             if (requiredPermissions != null && requiredPermissions.length > 0) {
19385                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19386                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
19387                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19388             }
19389             if (intent.getComponent() != null) {
19390                 throw new SecurityException(
19391                         "Sticky broadcasts can't target a specific component");
19392             }
19393             // We use userId directly here, since the "all" target is maintained
19394             // as a separate set of sticky broadcasts.
19395             if (userId != UserHandle.USER_ALL) {
19396                 // But first, if this is not a broadcast to all users, then
19397                 // make sure it doesn't conflict with an existing broadcast to
19398                 // all users.
19399                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19400                         UserHandle.USER_ALL);
19401                 if (stickies != null) {
19402                     ArrayList<Intent> list = stickies.get(intent.getAction());
19403                     if (list != null) {
19404                         int N = list.size();
19405                         int i;
19406                         for (i=0; i<N; i++) {
19407                             if (intent.filterEquals(list.get(i))) {
19408                                 throw new IllegalArgumentException(
19409                                         "Sticky broadcast " + intent + " for user "
19410                                         + userId + " conflicts with existing global broadcast");
19411                             }
19412                         }
19413                     }
19414                 }
19415             }
19416             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19417             if (stickies == null) {
19418                 stickies = new ArrayMap<>();
19419                 mStickyBroadcasts.put(userId, stickies);
19420             }
19421             ArrayList<Intent> list = stickies.get(intent.getAction());
19422             if (list == null) {
19423                 list = new ArrayList<>();
19424                 stickies.put(intent.getAction(), list);
19425             }
19426             final int stickiesCount = list.size();
19427             int i;
19428             for (i = 0; i < stickiesCount; i++) {
19429                 if (intent.filterEquals(list.get(i))) {
19430                     // This sticky already exists, replace it.
19431                     list.set(i, new Intent(intent));
19432                     break;
19433                 }
19434             }
19435             if (i >= stickiesCount) {
19436                 list.add(new Intent(intent));
19437             }
19438         }
19439
19440         int[] users;
19441         if (userId == UserHandle.USER_ALL) {
19442             // Caller wants broadcast to go to all started users.
19443             users = mUserController.getStartedUserArrayLocked();
19444         } else {
19445             // Caller wants broadcast to go to one specific user.
19446             users = new int[] {userId};
19447         }
19448
19449         // Figure out who all will receive this broadcast.
19450         List receivers = null;
19451         List<BroadcastFilter> registeredReceivers = null;
19452         // Need to resolve the intent to interested receivers...
19453         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19454                  == 0) {
19455             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19456         }
19457         if (intent.getComponent() == null) {
19458             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19459                 // Query one target user at a time, excluding shell-restricted users
19460                 for (int i = 0; i < users.length; i++) {
19461                     if (mUserController.hasUserRestriction(
19462                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19463                         continue;
19464                     }
19465                     List<BroadcastFilter> registeredReceiversForUser =
19466                             mReceiverResolver.queryIntent(intent,
19467                                     resolvedType, false /*defaultOnly*/, users[i]);
19468                     if (registeredReceivers == null) {
19469                         registeredReceivers = registeredReceiversForUser;
19470                     } else if (registeredReceiversForUser != null) {
19471                         registeredReceivers.addAll(registeredReceiversForUser);
19472                     }
19473                 }
19474             } else {
19475                 registeredReceivers = mReceiverResolver.queryIntent(intent,
19476                         resolvedType, false /*defaultOnly*/, userId);
19477             }
19478         }
19479
19480         final boolean replacePending =
19481                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19482
19483         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19484                 + " replacePending=" + replacePending);
19485
19486         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19487         if (!ordered && NR > 0) {
19488             // If we are not serializing this broadcast, then send the
19489             // registered receivers separately so they don't wait for the
19490             // components to be launched.
19491             if (isCallerSystem) {
19492                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19493                         isProtectedBroadcast, registeredReceivers);
19494             }
19495             final BroadcastQueue queue = broadcastQueueForIntent(intent);
19496             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19497                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19498                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19499                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19500             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19501             final boolean replaced = replacePending
19502                     && (queue.replaceParallelBroadcastLocked(r) != null);
19503             // Note: We assume resultTo is null for non-ordered broadcasts.
19504             if (!replaced) {
19505                 queue.enqueueParallelBroadcastLocked(r);
19506                 queue.scheduleBroadcastsLocked();
19507             }
19508             registeredReceivers = null;
19509             NR = 0;
19510         }
19511
19512         // Merge into one list.
19513         int ir = 0;
19514         if (receivers != null) {
19515             // A special case for PACKAGE_ADDED: do not allow the package
19516             // being added to see this broadcast.  This prevents them from
19517             // using this as a back door to get run as soon as they are
19518             // installed.  Maybe in the future we want to have a special install
19519             // broadcast or such for apps, but we'd like to deliberately make
19520             // this decision.
19521             String skipPackages[] = null;
19522             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19523                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19524                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19525                 Uri data = intent.getData();
19526                 if (data != null) {
19527                     String pkgName = data.getSchemeSpecificPart();
19528                     if (pkgName != null) {
19529                         skipPackages = new String[] { pkgName };
19530                     }
19531                 }
19532             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19533                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19534             }
19535             if (skipPackages != null && (skipPackages.length > 0)) {
19536                 for (String skipPackage : skipPackages) {
19537                     if (skipPackage != null) {
19538                         int NT = receivers.size();
19539                         for (int it=0; it<NT; it++) {
19540                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
19541                             if (curt.activityInfo.packageName.equals(skipPackage)) {
19542                                 receivers.remove(it);
19543                                 it--;
19544                                 NT--;
19545                             }
19546                         }
19547                     }
19548                 }
19549             }
19550
19551             int NT = receivers != null ? receivers.size() : 0;
19552             int it = 0;
19553             ResolveInfo curt = null;
19554             BroadcastFilter curr = null;
19555             while (it < NT && ir < NR) {
19556                 if (curt == null) {
19557                     curt = (ResolveInfo)receivers.get(it);
19558                 }
19559                 if (curr == null) {
19560                     curr = registeredReceivers.get(ir);
19561                 }
19562                 if (curr.getPriority() >= curt.priority) {
19563                     // Insert this broadcast record into the final list.
19564                     receivers.add(it, curr);
19565                     ir++;
19566                     curr = null;
19567                     it++;
19568                     NT++;
19569                 } else {
19570                     // Skip to the next ResolveInfo in the final list.
19571                     it++;
19572                     curt = null;
19573                 }
19574             }
19575         }
19576         while (ir < NR) {
19577             if (receivers == null) {
19578                 receivers = new ArrayList();
19579             }
19580             receivers.add(registeredReceivers.get(ir));
19581             ir++;
19582         }
19583
19584         if (isCallerSystem) {
19585             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19586                     isProtectedBroadcast, receivers);
19587         }
19588
19589         if ((receivers != null && receivers.size() > 0)
19590                 || resultTo != null) {
19591             BroadcastQueue queue = broadcastQueueForIntent(intent);
19592             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19593                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19594                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19595                     resultData, resultExtras, ordered, sticky, false, userId);
19596
19597             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19598                     + ": prev had " + queue.mOrderedBroadcasts.size());
19599             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19600                     "Enqueueing broadcast " + r.intent.getAction());
19601
19602             final BroadcastRecord oldRecord =
19603                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19604             if (oldRecord != null) {
19605                 // Replaced, fire the result-to receiver.
19606                 if (oldRecord.resultTo != null) {
19607                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19608                     try {
19609                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19610                                 oldRecord.intent,
19611                                 Activity.RESULT_CANCELED, null, null,
19612                                 false, false, oldRecord.userId);
19613                     } catch (RemoteException e) {
19614                         Slog.w(TAG, "Failure ["
19615                                 + queue.mQueueName + "] sending broadcast result of "
19616                                 + intent, e);
19617
19618                     }
19619                 }
19620             } else {
19621                 queue.enqueueOrderedBroadcastLocked(r);
19622                 queue.scheduleBroadcastsLocked();
19623             }
19624         } else {
19625             // There was nobody interested in the broadcast, but we still want to record
19626             // that it happened.
19627             if (intent.getComponent() == null && intent.getPackage() == null
19628                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19629                 // This was an implicit broadcast... let's record it for posterity.
19630                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19631             }
19632         }
19633
19634         return ActivityManager.BROADCAST_SUCCESS;
19635     }
19636
19637     /**
19638      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19639      */
19640     private int getUidFromIntent(Intent intent) {
19641         if (intent == null) {
19642             return -1;
19643         }
19644         final Bundle intentExtras = intent.getExtras();
19645         return intent.hasExtra(Intent.EXTRA_UID)
19646                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19647     }
19648
19649     final void rotateBroadcastStatsIfNeededLocked() {
19650         final long now = SystemClock.elapsedRealtime();
19651         if (mCurBroadcastStats == null ||
19652                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19653             mLastBroadcastStats = mCurBroadcastStats;
19654             if (mLastBroadcastStats != null) {
19655                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19656                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19657             }
19658             mCurBroadcastStats = new BroadcastStats();
19659         }
19660     }
19661
19662     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19663             int skipCount, long dispatchTime) {
19664         rotateBroadcastStatsIfNeededLocked();
19665         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19666     }
19667
19668     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19669         rotateBroadcastStatsIfNeededLocked();
19670         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19671     }
19672
19673     final Intent verifyBroadcastLocked(Intent intent) {
19674         // Refuse possible leaked file descriptors
19675         if (intent != null && intent.hasFileDescriptors() == true) {
19676             throw new IllegalArgumentException("File descriptors passed in Intent");
19677         }
19678
19679         int flags = intent.getFlags();
19680
19681         if (!mProcessesReady) {
19682             // if the caller really truly claims to know what they're doing, go
19683             // ahead and allow the broadcast without launching any receivers
19684             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19685                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19686             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19687                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19688                         + " before boot completion");
19689                 throw new IllegalStateException("Cannot broadcast before boot completed");
19690             }
19691         }
19692
19693         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19694             throw new IllegalArgumentException(
19695                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19696         }
19697
19698         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19699             switch (Binder.getCallingUid()) {
19700                 case ROOT_UID:
19701                 case SHELL_UID:
19702                     break;
19703                 default:
19704                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19705                             + Binder.getCallingUid());
19706                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19707                     break;
19708             }
19709         }
19710
19711         return intent;
19712     }
19713
19714     public final int broadcastIntent(IApplicationThread caller,
19715             Intent intent, String resolvedType, IIntentReceiver resultTo,
19716             int resultCode, String resultData, Bundle resultExtras,
19717             String[] requiredPermissions, int appOp, Bundle bOptions,
19718             boolean serialized, boolean sticky, int userId) {
19719         enforceNotIsolatedCaller("broadcastIntent");
19720         synchronized(this) {
19721             intent = verifyBroadcastLocked(intent);
19722
19723             final ProcessRecord callerApp = getRecordForAppLocked(caller);
19724             final int callingPid = Binder.getCallingPid();
19725             final int callingUid = Binder.getCallingUid();
19726             final long origId = Binder.clearCallingIdentity();
19727             int res = broadcastIntentLocked(callerApp,
19728                     callerApp != null ? callerApp.info.packageName : null,
19729                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19730                     requiredPermissions, appOp, bOptions, serialized, sticky,
19731                     callingPid, callingUid, userId);
19732             Binder.restoreCallingIdentity(origId);
19733             return res;
19734         }
19735     }
19736
19737
19738     int broadcastIntentInPackage(String packageName, int uid,
19739             Intent intent, String resolvedType, IIntentReceiver resultTo,
19740             int resultCode, String resultData, Bundle resultExtras,
19741             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19742             int userId) {
19743         synchronized(this) {
19744             intent = verifyBroadcastLocked(intent);
19745
19746             final long origId = Binder.clearCallingIdentity();
19747             String[] requiredPermissions = requiredPermission == null ? null
19748                     : new String[] {requiredPermission};
19749             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19750                     resultTo, resultCode, resultData, resultExtras,
19751                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19752                     sticky, -1, uid, userId);
19753             Binder.restoreCallingIdentity(origId);
19754             return res;
19755         }
19756     }
19757
19758     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19759         // Refuse possible leaked file descriptors
19760         if (intent != null && intent.hasFileDescriptors() == true) {
19761             throw new IllegalArgumentException("File descriptors passed in Intent");
19762         }
19763
19764         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19765                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19766
19767         synchronized(this) {
19768             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19769                     != PackageManager.PERMISSION_GRANTED) {
19770                 String msg = "Permission Denial: unbroadcastIntent() from pid="
19771                         + Binder.getCallingPid()
19772                         + ", uid=" + Binder.getCallingUid()
19773                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19774                 Slog.w(TAG, msg);
19775                 throw new SecurityException(msg);
19776             }
19777             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19778             if (stickies != null) {
19779                 ArrayList<Intent> list = stickies.get(intent.getAction());
19780                 if (list != null) {
19781                     int N = list.size();
19782                     int i;
19783                     for (i=0; i<N; i++) {
19784                         if (intent.filterEquals(list.get(i))) {
19785                             list.remove(i);
19786                             break;
19787                         }
19788                     }
19789                     if (list.size() <= 0) {
19790                         stickies.remove(intent.getAction());
19791                     }
19792                 }
19793                 if (stickies.size() <= 0) {
19794                     mStickyBroadcasts.remove(userId);
19795                 }
19796             }
19797         }
19798     }
19799
19800     void backgroundServicesFinishedLocked(int userId) {
19801         for (BroadcastQueue queue : mBroadcastQueues) {
19802             queue.backgroundServicesFinishedLocked(userId);
19803         }
19804     }
19805
19806     public void finishReceiver(IBinder who, int resultCode, String resultData,
19807             Bundle resultExtras, boolean resultAbort, int flags) {
19808         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19809
19810         // Refuse possible leaked file descriptors
19811         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19812             throw new IllegalArgumentException("File descriptors passed in Bundle");
19813         }
19814
19815         final long origId = Binder.clearCallingIdentity();
19816         try {
19817             boolean doNext = false;
19818             BroadcastRecord r;
19819
19820             synchronized(this) {
19821                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19822                         ? mFgBroadcastQueue : mBgBroadcastQueue;
19823                 r = queue.getMatchingOrderedReceiver(who);
19824                 if (r != null) {
19825                     doNext = r.queue.finishReceiverLocked(r, resultCode,
19826                         resultData, resultExtras, resultAbort, true);
19827                 }
19828             }
19829
19830             if (doNext) {
19831                 r.queue.processNextBroadcast(false);
19832             }
19833             trimApplications();
19834         } finally {
19835             Binder.restoreCallingIdentity(origId);
19836         }
19837     }
19838
19839     // =========================================================
19840     // INSTRUMENTATION
19841     // =========================================================
19842
19843     public boolean startInstrumentation(ComponentName className,
19844             String profileFile, int flags, Bundle arguments,
19845             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19846             int userId, String abiOverride) {
19847         enforceNotIsolatedCaller("startInstrumentation");
19848         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19849                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19850         // Refuse possible leaked file descriptors
19851         if (arguments != null && arguments.hasFileDescriptors()) {
19852             throw new IllegalArgumentException("File descriptors passed in Bundle");
19853         }
19854
19855         synchronized(this) {
19856             InstrumentationInfo ii = null;
19857             ApplicationInfo ai = null;
19858             try {
19859                 ii = mContext.getPackageManager().getInstrumentationInfo(
19860                     className, STOCK_PM_FLAGS);
19861                 ai = AppGlobals.getPackageManager().getApplicationInfo(
19862                         ii.targetPackage, STOCK_PM_FLAGS, userId);
19863             } catch (PackageManager.NameNotFoundException e) {
19864             } catch (RemoteException e) {
19865             }
19866             if (ii == null) {
19867                 reportStartInstrumentationFailureLocked(watcher, className,
19868                         "Unable to find instrumentation info for: " + className);
19869                 return false;
19870             }
19871             if (ai == null) {
19872                 reportStartInstrumentationFailureLocked(watcher, className,
19873                         "Unable to find instrumentation target package: " + ii.targetPackage);
19874                 return false;
19875             }
19876             if (!ai.hasCode()) {
19877                 reportStartInstrumentationFailureLocked(watcher, className,
19878                         "Instrumentation target has no code: " + ii.targetPackage);
19879                 return false;
19880             }
19881
19882             int match = mContext.getPackageManager().checkSignatures(
19883                     ii.targetPackage, ii.packageName);
19884             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19885                 String msg = "Permission Denial: starting instrumentation "
19886                         + className + " from pid="
19887                         + Binder.getCallingPid()
19888                         + ", uid=" + Binder.getCallingPid()
19889                         + " not allowed because package " + ii.packageName
19890                         + " does not have a signature matching the target "
19891                         + ii.targetPackage;
19892                 reportStartInstrumentationFailureLocked(watcher, className, msg);
19893                 throw new SecurityException(msg);
19894             }
19895
19896             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19897             activeInstr.mClass = className;
19898             String defProcess = ai.processName;;
19899             if (ii.targetProcesses == null) {
19900                 activeInstr.mTargetProcesses = new String[]{ai.processName};
19901             } else if (ii.targetProcesses.equals("*")) {
19902                 activeInstr.mTargetProcesses = new String[0];
19903             } else {
19904                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19905                 defProcess = activeInstr.mTargetProcesses[0];
19906             }
19907             activeInstr.mTargetInfo = ai;
19908             activeInstr.mProfileFile = profileFile;
19909             activeInstr.mArguments = arguments;
19910             activeInstr.mWatcher = watcher;
19911             activeInstr.mUiAutomationConnection = uiAutomationConnection;
19912             activeInstr.mResultClass = className;
19913
19914             final long origId = Binder.clearCallingIdentity();
19915             // Instrumentation can kill and relaunch even persistent processes
19916             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19917                     "start instr");
19918             ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19919             app.instr = activeInstr;
19920             activeInstr.mFinished = false;
19921             activeInstr.mRunningProcesses.add(app);
19922             if (!mActiveInstrumentation.contains(activeInstr)) {
19923                 mActiveInstrumentation.add(activeInstr);
19924             }
19925             Binder.restoreCallingIdentity(origId);
19926         }
19927
19928         return true;
19929     }
19930
19931     /**
19932      * Report errors that occur while attempting to start Instrumentation.  Always writes the
19933      * error to the logs, but if somebody is watching, send the report there too.  This enables
19934      * the "am" command to report errors with more information.
19935      *
19936      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19937      * @param cn The component name of the instrumentation.
19938      * @param report The error report.
19939      */
19940     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19941             ComponentName cn, String report) {
19942         Slog.w(TAG, report);
19943         if (watcher != null) {
19944             Bundle results = new Bundle();
19945             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19946             results.putString("Error", report);
19947             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19948         }
19949     }
19950
19951     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19952         if (app.instr == null) {
19953             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19954             return;
19955         }
19956
19957         if (!app.instr.mFinished && results != null) {
19958             if (app.instr.mCurResults == null) {
19959                 app.instr.mCurResults = new Bundle(results);
19960             } else {
19961                 app.instr.mCurResults.putAll(results);
19962             }
19963         }
19964     }
19965
19966     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19967         int userId = UserHandle.getCallingUserId();
19968         // Refuse possible leaked file descriptors
19969         if (results != null && results.hasFileDescriptors()) {
19970             throw new IllegalArgumentException("File descriptors passed in Intent");
19971         }
19972
19973         synchronized(this) {
19974             ProcessRecord app = getRecordForAppLocked(target);
19975             if (app == null) {
19976                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19977                 return;
19978             }
19979             final long origId = Binder.clearCallingIdentity();
19980             addInstrumentationResultsLocked(app, results);
19981             Binder.restoreCallingIdentity(origId);
19982         }
19983     }
19984
19985     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
19986         if (app.instr == null) {
19987             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19988             return;
19989         }
19990
19991         if (!app.instr.mFinished) {
19992             if (app.instr.mWatcher != null) {
19993                 Bundle finalResults = app.instr.mCurResults;
19994                 if (finalResults != null) {
19995                     if (app.instr.mCurResults != null && results != null) {
19996                         finalResults.putAll(results);
19997                     }
19998                 } else {
19999                     finalResults = results;
20000                 }
20001                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20002                         app.instr.mClass, resultCode, finalResults);
20003             }
20004
20005             // Can't call out of the system process with a lock held, so post a message.
20006             if (app.instr.mUiAutomationConnection != null) {
20007                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20008                         app.instr.mUiAutomationConnection).sendToTarget();
20009             }
20010             app.instr.mFinished = true;
20011         }
20012
20013         app.instr.removeProcess(app);
20014         app.instr = null;
20015
20016         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20017                 "finished inst");
20018     }
20019
20020     public void finishInstrumentation(IApplicationThread target,
20021             int resultCode, Bundle results) {
20022         int userId = UserHandle.getCallingUserId();
20023         // Refuse possible leaked file descriptors
20024         if (results != null && results.hasFileDescriptors()) {
20025             throw new IllegalArgumentException("File descriptors passed in Intent");
20026         }
20027
20028         synchronized(this) {
20029             ProcessRecord app = getRecordForAppLocked(target);
20030             if (app == null) {
20031                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20032                 return;
20033             }
20034             final long origId = Binder.clearCallingIdentity();
20035             finishInstrumentationLocked(app, resultCode, results);
20036             Binder.restoreCallingIdentity(origId);
20037         }
20038     }
20039
20040     // =========================================================
20041     // CONFIGURATION
20042     // =========================================================
20043
20044     public ConfigurationInfo getDeviceConfigurationInfo() {
20045         ConfigurationInfo config = new ConfigurationInfo();
20046         synchronized (this) {
20047             final Configuration globalConfig = getGlobalConfiguration();
20048             config.reqTouchScreen = globalConfig.touchscreen;
20049             config.reqKeyboardType = globalConfig.keyboard;
20050             config.reqNavigation = globalConfig.navigation;
20051             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20052                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20053                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20054             }
20055             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20056                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20057                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20058             }
20059             config.reqGlEsVersion = GL_ES_VERSION;
20060         }
20061         return config;
20062     }
20063
20064     ActivityStack getFocusedStack() {
20065         return mStackSupervisor.getFocusedStack();
20066     }
20067
20068     @Override
20069     public int getFocusedStackId() throws RemoteException {
20070         ActivityStack focusedStack = getFocusedStack();
20071         if (focusedStack != null) {
20072             return focusedStack.getStackId();
20073         }
20074         return -1;
20075     }
20076
20077     public Configuration getConfiguration() {
20078         Configuration ci;
20079         synchronized(this) {
20080             ci = new Configuration(getGlobalConfiguration());
20081             ci.userSetLocale = false;
20082         }
20083         return ci;
20084     }
20085
20086     @Override
20087     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20088         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20089         synchronized (this) {
20090             mSuppressResizeConfigChanges = suppress;
20091         }
20092     }
20093
20094     /**
20095      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20096      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20097      *       activity and clearing the task at the same time.
20098      */
20099     @Override
20100     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20101         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20102         if (StackId.isHomeOrRecentsStack(fromStackId)) {
20103             throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20104         }
20105         synchronized (this) {
20106             final long origId = Binder.clearCallingIdentity();
20107             try {
20108                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20109             } finally {
20110                 Binder.restoreCallingIdentity(origId);
20111             }
20112         }
20113     }
20114
20115     @Override
20116     public void updatePersistentConfiguration(Configuration values) {
20117         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20118         enforceWriteSettingsPermission("updatePersistentConfiguration()");
20119         if (values == null) {
20120             throw new NullPointerException("Configuration must not be null");
20121         }
20122
20123         int userId = UserHandle.getCallingUserId();
20124
20125         synchronized(this) {
20126             updatePersistentConfigurationLocked(values, userId);
20127         }
20128     }
20129
20130     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20131         final long origId = Binder.clearCallingIdentity();
20132         try {
20133             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20134         } finally {
20135             Binder.restoreCallingIdentity(origId);
20136         }
20137     }
20138
20139     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20140         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20141                 FONT_SCALE, 1.0f, userId);
20142
20143         synchronized (this) {
20144             if (getGlobalConfiguration().fontScale == scaleFactor) {
20145                 return;
20146             }
20147
20148             final Configuration configuration
20149                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20150             configuration.fontScale = scaleFactor;
20151             updatePersistentConfigurationLocked(configuration, userId);
20152         }
20153     }
20154
20155     private void enforceWriteSettingsPermission(String func) {
20156         int uid = Binder.getCallingUid();
20157         if (uid == ROOT_UID) {
20158             return;
20159         }
20160
20161         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20162                 Settings.getPackageNameForUid(mContext, uid), false)) {
20163             return;
20164         }
20165
20166         String msg = "Permission Denial: " + func + " from pid="
20167                 + Binder.getCallingPid()
20168                 + ", uid=" + uid
20169                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20170         Slog.w(TAG, msg);
20171         throw new SecurityException(msg);
20172     }
20173
20174     @Override
20175     public boolean updateConfiguration(Configuration values) {
20176         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20177
20178         synchronized(this) {
20179             if (values == null && mWindowManager != null) {
20180                 // sentinel: fetch the current configuration from the window manager
20181                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20182             }
20183
20184             if (mWindowManager != null) {
20185                 // Update OOM levels based on display size.
20186                 mProcessList.applyDisplaySize(mWindowManager);
20187             }
20188
20189             final long origId = Binder.clearCallingIdentity();
20190             try {
20191                 if (values != null) {
20192                     Settings.System.clearConfiguration(values);
20193                 }
20194                 updateConfigurationLocked(values, null, false, false /* persistent */,
20195                         UserHandle.USER_NULL, false /* deferResume */,
20196                         mTmpUpdateConfigurationResult);
20197                 return mTmpUpdateConfigurationResult.changes != 0;
20198             } finally {
20199                 Binder.restoreCallingIdentity(origId);
20200             }
20201         }
20202     }
20203
20204     void updateUserConfigurationLocked() {
20205         final Configuration configuration = new Configuration(getGlobalConfiguration());
20206         final int currentUserId = mUserController.getCurrentUserIdLocked();
20207         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20208                 currentUserId, Settings.System.canWrite(mContext));
20209         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20210                 false /* persistent */, currentUserId, false /* deferResume */);
20211     }
20212
20213     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20214             boolean initLocale) {
20215         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20216     }
20217
20218     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20219             boolean initLocale, boolean deferResume) {
20220         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20221         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20222                 UserHandle.USER_NULL, deferResume);
20223     }
20224
20225     // To cache the list of supported system locales
20226     private String[] mSupportedSystemLocales = null;
20227
20228     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20229             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20230         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20231                 deferResume, null /* result */);
20232     }
20233
20234     /**
20235      * Do either or both things: (1) change the current configuration, and (2)
20236      * make sure the given activity is running with the (now) current
20237      * configuration.  Returns true if the activity has been left running, or
20238      * false if <var>starting</var> is being destroyed to match the new
20239      * configuration.
20240      *
20241      * @param userId is only used when persistent parameter is set to true to persist configuration
20242      *               for that particular user
20243      */
20244     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20245             boolean initLocale, boolean persistent, int userId, boolean deferResume,
20246             UpdateConfigurationResult result) {
20247         int changes = 0;
20248         boolean kept = true;
20249
20250         if (mWindowManager != null) {
20251             mWindowManager.deferSurfaceLayout();
20252         }
20253         try {
20254             if (values != null) {
20255                 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20256                         deferResume);
20257             }
20258
20259             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20260         } finally {
20261             if (mWindowManager != null) {
20262                 mWindowManager.continueSurfaceLayout();
20263             }
20264         }
20265
20266         if (result != null) {
20267             result.changes = changes;
20268             result.activityRelaunched = !kept;
20269         }
20270         return kept;
20271     }
20272
20273     /** Update default (global) configuration and notify listeners about changes. */
20274     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20275             boolean persistent, int userId, boolean deferResume) {
20276         mTempConfig.setTo(getGlobalConfiguration());
20277         final int changes = mTempConfig.updateFrom(values);
20278         if (changes == 0) {
20279             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20280             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20281             // performDisplayOverrideConfigUpdate in order to send the new display configuration
20282             // (even if there are no actual changes) to unfreeze the window.
20283             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20284             return 0;
20285         }
20286
20287         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20288                 "Updating global configuration to: " + values);
20289
20290         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20291
20292         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20293             final LocaleList locales = values.getLocales();
20294             int bestLocaleIndex = 0;
20295             if (locales.size() > 1) {
20296                 if (mSupportedSystemLocales == null) {
20297                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20298                 }
20299                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20300             }
20301             SystemProperties.set("persist.sys.locale",
20302                     locales.get(bestLocaleIndex).toLanguageTag());
20303             LocaleList.setDefault(locales, bestLocaleIndex);
20304             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20305                     locales.get(bestLocaleIndex)));
20306         }
20307
20308         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20309         mTempConfig.seq = mConfigurationSeq;
20310
20311         // Update stored global config and notify everyone about the change.
20312         mStackSupervisor.onConfigurationChanged(mTempConfig);
20313
20314         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20315         // TODO(multi-display): Update UsageEvents#Event to include displayId.
20316         mUsageStatsService.reportConfigurationChange(mTempConfig,
20317                 mUserController.getCurrentUserIdLocked());
20318
20319         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20320         mShowDialogs = shouldShowDialogs(mTempConfig);
20321
20322         AttributeCache ac = AttributeCache.instance();
20323         if (ac != null) {
20324             ac.updateConfiguration(mTempConfig);
20325         }
20326
20327         // Make sure all resources in our process are updated right now, so that anyone who is going
20328         // to retrieve resource values after we return will be sure to get the new ones. This is
20329         // especially important during boot, where the first config change needs to guarantee all
20330         // resources have that config before following boot code is executed.
20331         mSystemThread.applyConfigurationToResources(mTempConfig);
20332
20333         // We need another copy of global config because we're scheduling some calls instead of
20334         // running them in place. We need to be sure that object we send will be handled unchanged.
20335         final Configuration configCopy = new Configuration(mTempConfig);
20336         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20337             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20338             msg.obj = configCopy;
20339             msg.arg1 = userId;
20340             mHandler.sendMessage(msg);
20341         }
20342
20343         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20344             ProcessRecord app = mLruProcesses.get(i);
20345             try {
20346                 if (app.thread != null) {
20347                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20348                             + app.processName + " new config " + configCopy);
20349                     app.thread.scheduleConfigurationChanged(configCopy);
20350                 }
20351             } catch (Exception e) {
20352             }
20353         }
20354
20355         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20356         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20357                 | Intent.FLAG_RECEIVER_FOREGROUND
20358                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20359         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20360                 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20361                 UserHandle.USER_ALL);
20362         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20363             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20364             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20365                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20366                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20367             if (initLocale || !mProcessesReady) {
20368                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20369             }
20370             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20371                     AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20372                     UserHandle.USER_ALL);
20373         }
20374
20375         // Override configuration of the default display duplicates global config, so we need to
20376         // update it also. This will also notify WindowManager about changes.
20377         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20378                 DEFAULT_DISPLAY);
20379
20380         return changes;
20381     }
20382
20383     @Override
20384     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20385         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20386
20387         synchronized (this) {
20388             // Check if display is initialized in AM.
20389             if (!mStackSupervisor.isDisplayAdded(displayId)) {
20390                 // Call might come when display is not yet added or has already been removed.
20391                 if (DEBUG_CONFIGURATION) {
20392                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20393                             + displayId);
20394                 }
20395                 return false;
20396             }
20397
20398             if (values == null && mWindowManager != null) {
20399                 // sentinel: fetch the current configuration from the window manager
20400                 values = mWindowManager.computeNewConfiguration(displayId);
20401             }
20402
20403             if (mWindowManager != null) {
20404                 // Update OOM levels based on display size.
20405                 mProcessList.applyDisplaySize(mWindowManager);
20406             }
20407
20408             final long origId = Binder.clearCallingIdentity();
20409             try {
20410                 if (values != null) {
20411                     Settings.System.clearConfiguration(values);
20412                 }
20413                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20414                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20415                 return mTmpUpdateConfigurationResult.changes != 0;
20416             } finally {
20417                 Binder.restoreCallingIdentity(origId);
20418             }
20419         }
20420     }
20421
20422     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20423             boolean deferResume, int displayId) {
20424         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20425                 displayId, null /* result */);
20426     }
20427
20428     /**
20429      * Updates override configuration specific for the selected display. If no config is provided,
20430      * new one will be computed in WM based on current display info.
20431      */
20432     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20433             ActivityRecord starting, boolean deferResume, int displayId,
20434             UpdateConfigurationResult result) {
20435         int changes = 0;
20436         boolean kept = true;
20437
20438         if (mWindowManager != null) {
20439             mWindowManager.deferSurfaceLayout();
20440         }
20441         try {
20442             if (values != null) {
20443                 if (displayId == DEFAULT_DISPLAY) {
20444                     // Override configuration of the default display duplicates global config, so
20445                     // we're calling global config update instead for default display. It will also
20446                     // apply the correct override config.
20447                     changes = updateGlobalConfiguration(values, false /* initLocale */,
20448                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20449                 } else {
20450                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20451                 }
20452             }
20453
20454             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20455         } finally {
20456             if (mWindowManager != null) {
20457                 mWindowManager.continueSurfaceLayout();
20458             }
20459         }
20460
20461         if (result != null) {
20462             result.changes = changes;
20463             result.activityRelaunched = !kept;
20464         }
20465         return kept;
20466     }
20467
20468     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20469             int displayId) {
20470         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20471         final int changes = mTempConfig.updateFrom(values);
20472         if (changes != 0) {
20473             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20474                     + mTempConfig + " for displayId=" + displayId);
20475             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20476
20477             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20478             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20479                 // Reset the unsupported display size dialog.
20480                 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20481
20482                 killAllBackgroundProcessesExcept(N,
20483                         ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20484             }
20485         }
20486
20487         // Update the configuration with WM first and check if any of the stacks need to be resized
20488         // due to the configuration change. If so, resize the stacks now and do any relaunches if
20489         // necessary. This way we don't need to relaunch again afterwards in
20490         // ensureActivityConfigurationLocked().
20491         if (mWindowManager != null) {
20492             final int[] resizedStacks =
20493                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20494             if (resizedStacks != null) {
20495                 for (int stackId : resizedStacks) {
20496                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20497                 }
20498             }
20499         }
20500
20501         return changes;
20502     }
20503
20504     /** Applies latest configuration and/or visibility updates if needed. */
20505     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20506         boolean kept = true;
20507         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20508         // mainStack is null during startup.
20509         if (mainStack != null) {
20510             if (changes != 0 && starting == null) {
20511                 // If the configuration changed, and the caller is not already
20512                 // in the process of starting an activity, then find the top
20513                 // activity to check if its configuration needs to change.
20514                 starting = mainStack.topRunningActivityLocked();
20515             }
20516
20517             if (starting != null) {
20518                 kept = starting.ensureActivityConfigurationLocked(changes,
20519                         false /* preserveWindow */);
20520                 // And we need to make sure at this point that all other activities
20521                 // are made visible with the correct configuration.
20522                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20523                         !PRESERVE_WINDOWS);
20524             }
20525         }
20526
20527         return kept;
20528     }
20529
20530     /** Helper method that requests bounds from WM and applies them to stack. */
20531     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20532         final Rect newStackBounds = new Rect();
20533         mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20534         mStackSupervisor.resizeStackLocked(
20535                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20536                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20537                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20538     }
20539
20540     /**
20541      * Decide based on the configuration whether we should show the ANR,
20542      * crash, etc dialogs.  The idea is that if there is no affordance to
20543      * press the on-screen buttons, or the user experience would be more
20544      * greatly impacted than the crash itself, we shouldn't show the dialog.
20545      *
20546      * A thought: SystemUI might also want to get told about this, the Power
20547      * dialog / global actions also might want different behaviors.
20548      */
20549     private static boolean shouldShowDialogs(Configuration config) {
20550         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20551                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20552                                    && config.navigation == Configuration.NAVIGATION_NONAV);
20553         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20554         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20555                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20556                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20557                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20558         return inputMethodExists && uiModeSupportsDialogs;
20559     }
20560
20561     @Override
20562     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20563         synchronized (this) {
20564             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20565             if (srec != null) {
20566                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20567             }
20568         }
20569         return false;
20570     }
20571
20572     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20573             Intent resultData) {
20574
20575         synchronized (this) {
20576             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20577             if (r != null) {
20578                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20579             }
20580             return false;
20581         }
20582     }
20583
20584     public int getLaunchedFromUid(IBinder activityToken) {
20585         ActivityRecord srec;
20586         synchronized (this) {
20587             srec = ActivityRecord.forTokenLocked(activityToken);
20588         }
20589         if (srec == null) {
20590             return -1;
20591         }
20592         return srec.launchedFromUid;
20593     }
20594
20595     public String getLaunchedFromPackage(IBinder activityToken) {
20596         ActivityRecord srec;
20597         synchronized (this) {
20598             srec = ActivityRecord.forTokenLocked(activityToken);
20599         }
20600         if (srec == null) {
20601             return null;
20602         }
20603         return srec.launchedFromPackage;
20604     }
20605
20606     // =========================================================
20607     // LIFETIME MANAGEMENT
20608     // =========================================================
20609
20610     // Returns whether the app is receiving broadcast.
20611     // If receiving, fetch all broadcast queues which the app is
20612     // the current [or imminent] receiver on.
20613     private boolean isReceivingBroadcastLocked(ProcessRecord app,
20614             ArraySet<BroadcastQueue> receivingQueues) {
20615         if (!app.curReceivers.isEmpty()) {
20616             for (BroadcastRecord r : app.curReceivers) {
20617                 receivingQueues.add(r.queue);
20618             }
20619             return true;
20620         }
20621
20622         // It's not the current receiver, but it might be starting up to become one
20623         for (BroadcastQueue queue : mBroadcastQueues) {
20624             final BroadcastRecord r = queue.mPendingBroadcast;
20625             if (r != null && r.curApp == app) {
20626                 // found it; report which queue it's in
20627                 receivingQueues.add(queue);
20628             }
20629         }
20630
20631         return !receivingQueues.isEmpty();
20632     }
20633
20634     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20635             int targetUid, ComponentName targetComponent, String targetProcess) {
20636         if (!mTrackingAssociations) {
20637             return null;
20638         }
20639         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20640                 = mAssociations.get(targetUid);
20641         if (components == null) {
20642             components = new ArrayMap<>();
20643             mAssociations.put(targetUid, components);
20644         }
20645         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20646         if (sourceUids == null) {
20647             sourceUids = new SparseArray<>();
20648             components.put(targetComponent, sourceUids);
20649         }
20650         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20651         if (sourceProcesses == null) {
20652             sourceProcesses = new ArrayMap<>();
20653             sourceUids.put(sourceUid, sourceProcesses);
20654         }
20655         Association ass = sourceProcesses.get(sourceProcess);
20656         if (ass == null) {
20657             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20658                     targetProcess);
20659             sourceProcesses.put(sourceProcess, ass);
20660         }
20661         ass.mCount++;
20662         ass.mNesting++;
20663         if (ass.mNesting == 1) {
20664             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20665             ass.mLastState = sourceState;
20666         }
20667         return ass;
20668     }
20669
20670     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20671             ComponentName targetComponent) {
20672         if (!mTrackingAssociations) {
20673             return;
20674         }
20675         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20676                 = mAssociations.get(targetUid);
20677         if (components == null) {
20678             return;
20679         }
20680         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20681         if (sourceUids == null) {
20682             return;
20683         }
20684         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20685         if (sourceProcesses == null) {
20686             return;
20687         }
20688         Association ass = sourceProcesses.get(sourceProcess);
20689         if (ass == null || ass.mNesting <= 0) {
20690             return;
20691         }
20692         ass.mNesting--;
20693         if (ass.mNesting == 0) {
20694             long uptime = SystemClock.uptimeMillis();
20695             ass.mTime += uptime - ass.mStartTime;
20696             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20697                     += uptime - ass.mLastStateUptime;
20698             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20699         }
20700     }
20701
20702     private void noteUidProcessState(final int uid, final int state) {
20703         mBatteryStatsService.noteUidProcessState(uid, state);
20704         if (mTrackingAssociations) {
20705             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20706                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20707                         = mAssociations.valueAt(i1);
20708                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20709                     SparseArray<ArrayMap<String, Association>> sourceUids
20710                             = targetComponents.valueAt(i2);
20711                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20712                     if (sourceProcesses != null) {
20713                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20714                             Association ass = sourceProcesses.valueAt(i4);
20715                             if (ass.mNesting >= 1) {
20716                                 // currently associated
20717                                 long uptime = SystemClock.uptimeMillis();
20718                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20719                                         += uptime - ass.mLastStateUptime;
20720                                 ass.mLastState = state;
20721                                 ass.mLastStateUptime = uptime;
20722                             }
20723                         }
20724                     }
20725                 }
20726             }
20727         }
20728     }
20729
20730     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20731             boolean doingAll, long now) {
20732         if (mAdjSeq == app.adjSeq) {
20733             // This adjustment has already been computed.
20734             return app.curRawAdj;
20735         }
20736
20737         if (app.thread == null) {
20738             app.adjSeq = mAdjSeq;
20739             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20740             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20741             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20742         }
20743
20744         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20745         app.adjSource = null;
20746         app.adjTarget = null;
20747         app.empty = false;
20748         app.cached = false;
20749
20750         final int activitiesSize = app.activities.size();
20751
20752         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20753             // The max adjustment doesn't allow this app to be anything
20754             // below foreground, so it is not worth doing work for it.
20755             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20756             app.adjType = "fixed";
20757             app.adjSeq = mAdjSeq;
20758             app.curRawAdj = app.maxAdj;
20759             app.foregroundActivities = false;
20760             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20761             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20762             // System processes can do UI, and when they do we want to have
20763             // them trim their memory after the user leaves the UI.  To
20764             // facilitate this, here we need to determine whether or not it
20765             // is currently showing UI.
20766             app.systemNoUi = true;
20767             if (app == TOP_APP) {
20768                 app.systemNoUi = false;
20769                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20770                 app.adjType = "pers-top-activity";
20771             } else if (app.hasTopUi) {
20772                 app.systemNoUi = false;
20773                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20774                 app.adjType = "pers-top-ui";
20775             } else if (activitiesSize > 0) {
20776                 for (int j = 0; j < activitiesSize; j++) {
20777                     final ActivityRecord r = app.activities.get(j);
20778                     if (r.visible) {
20779                         app.systemNoUi = false;
20780                     }
20781                 }
20782             }
20783             if (!app.systemNoUi) {
20784                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20785             }
20786             return (app.curAdj=app.maxAdj);
20787         }
20788
20789         app.systemNoUi = false;
20790
20791         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20792
20793         // Determine the importance of the process, starting with most
20794         // important to least, and assign an appropriate OOM adjustment.
20795         int adj;
20796         int schedGroup;
20797         int procState;
20798         boolean foregroundActivities = false;
20799         mTmpBroadcastQueue.clear();
20800         if (app == TOP_APP) {
20801             // The last app on the list is the foreground app.
20802             adj = ProcessList.FOREGROUND_APP_ADJ;
20803             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20804             app.adjType = "top-activity";
20805             foregroundActivities = true;
20806             procState = PROCESS_STATE_CUR_TOP;
20807             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20808         } else if (app.instr != null) {
20809             // Don't want to kill running instrumentation.
20810             adj = ProcessList.FOREGROUND_APP_ADJ;
20811             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20812             app.adjType = "instrumentation";
20813             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20814             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20815         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20816             // An app that is currently receiving a broadcast also
20817             // counts as being in the foreground for OOM killer purposes.
20818             // It's placed in a sched group based on the nature of the
20819             // broadcast as reflected by which queue it's active in.
20820             adj = ProcessList.FOREGROUND_APP_ADJ;
20821             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20822                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20823             app.adjType = "broadcast";
20824             procState = ActivityManager.PROCESS_STATE_RECEIVER;
20825             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20826         } else if (app.executingServices.size() > 0) {
20827             // An app that is currently executing a service callback also
20828             // counts as being in the foreground.
20829             adj = ProcessList.FOREGROUND_APP_ADJ;
20830             schedGroup = app.execServicesFg ?
20831                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20832             app.adjType = "exec-service";
20833             procState = ActivityManager.PROCESS_STATE_SERVICE;
20834             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20835             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20836         } else {
20837             // As far as we know the process is empty.  We may change our mind later.
20838             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20839             // At this point we don't actually know the adjustment.  Use the cached adj
20840             // value that the caller wants us to.
20841             adj = cachedAdj;
20842             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20843             app.cached = true;
20844             app.empty = true;
20845             app.adjType = "cch-empty";
20846             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20847         }
20848
20849         // Examine all activities if not already foreground.
20850         if (!foregroundActivities && activitiesSize > 0) {
20851             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20852             for (int j = 0; j < activitiesSize; j++) {
20853                 final ActivityRecord r = app.activities.get(j);
20854                 if (r.app != app) {
20855                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20856                             + " instead of expected " + app);
20857                     if (r.app == null || (r.app.uid == app.uid)) {
20858                         // Only fix things up when they look sane
20859                         r.app = app;
20860                     } else {
20861                         continue;
20862                     }
20863                 }
20864                 if (r.visible) {
20865                     // App has a visible activity; only upgrade adjustment.
20866                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
20867                         adj = ProcessList.VISIBLE_APP_ADJ;
20868                         app.adjType = "vis-activity";
20869                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20870                     }
20871                     if (procState > PROCESS_STATE_CUR_TOP) {
20872                         procState = PROCESS_STATE_CUR_TOP;
20873                         app.adjType = "vis-activity";
20874                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20875                     }
20876                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20877                     app.cached = false;
20878                     app.empty = false;
20879                     foregroundActivities = true;
20880                     final TaskRecord task = r.getTask();
20881                     if (task != null && minLayer > 0) {
20882                         final int layer = task.mLayerRank;
20883                         if (layer >= 0 && minLayer > layer) {
20884                             minLayer = layer;
20885                         }
20886                     }
20887                     break;
20888                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20889                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20890                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20891                         app.adjType = "pause-activity";
20892                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20893                     }
20894                     if (procState > PROCESS_STATE_CUR_TOP) {
20895                         procState = PROCESS_STATE_CUR_TOP;
20896                         app.adjType = "pause-activity";
20897                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20898                     }
20899                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20900                     app.cached = false;
20901                     app.empty = false;
20902                     foregroundActivities = true;
20903                 } else if (r.state == ActivityState.STOPPING) {
20904                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20905                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20906                         app.adjType = "stop-activity";
20907                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20908                     }
20909                     // For the process state, we will at this point consider the
20910                     // process to be cached.  It will be cached either as an activity
20911                     // or empty depending on whether the activity is finishing.  We do
20912                     // this so that we can treat the process as cached for purposes of
20913                     // memory trimming (determing current memory level, trim command to
20914                     // send to process) since there can be an arbitrary number of stopping
20915                     // processes and they should soon all go into the cached state.
20916                     if (!r.finishing) {
20917                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20918                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20919                             app.adjType = "stop-activity";
20920                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20921                         }
20922                     }
20923                     app.cached = false;
20924                     app.empty = false;
20925                     foregroundActivities = true;
20926                 } else {
20927                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20928                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20929                         app.adjType = "cch-act";
20930                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
20931                     }
20932                 }
20933             }
20934             if (adj == ProcessList.VISIBLE_APP_ADJ) {
20935                 adj += minLayer;
20936             }
20937         }
20938
20939         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20940                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20941             if (app.foregroundServices) {
20942                 // The user is aware of this app, so make it visible.
20943                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20944                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20945                 app.cached = false;
20946                 app.adjType = "fg-service";
20947                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20948                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
20949             } else if (app.hasOverlayUi) {
20950                 // The process is display an overlay UI.
20951                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20952                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20953                 app.cached = false;
20954                 app.adjType = "has-overlay-ui";
20955                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20956                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
20957             }
20958         }
20959
20960         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20961                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
20962             if (app.forcingToImportant != null) {
20963                 // This is currently used for toasts...  they are not interactive, and
20964                 // we don't want them to cause the app to become fully foreground (and
20965                 // thus out of background check), so we yes the best background level we can.
20966                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20967                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
20968                 app.cached = false;
20969                 app.adjType = "force-imp";
20970                 app.adjSource = app.forcingToImportant;
20971                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20972                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
20973             }
20974         }
20975
20976         if (app == mHeavyWeightProcess) {
20977             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20978                 // We don't want to kill the current heavy-weight process.
20979                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20980                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20981                 app.cached = false;
20982                 app.adjType = "heavy";
20983                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
20984             }
20985             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20986                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
20987                 app.adjType = "heavy";
20988                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
20989             }
20990         }
20991
20992         if (app == mHomeProcess) {
20993             if (adj > ProcessList.HOME_APP_ADJ) {
20994                 // This process is hosting what we currently consider to be the
20995                 // home app, so we don't want to let it go into the background.
20996                 adj = ProcessList.HOME_APP_ADJ;
20997                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20998                 app.cached = false;
20999                 app.adjType = "home";
21000                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21001             }
21002             if (procState > ActivityManager.PROCESS_STATE_HOME) {
21003                 procState = ActivityManager.PROCESS_STATE_HOME;
21004                 app.adjType = "home";
21005                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21006             }
21007         }
21008
21009         if (app == mPreviousProcess && app.activities.size() > 0) {
21010             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21011                 // This was the previous process that showed UI to the user.
21012                 // We want to try to keep it around more aggressively, to give
21013                 // a good experience around switching between two apps.
21014                 adj = ProcessList.PREVIOUS_APP_ADJ;
21015                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21016                 app.cached = false;
21017                 app.adjType = "previous";
21018                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21019             }
21020             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21021                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21022                 app.adjType = "previous";
21023                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21024             }
21025         }
21026
21027         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21028                 + " reason=" + app.adjType);
21029
21030         // By default, we use the computed adjustment.  It may be changed if
21031         // there are applications dependent on our services or providers, but
21032         // this gives us a baseline and makes sure we don't get into an
21033         // infinite recursion.
21034         app.adjSeq = mAdjSeq;
21035         app.curRawAdj = adj;
21036         app.hasStartedServices = false;
21037
21038         if (mBackupTarget != null && app == mBackupTarget.app) {
21039             // If possible we want to avoid killing apps while they're being backed up
21040             if (adj > ProcessList.BACKUP_APP_ADJ) {
21041                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21042                 adj = ProcessList.BACKUP_APP_ADJ;
21043                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21044                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21045                 }
21046                 app.adjType = "backup";
21047                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21048                 app.cached = false;
21049             }
21050             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21051                 procState = ActivityManager.PROCESS_STATE_BACKUP;
21052                 app.adjType = "backup";
21053                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21054             }
21055         }
21056
21057         boolean mayBeTop = false;
21058         String mayBeTopType = null;
21059         Object mayBeTopSource = null;
21060         Object mayBeTopTarget = null;
21061
21062         for (int is = app.services.size()-1;
21063                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21064                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21065                         || procState > ActivityManager.PROCESS_STATE_TOP);
21066                 is--) {
21067             ServiceRecord s = app.services.valueAt(is);
21068             if (s.startRequested) {
21069                 app.hasStartedServices = true;
21070                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21071                     procState = ActivityManager.PROCESS_STATE_SERVICE;
21072                     app.adjType = "started-services";
21073                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21074                 }
21075                 if (app.hasShownUi && app != mHomeProcess) {
21076                     // If this process has shown some UI, let it immediately
21077                     // go to the LRU list because it may be pretty heavy with
21078                     // UI stuff.  We'll tag it with a label just to help
21079                     // debug and understand what is going on.
21080                     if (adj > ProcessList.SERVICE_ADJ) {
21081                         app.adjType = "cch-started-ui-services";
21082                     }
21083                 } else {
21084                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21085                         // This service has seen some activity within
21086                         // recent memory, so we will keep its process ahead
21087                         // of the background processes.
21088                         if (adj > ProcessList.SERVICE_ADJ) {
21089                             adj = ProcessList.SERVICE_ADJ;
21090                             app.adjType = "started-services";
21091                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21092                             app.cached = false;
21093                         }
21094                     }
21095                     // If we have let the service slide into the background
21096                     // state, still have some text describing what it is doing
21097                     // even though the service no longer has an impact.
21098                     if (adj > ProcessList.SERVICE_ADJ) {
21099                         app.adjType = "cch-started-services";
21100                     }
21101                 }
21102             }
21103
21104             for (int conni = s.connections.size()-1;
21105                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21106                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21107                             || procState > ActivityManager.PROCESS_STATE_TOP);
21108                     conni--) {
21109                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21110                 for (int i = 0;
21111                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21112                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21113                                 || procState > ActivityManager.PROCESS_STATE_TOP);
21114                         i++) {
21115                     // XXX should compute this based on the max of
21116                     // all connected clients.
21117                     ConnectionRecord cr = clist.get(i);
21118                     if (cr.binding.client == app) {
21119                         // Binding to ourself is not interesting.
21120                         continue;
21121                     }
21122
21123                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21124                         ProcessRecord client = cr.binding.client;
21125                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
21126                                 TOP_APP, doingAll, now);
21127                         int clientProcState = client.curProcState;
21128                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21129                             // If the other app is cached for any reason, for purposes here
21130                             // we are going to consider it empty.  The specific cached state
21131                             // doesn't propagate except under certain conditions.
21132                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21133                         }
21134                         String adjType = null;
21135                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21136                             // Not doing bind OOM management, so treat
21137                             // this guy more like a started service.
21138                             if (app.hasShownUi && app != mHomeProcess) {
21139                                 // If this process has shown some UI, let it immediately
21140                                 // go to the LRU list because it may be pretty heavy with
21141                                 // UI stuff.  We'll tag it with a label just to help
21142                                 // debug and understand what is going on.
21143                                 if (adj > clientAdj) {
21144                                     adjType = "cch-bound-ui-services";
21145                                 }
21146                                 app.cached = false;
21147                                 clientAdj = adj;
21148                                 clientProcState = procState;
21149                             } else {
21150                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21151                                     // This service has not seen activity within
21152                                     // recent memory, so allow it to drop to the
21153                                     // LRU list if there is no other reason to keep
21154                                     // it around.  We'll also tag it with a label just
21155                                     // to help debug and undertand what is going on.
21156                                     if (adj > clientAdj) {
21157                                         adjType = "cch-bound-services";
21158                                     }
21159                                     clientAdj = adj;
21160                                 }
21161                             }
21162                         }
21163                         if (adj > clientAdj) {
21164                             // If this process has recently shown UI, and
21165                             // the process that is binding to it is less
21166                             // important than being visible, then we don't
21167                             // care about the binding as much as we care
21168                             // about letting this process get into the LRU
21169                             // list to be killed and restarted if needed for
21170                             // memory.
21171                             if (app.hasShownUi && app != mHomeProcess
21172                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21173                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21174                                     adjType = "cch-bound-ui-services";
21175                                 }
21176                             } else {
21177                                 int newAdj;
21178                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21179                                         |Context.BIND_IMPORTANT)) != 0) {
21180                                     newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21181                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21182                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21183                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21184                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21185                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21186                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21187                                     newAdj = clientAdj;
21188                                 } else {
21189                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
21190                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21191                                     } else {
21192                                         newAdj = adj;
21193                                     }
21194                                 }
21195                                 if (!client.cached) {
21196                                     app.cached = false;
21197                                 }
21198                                 if (adj >  newAdj) {
21199                                     adj = newAdj;
21200                                     adjType = "service";
21201                                 }
21202                             }
21203                         }
21204                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21205                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21206                             // This will treat important bound services identically to
21207                             // the top app, which may behave differently than generic
21208                             // foreground work.
21209                             if (client.curSchedGroup > schedGroup) {
21210                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21211                                     schedGroup = client.curSchedGroup;
21212                                 } else {
21213                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21214                                 }
21215                             }
21216                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21217                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21218                                     // Special handling of clients who are in the top state.
21219                                     // We *may* want to consider this process to be in the
21220                                     // top state as well, but only if there is not another
21221                                     // reason for it to be running.  Being on the top is a
21222                                     // special state, meaning you are specifically running
21223                                     // for the current top app.  If the process is already
21224                                     // running in the background for some other reason, it
21225                                     // is more important to continue considering it to be
21226                                     // in the background state.
21227                                     mayBeTop = true;
21228                                     mayBeTopType = "service";
21229                                     mayBeTopSource = cr.binding.client;
21230                                     mayBeTopTarget = s.name;
21231                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21232                                 } else {
21233                                     // Special handling for above-top states (persistent
21234                                     // processes).  These should not bring the current process
21235                                     // into the top state, since they are not on top.  Instead
21236                                     // give them the best state after that.
21237                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21238                                         clientProcState =
21239                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21240                                     } else if (mWakefulness
21241                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21242                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21243                                                     != 0) {
21244                                         clientProcState =
21245                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21246                                     } else {
21247                                         clientProcState =
21248                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21249                                     }
21250                                 }
21251                             }
21252                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21253                             if (clientProcState <
21254                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21255                                 clientProcState =
21256                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21257                             }
21258                         } else {
21259                             if (clientProcState <
21260                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21261                                 clientProcState =
21262                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21263                             }
21264                         }
21265                         if (procState > clientProcState) {
21266                             procState = clientProcState;
21267                             if (adjType == null) {
21268                                 adjType = "service";
21269                             }
21270                         }
21271                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21272                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21273                             app.pendingUiClean = true;
21274                         }
21275                         if (adjType != null) {
21276                             app.adjType = adjType;
21277                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21278                                     .REASON_SERVICE_IN_USE;
21279                             app.adjSource = cr.binding.client;
21280                             app.adjSourceProcState = clientProcState;
21281                             app.adjTarget = s.name;
21282                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21283                                     + ": " + app + ", due to " + cr.binding.client
21284                                     + " adj=" + adj + " procState=" + procState);
21285                         }
21286                     }
21287                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21288                         app.treatLikeActivity = true;
21289                     }
21290                     final ActivityRecord a = cr.activity;
21291                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21292                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21293                             (a.visible || a.state == ActivityState.RESUMED ||
21294                              a.state == ActivityState.PAUSING)) {
21295                             adj = ProcessList.FOREGROUND_APP_ADJ;
21296                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21297                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21298                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21299                                 } else {
21300                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21301                                 }
21302                             }
21303                             app.cached = false;
21304                             app.adjType = "service";
21305                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21306                                     .REASON_SERVICE_IN_USE;
21307                             app.adjSource = a;
21308                             app.adjSourceProcState = procState;
21309                             app.adjTarget = s.name;
21310                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21311                                     + app);
21312                         }
21313                     }
21314                 }
21315             }
21316         }
21317
21318         for (int provi = app.pubProviders.size()-1;
21319                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21320                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21321                         || procState > ActivityManager.PROCESS_STATE_TOP);
21322                 provi--) {
21323             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21324             for (int i = cpr.connections.size()-1;
21325                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21326                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21327                             || procState > ActivityManager.PROCESS_STATE_TOP);
21328                     i--) {
21329                 ContentProviderConnection conn = cpr.connections.get(i);
21330                 ProcessRecord client = conn.client;
21331                 if (client == app) {
21332                     // Being our own client is not interesting.
21333                     continue;
21334                 }
21335                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21336                 int clientProcState = client.curProcState;
21337                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21338                     // If the other app is cached for any reason, for purposes here
21339                     // we are going to consider it empty.
21340                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21341                 }
21342                 String adjType = null;
21343                 if (adj > clientAdj) {
21344                     if (app.hasShownUi && app != mHomeProcess
21345                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21346                         adjType = "cch-ui-provider";
21347                     } else {
21348                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21349                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21350                         adjType = "provider";
21351                     }
21352                     app.cached &= client.cached;
21353                 }
21354                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21355                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21356                         // Special handling of clients who are in the top state.
21357                         // We *may* want to consider this process to be in the
21358                         // top state as well, but only if there is not another
21359                         // reason for it to be running.  Being on the top is a
21360                         // special state, meaning you are specifically running
21361                         // for the current top app.  If the process is already
21362                         // running in the background for some other reason, it
21363                         // is more important to continue considering it to be
21364                         // in the background state.
21365                         mayBeTop = true;
21366                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21367                         mayBeTopType = adjType = "provider-top";
21368                         mayBeTopSource = client;
21369                         mayBeTopTarget = cpr.name;
21370                     } else {
21371                         // Special handling for above-top states (persistent
21372                         // processes).  These should not bring the current process
21373                         // into the top state, since they are not on top.  Instead
21374                         // give them the best state after that.
21375                         clientProcState =
21376                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21377                         if (adjType == null) {
21378                             adjType = "provider";
21379                         }
21380                     }
21381                 }
21382                 if (procState > clientProcState) {
21383                     procState = clientProcState;
21384                 }
21385                 if (client.curSchedGroup > schedGroup) {
21386                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21387                 }
21388                 if (adjType != null) {
21389                     app.adjType = adjType;
21390                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21391                             .REASON_PROVIDER_IN_USE;
21392                     app.adjSource = client;
21393                     app.adjSourceProcState = clientProcState;
21394                     app.adjTarget = cpr.name;
21395                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21396                             + ": " + app + ", due to " + client
21397                             + " adj=" + adj + " procState=" + procState);
21398                 }
21399             }
21400             // If the provider has external (non-framework) process
21401             // dependencies, ensure that its adjustment is at least
21402             // FOREGROUND_APP_ADJ.
21403             if (cpr.hasExternalProcessHandles()) {
21404                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21405                     adj = ProcessList.FOREGROUND_APP_ADJ;
21406                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21407                     app.cached = false;
21408                     app.adjType = "ext-provider";
21409                     app.adjTarget = cpr.name;
21410                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21411                 }
21412                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21413                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21414                 }
21415             }
21416         }
21417
21418         if (app.lastProviderTime > 0 &&
21419                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21420             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21421                 adj = ProcessList.PREVIOUS_APP_ADJ;
21422                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21423                 app.cached = false;
21424                 app.adjType = "recent-provider";
21425                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21426             }
21427             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21428                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21429                 app.adjType = "recent-provider";
21430                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21431             }
21432         }
21433
21434         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21435             // A client of one of our services or providers is in the top state.  We
21436             // *may* want to be in the top state, but not if we are already running in
21437             // the background for some other reason.  For the decision here, we are going
21438             // to pick out a few specific states that we want to remain in when a client
21439             // is top (states that tend to be longer-term) and otherwise allow it to go
21440             // to the top state.
21441             switch (procState) {
21442                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21443                     // Something else is keeping it at this level, just leave it.
21444                     break;
21445                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21446                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21447                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21448                 case ActivityManager.PROCESS_STATE_SERVICE:
21449                     // These all are longer-term states, so pull them up to the top
21450                     // of the background states, but not all the way to the top state.
21451                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21452                     app.adjType = mayBeTopType;
21453                     app.adjSource = mayBeTopSource;
21454                     app.adjTarget = mayBeTopTarget;
21455                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21456                             + ": " + app + ", due to " + mayBeTopSource
21457                             + " adj=" + adj + " procState=" + procState);
21458                     break;
21459                 default:
21460                     // Otherwise, top is a better choice, so take it.
21461                     procState = ActivityManager.PROCESS_STATE_TOP;
21462                     app.adjType = mayBeTopType;
21463                     app.adjSource = mayBeTopSource;
21464                     app.adjTarget = mayBeTopTarget;
21465                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21466                             + ": " + app + ", due to " + mayBeTopSource
21467                             + " adj=" + adj + " procState=" + procState);
21468                     break;
21469             }
21470         }
21471
21472         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21473             if (app.hasClientActivities) {
21474                 // This is a cached process, but with client activities.  Mark it so.
21475                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21476                 app.adjType = "cch-client-act";
21477             } else if (app.treatLikeActivity) {
21478                 // This is a cached process, but somebody wants us to treat it like it has
21479                 // an activity, okay!
21480                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21481                 app.adjType = "cch-as-act";
21482             }
21483         }
21484
21485         if (adj == ProcessList.SERVICE_ADJ) {
21486             if (doingAll) {
21487                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21488                 mNewNumServiceProcs++;
21489                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21490                 if (!app.serviceb) {
21491                     // This service isn't far enough down on the LRU list to
21492                     // normally be a B service, but if we are low on RAM and it
21493                     // is large we want to force it down since we would prefer to
21494                     // keep launcher over it.
21495                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21496                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21497                         app.serviceHighRam = true;
21498                         app.serviceb = true;
21499                         //Slog.i(TAG, "ADJ " + app + " high ram!");
21500                     } else {
21501                         mNewNumAServiceProcs++;
21502                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
21503                     }
21504                 } else {
21505                     app.serviceHighRam = false;
21506                 }
21507             }
21508             if (app.serviceb) {
21509                 adj = ProcessList.SERVICE_B_ADJ;
21510             }
21511         }
21512
21513         app.curRawAdj = adj;
21514
21515         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21516         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21517         if (adj > app.maxAdj) {
21518             adj = app.maxAdj;
21519             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21520                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21521             }
21522         }
21523
21524         // Do final modification to adj.  Everything we do between here and applying
21525         // the final setAdj must be done in this function, because we will also use
21526         // it when computing the final cached adj later.  Note that we don't need to
21527         // worry about this for max adj above, since max adj will always be used to
21528         // keep it out of the cached vaues.
21529         app.curAdj = app.modifyRawOomAdj(adj);
21530         app.curSchedGroup = schedGroup;
21531         app.curProcState = procState;
21532         app.foregroundActivities = foregroundActivities;
21533
21534         return app.curRawAdj;
21535     }
21536
21537     /**
21538      * Record new PSS sample for a process.
21539      */
21540     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21541             long now) {
21542         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21543                 swapPss * 1024);
21544         proc.lastPssTime = now;
21545         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21546         if (DEBUG_PSS) Slog.d(TAG_PSS,
21547                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21548                 + " state=" + ProcessList.makeProcStateString(procState));
21549         if (proc.initialIdlePss == 0) {
21550             proc.initialIdlePss = pss;
21551         }
21552         proc.lastPss = pss;
21553         proc.lastSwapPss = swapPss;
21554         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21555             proc.lastCachedPss = pss;
21556             proc.lastCachedSwapPss = swapPss;
21557         }
21558
21559         final SparseArray<Pair<Long, String>> watchUids
21560                 = mMemWatchProcesses.getMap().get(proc.processName);
21561         Long check = null;
21562         if (watchUids != null) {
21563             Pair<Long, String> val = watchUids.get(proc.uid);
21564             if (val == null) {
21565                 val = watchUids.get(0);
21566             }
21567             if (val != null) {
21568                 check = val.first;
21569             }
21570         }
21571         if (check != null) {
21572             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21573                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21574                 if (!isDebuggable) {
21575                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21576                         isDebuggable = true;
21577                     }
21578                 }
21579                 if (isDebuggable) {
21580                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21581                     final ProcessRecord myProc = proc;
21582                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
21583                     mMemWatchDumpProcName = proc.processName;
21584                     mMemWatchDumpFile = heapdumpFile.toString();
21585                     mMemWatchDumpPid = proc.pid;
21586                     mMemWatchDumpUid = proc.uid;
21587                     BackgroundThread.getHandler().post(new Runnable() {
21588                         @Override
21589                         public void run() {
21590                             revokeUriPermission(ActivityThread.currentActivityThread()
21591                                             .getApplicationThread(),
21592                                     null, DumpHeapActivity.JAVA_URI,
21593                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
21594                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21595                                     UserHandle.myUserId());
21596                             ParcelFileDescriptor fd = null;
21597                             try {
21598                                 heapdumpFile.delete();
21599                                 fd = ParcelFileDescriptor.open(heapdumpFile,
21600                                         ParcelFileDescriptor.MODE_CREATE |
21601                                                 ParcelFileDescriptor.MODE_TRUNCATE |
21602                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
21603                                                 ParcelFileDescriptor.MODE_APPEND);
21604                                 IApplicationThread thread = myProc.thread;
21605                                 if (thread != null) {
21606                                     try {
21607                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
21608                                                 "Requesting dump heap from "
21609                                                 + myProc + " to " + heapdumpFile);
21610                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
21611                                     } catch (RemoteException e) {
21612                                     }
21613                                 }
21614                             } catch (FileNotFoundException e) {
21615                                 e.printStackTrace();
21616                             } finally {
21617                                 if (fd != null) {
21618                                     try {
21619                                         fd.close();
21620                                     } catch (IOException e) {
21621                                     }
21622                                 }
21623                             }
21624                         }
21625                     });
21626                 } else {
21627                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21628                             + ", but debugging not enabled");
21629                 }
21630             }
21631         }
21632     }
21633
21634     /**
21635      * Schedule PSS collection of a process.
21636      */
21637     void requestPssLocked(ProcessRecord proc, int procState) {
21638         if (mPendingPssProcesses.contains(proc)) {
21639             return;
21640         }
21641         if (mPendingPssProcesses.size() == 0) {
21642             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21643         }
21644         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21645         proc.pssProcState = procState;
21646         mPendingPssProcesses.add(proc);
21647     }
21648
21649     /**
21650      * Schedule PSS collection of all processes.
21651      */
21652     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21653         if (!always) {
21654             if (now < (mLastFullPssTime +
21655                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21656                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
21657                 return;
21658             }
21659         }
21660         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21661         mLastFullPssTime = now;
21662         mFullPssPending = true;
21663         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21664         mPendingPssProcesses.clear();
21665         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21666             ProcessRecord app = mLruProcesses.get(i);
21667             if (app.thread == null
21668                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21669                 continue;
21670             }
21671             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21672                 app.pssProcState = app.setProcState;
21673                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21674                         mTestPssMode, isSleepingLocked(), now);
21675                 mPendingPssProcesses.add(app);
21676             }
21677         }
21678         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21679     }
21680
21681     public void setTestPssMode(boolean enabled) {
21682         synchronized (this) {
21683             mTestPssMode = enabled;
21684             if (enabled) {
21685                 // Whenever we enable the mode, we want to take a snapshot all of current
21686                 // process mem use.
21687                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21688             }
21689         }
21690     }
21691
21692     /**
21693      * Ask a given process to GC right now.
21694      */
21695     final void performAppGcLocked(ProcessRecord app) {
21696         try {
21697             app.lastRequestedGc = SystemClock.uptimeMillis();
21698             if (app.thread != null) {
21699                 if (app.reportLowMemory) {
21700                     app.reportLowMemory = false;
21701                     app.thread.scheduleLowMemory();
21702                 } else {
21703                     app.thread.processInBackground();
21704                 }
21705             }
21706         } catch (Exception e) {
21707             // whatever.
21708         }
21709     }
21710
21711     /**
21712      * Returns true if things are idle enough to perform GCs.
21713      */
21714     private final boolean canGcNowLocked() {
21715         boolean processingBroadcasts = false;
21716         for (BroadcastQueue q : mBroadcastQueues) {
21717             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21718                 processingBroadcasts = true;
21719             }
21720         }
21721         return !processingBroadcasts
21722                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21723     }
21724
21725     /**
21726      * Perform GCs on all processes that are waiting for it, but only
21727      * if things are idle.
21728      */
21729     final void performAppGcsLocked() {
21730         final int N = mProcessesToGc.size();
21731         if (N <= 0) {
21732             return;
21733         }
21734         if (canGcNowLocked()) {
21735             while (mProcessesToGc.size() > 0) {
21736                 ProcessRecord proc = mProcessesToGc.remove(0);
21737                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21738                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21739                             <= SystemClock.uptimeMillis()) {
21740                         // To avoid spamming the system, we will GC processes one
21741                         // at a time, waiting a few seconds between each.
21742                         performAppGcLocked(proc);
21743                         scheduleAppGcsLocked();
21744                         return;
21745                     } else {
21746                         // It hasn't been long enough since we last GCed this
21747                         // process...  put it in the list to wait for its time.
21748                         addProcessToGcListLocked(proc);
21749                         break;
21750                     }
21751                 }
21752             }
21753
21754             scheduleAppGcsLocked();
21755         }
21756     }
21757
21758     /**
21759      * If all looks good, perform GCs on all processes waiting for them.
21760      */
21761     final void performAppGcsIfAppropriateLocked() {
21762         if (canGcNowLocked()) {
21763             performAppGcsLocked();
21764             return;
21765         }
21766         // Still not idle, wait some more.
21767         scheduleAppGcsLocked();
21768     }
21769
21770     /**
21771      * Schedule the execution of all pending app GCs.
21772      */
21773     final void scheduleAppGcsLocked() {
21774         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21775
21776         if (mProcessesToGc.size() > 0) {
21777             // Schedule a GC for the time to the next process.
21778             ProcessRecord proc = mProcessesToGc.get(0);
21779             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21780
21781             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21782             long now = SystemClock.uptimeMillis();
21783             if (when < (now+mConstants.GC_TIMEOUT)) {
21784                 when = now + mConstants.GC_TIMEOUT;
21785             }
21786             mHandler.sendMessageAtTime(msg, when);
21787         }
21788     }
21789
21790     /**
21791      * Add a process to the array of processes waiting to be GCed.  Keeps the
21792      * list in sorted order by the last GC time.  The process can't already be
21793      * on the list.
21794      */
21795     final void addProcessToGcListLocked(ProcessRecord proc) {
21796         boolean added = false;
21797         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21798             if (mProcessesToGc.get(i).lastRequestedGc <
21799                     proc.lastRequestedGc) {
21800                 added = true;
21801                 mProcessesToGc.add(i+1, proc);
21802                 break;
21803             }
21804         }
21805         if (!added) {
21806             mProcessesToGc.add(0, proc);
21807         }
21808     }
21809
21810     /**
21811      * Set up to ask a process to GC itself.  This will either do it
21812      * immediately, or put it on the list of processes to gc the next
21813      * time things are idle.
21814      */
21815     final void scheduleAppGcLocked(ProcessRecord app) {
21816         long now = SystemClock.uptimeMillis();
21817         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21818             return;
21819         }
21820         if (!mProcessesToGc.contains(app)) {
21821             addProcessToGcListLocked(app);
21822             scheduleAppGcsLocked();
21823         }
21824     }
21825
21826     final void checkExcessivePowerUsageLocked(boolean doKills) {
21827         updateCpuStatsNow();
21828
21829         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21830         boolean doWakeKills = doKills;
21831         boolean doCpuKills = doKills;
21832         if (mLastPowerCheckRealtime == 0) {
21833             doWakeKills = false;
21834         }
21835         if (mLastPowerCheckUptime == 0) {
21836             doCpuKills = false;
21837         }
21838         if (stats.isScreenOn()) {
21839             doWakeKills = false;
21840         }
21841         final long curRealtime = SystemClock.elapsedRealtime();
21842         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21843         final long curUptime = SystemClock.uptimeMillis();
21844         final long uptimeSince = curUptime - mLastPowerCheckUptime;
21845         mLastPowerCheckRealtime = curRealtime;
21846         mLastPowerCheckUptime = curUptime;
21847         if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
21848             doWakeKills = false;
21849         }
21850         if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
21851             doCpuKills = false;
21852         }
21853         int i = mLruProcesses.size();
21854         while (i > 0) {
21855             i--;
21856             ProcessRecord app = mLruProcesses.get(i);
21857             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21858                 long wtime;
21859                 synchronized (stats) {
21860                     wtime = stats.getProcessWakeTime(app.info.uid,
21861                             app.pid, curRealtime);
21862                 }
21863                 long wtimeUsed = wtime - app.lastWakeTime;
21864                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21865                 if (DEBUG_POWER) {
21866                     StringBuilder sb = new StringBuilder(128);
21867                     sb.append("Wake for ");
21868                     app.toShortString(sb);
21869                     sb.append(": over ");
21870                     TimeUtils.formatDuration(realtimeSince, sb);
21871                     sb.append(" used ");
21872                     TimeUtils.formatDuration(wtimeUsed, sb);
21873                     sb.append(" (");
21874                     sb.append((wtimeUsed*100)/realtimeSince);
21875                     sb.append("%)");
21876                     Slog.i(TAG_POWER, sb.toString());
21877                     sb.setLength(0);
21878                     sb.append("CPU for ");
21879                     app.toShortString(sb);
21880                     sb.append(": over ");
21881                     TimeUtils.formatDuration(uptimeSince, sb);
21882                     sb.append(" used ");
21883                     TimeUtils.formatDuration(cputimeUsed, sb);
21884                     sb.append(" (");
21885                     sb.append((cputimeUsed*100)/uptimeSince);
21886                     sb.append("%)");
21887                     Slog.i(TAG_POWER, sb.toString());
21888                 }
21889                 // If a process has held a wake lock for more
21890                 // than 50% of the time during this period,
21891                 // that sounds bad.  Kill!
21892                 if (doWakeKills && realtimeSince > 0
21893                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
21894                     synchronized (stats) {
21895                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21896                                 realtimeSince, wtimeUsed);
21897                     }
21898                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21899                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21900                 } else if (doCpuKills && uptimeSince > 0
21901                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
21902                     synchronized (stats) {
21903                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21904                                 uptimeSince, cputimeUsed);
21905                     }
21906                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21907                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21908                 } else {
21909                     app.lastWakeTime = wtime;
21910                     app.lastCpuTime = app.curCpuTime;
21911                 }
21912             }
21913         }
21914     }
21915
21916     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21917             long nowElapsed) {
21918         boolean success = true;
21919
21920         if (app.curRawAdj != app.setRawAdj) {
21921             app.setRawAdj = app.curRawAdj;
21922         }
21923
21924         int changes = 0;
21925
21926         if (app.curAdj != app.setAdj) {
21927             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21928             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21929                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21930                     + app.adjType);
21931             app.setAdj = app.curAdj;
21932             app.verifiedAdj = ProcessList.INVALID_ADJ;
21933         }
21934
21935         if (app.setSchedGroup != app.curSchedGroup) {
21936             int oldSchedGroup = app.setSchedGroup;
21937             app.setSchedGroup = app.curSchedGroup;
21938             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21939                     "Setting sched group of " + app.processName
21940                     + " to " + app.curSchedGroup);
21941             if (app.waitingToKill != null && app.curReceivers.isEmpty()
21942                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21943                 app.kill(app.waitingToKill, true);
21944                 success = false;
21945             } else {
21946                 int processGroup;
21947                 switch (app.curSchedGroup) {
21948                     case ProcessList.SCHED_GROUP_BACKGROUND:
21949                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21950                         break;
21951                     case ProcessList.SCHED_GROUP_TOP_APP:
21952                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21953                         processGroup = THREAD_GROUP_TOP_APP;
21954                         break;
21955                     default:
21956                         processGroup = THREAD_GROUP_DEFAULT;
21957                         break;
21958                 }
21959                 long oldId = Binder.clearCallingIdentity();
21960                 try {
21961                     setProcessGroup(app.pid, processGroup);
21962                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21963                         // do nothing if we already switched to RT
21964                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21965                             mVrController.onTopProcChangedLocked(app);
21966                             if (mUseFifoUiScheduling) {
21967                                 // Switch UI pipeline for app to SCHED_FIFO
21968                                 app.savedPriority = Process.getThreadPriority(app.pid);
21969                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
21970                                 if (app.renderThreadTid != 0) {
21971                                     scheduleAsFifoPriority(app.renderThreadTid,
21972                                         /* suppressLogs */true);
21973                                     if (DEBUG_OOM_ADJ) {
21974                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
21975                                             app.renderThreadTid + ") to FIFO");
21976                                     }
21977                                 } else {
21978                                     if (DEBUG_OOM_ADJ) {
21979                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
21980                                     }
21981                                 }
21982                             } else {
21983                                 // Boost priority for top app UI and render threads
21984                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
21985                                 if (app.renderThreadTid != 0) {
21986                                     try {
21987                                         setThreadPriority(app.renderThreadTid,
21988                                                 TOP_APP_PRIORITY_BOOST);
21989                                     } catch (IllegalArgumentException e) {
21990                                         // thread died, ignore
21991                                     }
21992                                 }
21993                             }
21994                         }
21995                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21996                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21997                         mVrController.onTopProcChangedLocked(app);
21998                         if (mUseFifoUiScheduling) {
21999                             // Reset UI pipeline to SCHED_OTHER
22000                             setThreadScheduler(app.pid, SCHED_OTHER, 0);
22001                             setThreadPriority(app.pid, app.savedPriority);
22002                             if (app.renderThreadTid != 0) {
22003                                 setThreadScheduler(app.renderThreadTid,
22004                                     SCHED_OTHER, 0);
22005                                 setThreadPriority(app.renderThreadTid, -4);
22006                             }
22007                         } else {
22008                             // Reset priority for top app UI and render threads
22009                             setThreadPriority(app.pid, 0);
22010                             if (app.renderThreadTid != 0) {
22011                                 setThreadPriority(app.renderThreadTid, 0);
22012                             }
22013                         }
22014                     }
22015                 } catch (Exception e) {
22016                     if (false) {
22017                         Slog.w(TAG, "Failed setting process group of " + app.pid
22018                                 + " to " + app.curSchedGroup);
22019                         Slog.w(TAG, "at location", e);
22020                     }
22021                 } finally {
22022                     Binder.restoreCallingIdentity(oldId);
22023                 }
22024             }
22025         }
22026         if (app.repForegroundActivities != app.foregroundActivities) {
22027             app.repForegroundActivities = app.foregroundActivities;
22028             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22029         }
22030         if (app.repProcState != app.curProcState) {
22031             app.repProcState = app.curProcState;
22032             if (app.thread != null) {
22033                 try {
22034                     if (false) {
22035                         //RuntimeException h = new RuntimeException("here");
22036                         Slog.i(TAG, "Sending new process state " + app.repProcState
22037                                 + " to " + app /*, h*/);
22038                     }
22039                     app.thread.setProcessState(app.repProcState);
22040                 } catch (RemoteException e) {
22041                 }
22042             }
22043         }
22044         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22045                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22046             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22047                 // Experimental code to more aggressively collect pss while
22048                 // running test...  the problem is that this tends to collect
22049                 // the data right when a process is transitioning between process
22050                 // states, which well tend to give noisy data.
22051                 long start = SystemClock.uptimeMillis();
22052                 long pss = Debug.getPss(app.pid, mTmpLong, null);
22053                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22054                 mPendingPssProcesses.remove(app);
22055                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22056                         + " to " + app.curProcState + ": "
22057                         + (SystemClock.uptimeMillis()-start) + "ms");
22058             }
22059             app.lastStateTime = now;
22060             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22061                     mTestPssMode, isSleepingLocked(), now);
22062             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22063                     + ProcessList.makeProcStateString(app.setProcState) + " to "
22064                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22065                     + (app.nextPssTime-now) + ": " + app);
22066         } else {
22067             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22068                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22069                     mTestPssMode)))) {
22070                 requestPssLocked(app, app.setProcState);
22071                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22072                         mTestPssMode, isSleepingLocked(), now);
22073             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22074                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22075         }
22076         if (app.setProcState != app.curProcState) {
22077             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22078                     "Proc state change of " + app.processName
22079                             + " to " + app.curProcState);
22080             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22081             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22082             if (setImportant && !curImportant) {
22083                 // This app is no longer something we consider important enough to allow to
22084                 // use arbitrary amounts of battery power.  Note
22085                 // its current wake lock time to later know to kill it if
22086                 // it is not behaving well.
22087                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22088                 synchronized (stats) {
22089                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
22090                             app.pid, nowElapsed);
22091                 }
22092                 app.lastCpuTime = app.curCpuTime;
22093
22094             }
22095             // Inform UsageStats of important process state change
22096             // Must be called before updating setProcState
22097             maybeUpdateUsageStatsLocked(app, nowElapsed);
22098
22099             app.setProcState = app.curProcState;
22100             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22101                 app.notCachedSinceIdle = false;
22102             }
22103             if (!doingAll) {
22104                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22105             } else {
22106                 app.procStateChanged = true;
22107             }
22108         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22109                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22110             // For apps that sit around for a long time in the interactive state, we need
22111             // to report this at least once a day so they don't go idle.
22112             maybeUpdateUsageStatsLocked(app, nowElapsed);
22113         }
22114
22115         if (changes != 0) {
22116             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22117                     "Changes in " + app + ": " + changes);
22118             int i = mPendingProcessChanges.size()-1;
22119             ProcessChangeItem item = null;
22120             while (i >= 0) {
22121                 item = mPendingProcessChanges.get(i);
22122                 if (item.pid == app.pid) {
22123                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22124                             "Re-using existing item: " + item);
22125                     break;
22126                 }
22127                 i--;
22128             }
22129             if (i < 0) {
22130                 // No existing item in pending changes; need a new one.
22131                 final int NA = mAvailProcessChanges.size();
22132                 if (NA > 0) {
22133                     item = mAvailProcessChanges.remove(NA-1);
22134                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22135                             "Retrieving available item: " + item);
22136                 } else {
22137                     item = new ProcessChangeItem();
22138                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22139                             "Allocating new item: " + item);
22140                 }
22141                 item.changes = 0;
22142                 item.pid = app.pid;
22143                 item.uid = app.info.uid;
22144                 if (mPendingProcessChanges.size() == 0) {
22145                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22146                             "*** Enqueueing dispatch processes changed!");
22147                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22148                 }
22149                 mPendingProcessChanges.add(item);
22150             }
22151             item.changes |= changes;
22152             item.foregroundActivities = app.repForegroundActivities;
22153             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22154                     "Item " + Integer.toHexString(System.identityHashCode(item))
22155                     + " " + app.toShortString() + ": changes=" + item.changes
22156                     + " foreground=" + item.foregroundActivities
22157                     + " type=" + app.adjType + " source=" + app.adjSource
22158                     + " target=" + app.adjTarget);
22159         }
22160
22161         return success;
22162     }
22163
22164     private boolean isEphemeralLocked(int uid) {
22165         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22166         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22167             return false;
22168         }
22169         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22170                 packages[0]);
22171     }
22172
22173     @VisibleForTesting
22174     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22175         final UidRecord.ChangeItem pendingChange;
22176         if (uidRec == null || uidRec.pendingChange == null) {
22177             if (mPendingUidChanges.size() == 0) {
22178                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22179                         "*** Enqueueing dispatch uid changed!");
22180                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22181             }
22182             final int NA = mAvailUidChanges.size();
22183             if (NA > 0) {
22184                 pendingChange = mAvailUidChanges.remove(NA-1);
22185                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22186                         "Retrieving available item: " + pendingChange);
22187             } else {
22188                 pendingChange = new UidRecord.ChangeItem();
22189                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22190                         "Allocating new item: " + pendingChange);
22191             }
22192             if (uidRec != null) {
22193                 uidRec.pendingChange = pendingChange;
22194                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
22195                     // If this uid is going away, and we haven't yet reported it is gone,
22196                     // then do so now.
22197                     change = UidRecord.CHANGE_GONE_IDLE;
22198                 }
22199             } else if (uid < 0) {
22200                 throw new IllegalArgumentException("No UidRecord or uid");
22201             }
22202             pendingChange.uidRecord = uidRec;
22203             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22204             mPendingUidChanges.add(pendingChange);
22205         } else {
22206             pendingChange = uidRec.pendingChange;
22207             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
22208                 change = UidRecord.CHANGE_GONE_IDLE;
22209             }
22210         }
22211         pendingChange.change = change;
22212         pendingChange.processState = uidRec != null
22213                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22214         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22215         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22216         if (uidRec != null) {
22217             uidRec.updateLastDispatchedProcStateSeq(change);
22218         }
22219
22220         // Directly update the power manager, since we sit on top of it and it is critical
22221         // it be kept in sync (so wake locks will be held as soon as appropriate).
22222         if (mLocalPowerManager != null) {
22223             switch (change) {
22224                 case UidRecord.CHANGE_GONE:
22225                 case UidRecord.CHANGE_GONE_IDLE:
22226                     mLocalPowerManager.uidGone(pendingChange.uid);
22227                     break;
22228                 case UidRecord.CHANGE_IDLE:
22229                     mLocalPowerManager.uidIdle(pendingChange.uid);
22230                     break;
22231                 case UidRecord.CHANGE_ACTIVE:
22232                     mLocalPowerManager.uidActive(pendingChange.uid);
22233                     break;
22234                 default:
22235                     mLocalPowerManager.updateUidProcState(pendingChange.uid,
22236                             pendingChange.processState);
22237                     break;
22238             }
22239         }
22240     }
22241
22242     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22243             String authority) {
22244         if (app == null) return;
22245         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22246             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22247             if (userState == null) return;
22248             final long now = SystemClock.elapsedRealtime();
22249             Long lastReported = userState.mProviderLastReportedFg.get(authority);
22250             if (lastReported == null || lastReported < now - 60 * 1000L) {
22251                 if (mSystemReady) {
22252                     // Cannot touch the user stats if not system ready
22253                     mUsageStatsService.reportContentProviderUsage(
22254                             authority, providerPkgName, app.userId);
22255                 }
22256                 userState.mProviderLastReportedFg.put(authority, now);
22257             }
22258         }
22259     }
22260
22261     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22262         if (DEBUG_USAGE_STATS) {
22263             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22264                     + "] state changes: old = " + app.setProcState + ", new = "
22265                     + app.curProcState);
22266         }
22267         if (mUsageStatsService == null) {
22268             return;
22269         }
22270         boolean isInteraction;
22271         // To avoid some abuse patterns, we are going to be careful about what we consider
22272         // to be an app interaction.  Being the top activity doesn't count while the display
22273         // is sleeping, nor do short foreground services.
22274         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22275             isInteraction = true;
22276             app.fgInteractionTime = 0;
22277         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22278             if (app.fgInteractionTime == 0) {
22279                 app.fgInteractionTime = nowElapsed;
22280                 isInteraction = false;
22281             } else {
22282                 isInteraction = nowElapsed > app.fgInteractionTime
22283                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22284             }
22285         } else {
22286             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22287             app.fgInteractionTime = 0;
22288         }
22289         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22290                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22291             app.interactionEventTime = nowElapsed;
22292             String[] packages = app.getPackageList();
22293             if (packages != null) {
22294                 for (int i = 0; i < packages.length; i++) {
22295                     mUsageStatsService.reportEvent(packages[i], app.userId,
22296                             UsageEvents.Event.SYSTEM_INTERACTION);
22297                 }
22298             }
22299         }
22300         app.reportedInteraction = isInteraction;
22301         if (!isInteraction) {
22302             app.interactionEventTime = 0;
22303         }
22304     }
22305
22306     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22307         if (proc.thread != null) {
22308             if (proc.baseProcessTracker != null) {
22309                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22310             }
22311         }
22312     }
22313
22314     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22315             ProcessRecord TOP_APP, boolean doingAll, long now) {
22316         if (app.thread == null) {
22317             return false;
22318         }
22319
22320         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22321
22322         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22323     }
22324
22325     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22326             boolean oomAdj) {
22327         if (isForeground != proc.foregroundServices) {
22328             proc.foregroundServices = isForeground;
22329             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22330                     proc.info.uid);
22331             if (isForeground) {
22332                 if (curProcs == null) {
22333                     curProcs = new ArrayList<ProcessRecord>();
22334                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22335                 }
22336                 if (!curProcs.contains(proc)) {
22337                     curProcs.add(proc);
22338                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22339                             proc.info.packageName, proc.info.uid);
22340                 }
22341             } else {
22342                 if (curProcs != null) {
22343                     if (curProcs.remove(proc)) {
22344                         mBatteryStatsService.noteEvent(
22345                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22346                                 proc.info.packageName, proc.info.uid);
22347                         if (curProcs.size() <= 0) {
22348                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22349                         }
22350                     }
22351                 }
22352             }
22353             if (oomAdj) {
22354                 updateOomAdjLocked();
22355             }
22356         }
22357     }
22358
22359     private final ActivityRecord resumedAppLocked() {
22360         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22361         String pkg;
22362         int uid;
22363         if (act != null) {
22364             pkg = act.packageName;
22365             uid = act.info.applicationInfo.uid;
22366         } else {
22367             pkg = null;
22368             uid = -1;
22369         }
22370         // Has the UID or resumed package name changed?
22371         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22372                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22373             if (mCurResumedPackage != null) {
22374                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22375                         mCurResumedPackage, mCurResumedUid);
22376             }
22377             mCurResumedPackage = pkg;
22378             mCurResumedUid = uid;
22379             if (mCurResumedPackage != null) {
22380                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22381                         mCurResumedPackage, mCurResumedUid);
22382             }
22383         }
22384         return act;
22385     }
22386
22387     /**
22388      * Update OomAdj for a specific process.
22389      * @param app The process to update
22390      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22391      *                  if necessary, or skip.
22392      * @return whether updateOomAdjLocked(app) was successful.
22393      */
22394     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22395         final ActivityRecord TOP_ACT = resumedAppLocked();
22396         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22397         final boolean wasCached = app.cached;
22398
22399         mAdjSeq++;
22400
22401         // This is the desired cached adjusment we want to tell it to use.
22402         // If our app is currently cached, we know it, and that is it.  Otherwise,
22403         // we don't know it yet, and it needs to now be cached we will then
22404         // need to do a complete oom adj.
22405         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22406                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22407         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22408                 SystemClock.uptimeMillis());
22409         if (oomAdjAll
22410                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22411             // Changed to/from cached state, so apps after it in the LRU
22412             // list may also be changed.
22413             updateOomAdjLocked();
22414         }
22415         return success;
22416     }
22417
22418     final void updateOomAdjLocked() {
22419         final ActivityRecord TOP_ACT = resumedAppLocked();
22420         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22421         final long now = SystemClock.uptimeMillis();
22422         final long nowElapsed = SystemClock.elapsedRealtime();
22423         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22424         final int N = mLruProcesses.size();
22425
22426         if (false) {
22427             RuntimeException e = new RuntimeException();
22428             e.fillInStackTrace();
22429             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22430         }
22431
22432         // Reset state in all uid records.
22433         for (int i=mActiveUids.size()-1; i>=0; i--) {
22434             final UidRecord uidRec = mActiveUids.valueAt(i);
22435             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22436                     "Starting update of " + uidRec);
22437             uidRec.reset();
22438         }
22439
22440         mStackSupervisor.rankTaskLayersIfNeeded();
22441
22442         mAdjSeq++;
22443         mNewNumServiceProcs = 0;
22444         mNewNumAServiceProcs = 0;
22445
22446         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22447         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22448
22449         // Let's determine how many processes we have running vs.
22450         // how many slots we have for background processes; we may want
22451         // to put multiple processes in a slot of there are enough of
22452         // them.
22453         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22454                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22455         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22456         if (numEmptyProcs > cachedProcessLimit) {
22457             // If there are more empty processes than our limit on cached
22458             // processes, then use the cached process limit for the factor.
22459             // This ensures that the really old empty processes get pushed
22460             // down to the bottom, so if we are running low on memory we will
22461             // have a better chance at keeping around more cached processes
22462             // instead of a gazillion empty processes.
22463             numEmptyProcs = cachedProcessLimit;
22464         }
22465         int emptyFactor = numEmptyProcs/numSlots;
22466         if (emptyFactor < 1) emptyFactor = 1;
22467         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22468         if (cachedFactor < 1) cachedFactor = 1;
22469         int stepCached = 0;
22470         int stepEmpty = 0;
22471         int numCached = 0;
22472         int numEmpty = 0;
22473         int numTrimming = 0;
22474
22475         mNumNonCachedProcs = 0;
22476         mNumCachedHiddenProcs = 0;
22477
22478         // First update the OOM adjustment for each of the
22479         // application processes based on their current state.
22480         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22481         int nextCachedAdj = curCachedAdj+1;
22482         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22483         int nextEmptyAdj = curEmptyAdj+2;
22484         for (int i=N-1; i>=0; i--) {
22485             ProcessRecord app = mLruProcesses.get(i);
22486             if (!app.killedByAm && app.thread != null) {
22487                 app.procStateChanged = false;
22488                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22489
22490                 // If we haven't yet assigned the final cached adj
22491                 // to the process, do that now.
22492                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22493                     switch (app.curProcState) {
22494                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22495                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22496                             // This process is a cached process holding activities...
22497                             // assign it the next cached value for that type, and then
22498                             // step that cached level.
22499                             app.curRawAdj = curCachedAdj;
22500                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22501                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22502                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22503                                     + ")");
22504                             if (curCachedAdj != nextCachedAdj) {
22505                                 stepCached++;
22506                                 if (stepCached >= cachedFactor) {
22507                                     stepCached = 0;
22508                                     curCachedAdj = nextCachedAdj;
22509                                     nextCachedAdj += 2;
22510                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22511                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22512                                     }
22513                                 }
22514                             }
22515                             break;
22516                         default:
22517                             // For everything else, assign next empty cached process
22518                             // level and bump that up.  Note that this means that
22519                             // long-running services that have dropped down to the
22520                             // cached level will be treated as empty (since their process
22521                             // state is still as a service), which is what we want.
22522                             app.curRawAdj = curEmptyAdj;
22523                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22524                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22525                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22526                                     + ")");
22527                             if (curEmptyAdj != nextEmptyAdj) {
22528                                 stepEmpty++;
22529                                 if (stepEmpty >= emptyFactor) {
22530                                     stepEmpty = 0;
22531                                     curEmptyAdj = nextEmptyAdj;
22532                                     nextEmptyAdj += 2;
22533                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22534                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22535                                     }
22536                                 }
22537                             }
22538                             break;
22539                     }
22540                 }
22541
22542                 applyOomAdjLocked(app, true, now, nowElapsed);
22543
22544                 // Count the number of process types.
22545                 switch (app.curProcState) {
22546                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22547                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22548                         mNumCachedHiddenProcs++;
22549                         numCached++;
22550                         if (numCached > cachedProcessLimit) {
22551                             app.kill("cached #" + numCached, true);
22552                         }
22553                         break;
22554                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22555                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22556                                 && app.lastActivityTime < oldTime) {
22557                             app.kill("empty for "
22558                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22559                                     / 1000) + "s", true);
22560                         } else {
22561                             numEmpty++;
22562                             if (numEmpty > emptyProcessLimit) {
22563                                 app.kill("empty #" + numEmpty, true);
22564                             }
22565                         }
22566                         break;
22567                     default:
22568                         mNumNonCachedProcs++;
22569                         break;
22570                 }
22571
22572                 if (app.isolated && app.services.size() <= 0) {
22573                     // If this is an isolated process, and there are no
22574                     // services running in it, then the process is no longer
22575                     // needed.  We agressively kill these because we can by
22576                     // definition not re-use the same process again, and it is
22577                     // good to avoid having whatever code was running in them
22578                     // left sitting around after no longer needed.
22579                     app.kill("isolated not needed", true);
22580                 } else {
22581                     // Keeping this process, update its uid.
22582                     final UidRecord uidRec = app.uidRecord;
22583                     if (uidRec != null) {
22584                         uidRec.ephemeral = app.info.isInstantApp();
22585                         if (uidRec.curProcState > app.curProcState) {
22586                             uidRec.curProcState = app.curProcState;
22587                         }
22588                         if (app.foregroundServices) {
22589                             uidRec.foregroundServices = true;
22590                         }
22591                     }
22592                 }
22593
22594                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22595                         && !app.killedByAm) {
22596                     numTrimming++;
22597                 }
22598             }
22599         }
22600
22601         incrementProcStateSeqAndNotifyAppsLocked();
22602
22603         mNumServiceProcs = mNewNumServiceProcs;
22604
22605         // Now determine the memory trimming level of background processes.
22606         // Unfortunately we need to start at the back of the list to do this
22607         // properly.  We only do this if the number of background apps we
22608         // are managing to keep around is less than half the maximum we desire;
22609         // if we are keeping a good number around, we'll let them use whatever
22610         // memory they want.
22611         final int numCachedAndEmpty = numCached + numEmpty;
22612         int memFactor;
22613         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22614                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22615             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22616                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22617             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22618                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22619             } else {
22620                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22621             }
22622         } else {
22623             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22624         }
22625         // We always allow the memory level to go up (better).  We only allow it to go
22626         // down if we are in a state where that is allowed, *and* the total number of processes
22627         // has gone down since last time.
22628         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22629                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22630                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22631         if (memFactor > mLastMemoryLevel) {
22632             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22633                 memFactor = mLastMemoryLevel;
22634                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22635             }
22636         }
22637         if (memFactor != mLastMemoryLevel) {
22638             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22639         }
22640         mLastMemoryLevel = memFactor;
22641         mLastNumProcesses = mLruProcesses.size();
22642         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22643         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22644         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22645             if (mLowRamStartTime == 0) {
22646                 mLowRamStartTime = now;
22647             }
22648             int step = 0;
22649             int fgTrimLevel;
22650             switch (memFactor) {
22651                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22652                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22653                     break;
22654                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22655                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22656                     break;
22657                 default:
22658                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22659                     break;
22660             }
22661             int factor = numTrimming/3;
22662             int minFactor = 2;
22663             if (mHomeProcess != null) minFactor++;
22664             if (mPreviousProcess != null) minFactor++;
22665             if (factor < minFactor) factor = minFactor;
22666             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22667             for (int i=N-1; i>=0; i--) {
22668                 ProcessRecord app = mLruProcesses.get(i);
22669                 if (allChanged || app.procStateChanged) {
22670                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22671                     app.procStateChanged = false;
22672                 }
22673                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22674                         && !app.killedByAm) {
22675                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
22676                         try {
22677                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22678                                     "Trimming memory of " + app.processName + " to " + curLevel);
22679                             app.thread.scheduleTrimMemory(curLevel);
22680                         } catch (RemoteException e) {
22681                         }
22682                         if (false) {
22683                             // For now we won't do this; our memory trimming seems
22684                             // to be good enough at this point that destroying
22685                             // activities causes more harm than good.
22686                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22687                                     && app != mHomeProcess && app != mPreviousProcess) {
22688                                 // Need to do this on its own message because the stack may not
22689                                 // be in a consistent state at this point.
22690                                 // For these apps we will also finish their activities
22691                                 // to help them free memory.
22692                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22693                             }
22694                         }
22695                     }
22696                     app.trimMemoryLevel = curLevel;
22697                     step++;
22698                     if (step >= factor) {
22699                         step = 0;
22700                         switch (curLevel) {
22701                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22702                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22703                                 break;
22704                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22705                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22706                                 break;
22707                         }
22708                     }
22709                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22710                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22711                             && app.thread != null) {
22712                         try {
22713                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22714                                     "Trimming memory of heavy-weight " + app.processName
22715                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22716                             app.thread.scheduleTrimMemory(
22717                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22718                         } catch (RemoteException e) {
22719                         }
22720                     }
22721                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22722                 } else {
22723                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22724                             || app.systemNoUi) && app.pendingUiClean) {
22725                         // If this application is now in the background and it
22726                         // had done UI, then give it the special trim level to
22727                         // have it free UI resources.
22728                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22729                         if (app.trimMemoryLevel < level && app.thread != null) {
22730                             try {
22731                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22732                                         "Trimming memory of bg-ui " + app.processName
22733                                         + " to " + level);
22734                                 app.thread.scheduleTrimMemory(level);
22735                             } catch (RemoteException e) {
22736                             }
22737                         }
22738                         app.pendingUiClean = false;
22739                     }
22740                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22741                         try {
22742                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22743                                     "Trimming memory of fg " + app.processName
22744                                     + " to " + fgTrimLevel);
22745                             app.thread.scheduleTrimMemory(fgTrimLevel);
22746                         } catch (RemoteException e) {
22747                         }
22748                     }
22749                     app.trimMemoryLevel = fgTrimLevel;
22750                 }
22751             }
22752         } else {
22753             if (mLowRamStartTime != 0) {
22754                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22755                 mLowRamStartTime = 0;
22756             }
22757             for (int i=N-1; i>=0; i--) {
22758                 ProcessRecord app = mLruProcesses.get(i);
22759                 if (allChanged || app.procStateChanged) {
22760                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22761                     app.procStateChanged = false;
22762                 }
22763                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22764                         || app.systemNoUi) && app.pendingUiClean) {
22765                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22766                             && app.thread != null) {
22767                         try {
22768                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22769                                     "Trimming memory of ui hidden " + app.processName
22770                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22771                             app.thread.scheduleTrimMemory(
22772                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22773                         } catch (RemoteException e) {
22774                         }
22775                     }
22776                     app.pendingUiClean = false;
22777                 }
22778                 app.trimMemoryLevel = 0;
22779             }
22780         }
22781
22782         if (mAlwaysFinishActivities) {
22783             // Need to do this on its own message because the stack may not
22784             // be in a consistent state at this point.
22785             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22786         }
22787
22788         if (allChanged) {
22789             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22790         }
22791
22792         // Update from any uid changes.
22793         if (mLocalPowerManager != null) {
22794             mLocalPowerManager.startUidChanges();
22795         }
22796         for (int i=mActiveUids.size()-1; i>=0; i--) {
22797             final UidRecord uidRec = mActiveUids.valueAt(i);
22798             int uidChange = UidRecord.CHANGE_PROCSTATE;
22799             if (uidRec.setProcState != uidRec.curProcState
22800                     || uidRec.setWhitelist != uidRec.curWhitelist) {
22801                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22802                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22803                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22804                         + " to " + uidRec.curWhitelist);
22805                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22806                         && !uidRec.curWhitelist) {
22807                     // UID is now in the background (and not on the temp whitelist).  Was it
22808                     // previously in the foreground (or on the temp whitelist)?
22809                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22810                             || uidRec.setWhitelist) {
22811                         uidRec.lastBackgroundTime = nowElapsed;
22812                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22813                             // Note: the background settle time is in elapsed realtime, while
22814                             // the handler time base is uptime.  All this means is that we may
22815                             // stop background uids later than we had intended, but that only
22816                             // happens because the device was sleeping so we are okay anyway.
22817                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22818                                     mConstants.BACKGROUND_SETTLE_TIME);
22819                         }
22820                     }
22821                 } else {
22822                     if (uidRec.idle) {
22823                         uidChange = UidRecord.CHANGE_ACTIVE;
22824                         EventLogTags.writeAmUidActive(uidRec.uid);
22825                         uidRec.idle = false;
22826                     }
22827                     uidRec.lastBackgroundTime = 0;
22828                 }
22829                 uidRec.setProcState = uidRec.curProcState;
22830                 uidRec.setWhitelist = uidRec.curWhitelist;
22831                 enqueueUidChangeLocked(uidRec, -1, uidChange);
22832                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22833                 if (uidRec.foregroundServices) {
22834                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
22835                 }
22836             }
22837         }
22838         if (mLocalPowerManager != null) {
22839             mLocalPowerManager.finishUidChanges();
22840         }
22841
22842         if (mProcessStats.shouldWriteNowLocked(now)) {
22843             mHandler.post(new Runnable() {
22844                 @Override public void run() {
22845                     synchronized (ActivityManagerService.this) {
22846                         mProcessStats.writeStateAsyncLocked();
22847                     }
22848                 }
22849             });
22850         }
22851
22852         if (DEBUG_OOM_ADJ) {
22853             final long duration = SystemClock.uptimeMillis() - now;
22854             if (false) {
22855                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22856                         new RuntimeException("here").fillInStackTrace());
22857             } else {
22858                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22859             }
22860         }
22861     }
22862
22863     @Override
22864     public void makePackageIdle(String packageName, int userId) {
22865         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22866                 != PackageManager.PERMISSION_GRANTED) {
22867             String msg = "Permission Denial: makePackageIdle() from pid="
22868                     + Binder.getCallingPid()
22869                     + ", uid=" + Binder.getCallingUid()
22870                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22871             Slog.w(TAG, msg);
22872             throw new SecurityException(msg);
22873         }
22874         final int callingPid = Binder.getCallingPid();
22875         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22876                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22877         long callingId = Binder.clearCallingIdentity();
22878         synchronized(this) {
22879             try {
22880                 IPackageManager pm = AppGlobals.getPackageManager();
22881                 int pkgUid = -1;
22882                 try {
22883                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22884                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22885                 } catch (RemoteException e) {
22886                 }
22887                 if (pkgUid == -1) {
22888                     throw new IllegalArgumentException("Unknown package name " + packageName);
22889                 }
22890
22891                 if (mLocalPowerManager != null) {
22892                     mLocalPowerManager.startUidChanges();
22893                 }
22894                 final int appId = UserHandle.getAppId(pkgUid);
22895                 final int N = mActiveUids.size();
22896                 for (int i=N-1; i>=0; i--) {
22897                     final UidRecord uidRec = mActiveUids.valueAt(i);
22898                     final long bgTime = uidRec.lastBackgroundTime;
22899                     if (bgTime > 0 && !uidRec.idle) {
22900                         if (UserHandle.getAppId(uidRec.uid) == appId) {
22901                             if (userId == UserHandle.USER_ALL ||
22902                                     userId == UserHandle.getUserId(uidRec.uid)) {
22903                                 EventLogTags.writeAmUidIdle(uidRec.uid);
22904                                 uidRec.idle = true;
22905                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22906                                         + " from package " + packageName + " user " + userId);
22907                                 doStopUidLocked(uidRec.uid, uidRec);
22908                             }
22909                         }
22910                     }
22911                 }
22912             } finally {
22913                 if (mLocalPowerManager != null) {
22914                     mLocalPowerManager.finishUidChanges();
22915                 }
22916                 Binder.restoreCallingIdentity(callingId);
22917             }
22918         }
22919     }
22920
22921     final void idleUids() {
22922         synchronized (this) {
22923             final int N = mActiveUids.size();
22924             if (N <= 0) {
22925                 return;
22926             }
22927             final long nowElapsed = SystemClock.elapsedRealtime();
22928             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22929             long nextTime = 0;
22930             if (mLocalPowerManager != null) {
22931                 mLocalPowerManager.startUidChanges();
22932             }
22933             for (int i=N-1; i>=0; i--) {
22934                 final UidRecord uidRec = mActiveUids.valueAt(i);
22935                 final long bgTime = uidRec.lastBackgroundTime;
22936                 if (bgTime > 0 && !uidRec.idle) {
22937                     if (bgTime <= maxBgTime) {
22938                         EventLogTags.writeAmUidIdle(uidRec.uid);
22939                         uidRec.idle = true;
22940                         doStopUidLocked(uidRec.uid, uidRec);
22941                     } else {
22942                         if (nextTime == 0 || nextTime > bgTime) {
22943                             nextTime = bgTime;
22944                         }
22945                     }
22946                 }
22947             }
22948             if (mLocalPowerManager != null) {
22949                 mLocalPowerManager.finishUidChanges();
22950             }
22951             if (nextTime > 0) {
22952                 mHandler.removeMessages(IDLE_UIDS_MSG);
22953                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22954                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
22955             }
22956         }
22957     }
22958
22959     /**
22960      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
22961      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
22962      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
22963      */
22964     @VisibleForTesting
22965     @GuardedBy("this")
22966     void incrementProcStateSeqAndNotifyAppsLocked() {
22967         if (mWaitForNetworkTimeoutMs <= 0) {
22968             return;
22969         }
22970         // Used for identifying which uids need to block for network.
22971         ArrayList<Integer> blockingUids = null;
22972         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
22973             final UidRecord uidRec = mActiveUids.valueAt(i);
22974             // If the network is not restricted for uid, then nothing to do here.
22975             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
22976                 continue;
22977             }
22978             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
22979                 continue;
22980             }
22981             // If process state is not changed, then there's nothing to do.
22982             if (uidRec.setProcState == uidRec.curProcState) {
22983                 continue;
22984             }
22985             final int blockState = getBlockStateForUid(uidRec);
22986             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
22987             // there's nothing the app needs to do in this scenario.
22988             if (blockState == NETWORK_STATE_NO_CHANGE) {
22989                 continue;
22990             }
22991             synchronized (uidRec.networkStateLock) {
22992                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
22993                 if (blockState == NETWORK_STATE_BLOCK) {
22994                     if (blockingUids == null) {
22995                         blockingUids = new ArrayList<>();
22996                     }
22997                     blockingUids.add(uidRec.uid);
22998                 } else {
22999                     if (DEBUG_NETWORK) {
23000                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23001                                 + " threads for uid: " + uidRec);
23002                     }
23003                     if (uidRec.waitingForNetwork) {
23004                         uidRec.networkStateLock.notifyAll();
23005                     }
23006                 }
23007             }
23008         }
23009
23010         // There are no uids that need to block, so nothing more to do.
23011         if (blockingUids == null) {
23012             return;
23013         }
23014
23015         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23016             final ProcessRecord app = mLruProcesses.get(i);
23017             if (!blockingUids.contains(app.uid)) {
23018                 continue;
23019             }
23020             if (!app.killedByAm && app.thread != null) {
23021                 final UidRecord uidRec = mActiveUids.get(app.uid);
23022                 try {
23023                     if (DEBUG_NETWORK) {
23024                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23025                                 + uidRec);
23026                     }
23027                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23028                 } catch (RemoteException ignored) {
23029                 }
23030             }
23031         }
23032     }
23033
23034     /**
23035      * Checks if the uid is coming from background to foreground or vice versa and returns
23036      * appropriate block state based on this.
23037      *
23038      * @return blockState based on whether the uid is coming from background to foreground or
23039      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23040      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23041      *         {@link #NETWORK_STATE_NO_CHANGE}.
23042      */
23043     @VisibleForTesting
23044     int getBlockStateForUid(UidRecord uidRec) {
23045         // Denotes whether uid's process state is currently allowed network access.
23046         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23047                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23048         // Denotes whether uid's process state was previously allowed network access.
23049         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23050                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23051
23052         // When the uid is coming to foreground, AMS should inform the app thread that it should
23053         // block for the network rules to get updated before launching an activity.
23054         if (!wasAllowed && isAllowed) {
23055             return NETWORK_STATE_BLOCK;
23056         }
23057         // When the uid is going to background, AMS should inform the app thread that if an
23058         // activity launch is blocked for the network rules to get updated, it should be unblocked.
23059         if (wasAllowed && !isAllowed) {
23060             return NETWORK_STATE_UNBLOCK;
23061         }
23062         return NETWORK_STATE_NO_CHANGE;
23063     }
23064
23065     final void runInBackgroundDisabled(int uid) {
23066         synchronized (this) {
23067             UidRecord uidRec = mActiveUids.get(uid);
23068             if (uidRec != null) {
23069                 // This uid is actually running...  should it be considered background now?
23070                 if (uidRec.idle) {
23071                     doStopUidLocked(uidRec.uid, uidRec);
23072                 }
23073             } else {
23074                 // This uid isn't actually running...  still send a report about it being "stopped".
23075                 doStopUidLocked(uid, null);
23076             }
23077         }
23078     }
23079
23080     final void doStopUidLocked(int uid, final UidRecord uidRec) {
23081         mServices.stopInBackgroundLocked(uid);
23082         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23083     }
23084
23085     /**
23086      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23087      */
23088     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23089             long duration, String tag) {
23090         if (DEBUG_WHITELISTS) {
23091             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23092                     + targetUid + ", " + duration + ")");
23093         }
23094
23095         synchronized (mPidsSelfLocked) {
23096             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23097             if (pr == null) {
23098                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23099                         + callerPid);
23100                 return;
23101             }
23102             if (!pr.whitelistManager) {
23103                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23104                         != PackageManager.PERMISSION_GRANTED) {
23105                     if (DEBUG_WHITELISTS) {
23106                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23107                                 + ": pid " + callerPid + " is not allowed");
23108                     }
23109                     return;
23110                 }
23111             }
23112         }
23113
23114         tempWhitelistUidLocked(targetUid, duration, tag);
23115     }
23116
23117     /**
23118      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23119      */
23120     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23121         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23122         setUidTempWhitelistStateLocked(targetUid, true);
23123         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23124     }
23125
23126     void pushTempWhitelist() {
23127         final int N;
23128         final PendingTempWhitelist[] list;
23129
23130         // First copy out the pending changes...  we need to leave them in the map for now,
23131         // in case someone needs to check what is coming up while we don't have the lock held.
23132         synchronized(this) {
23133             N = mPendingTempWhitelist.size();
23134             list = new PendingTempWhitelist[N];
23135             for (int i = 0; i < N; i++) {
23136                 list[i] = mPendingTempWhitelist.valueAt(i);
23137             }
23138         }
23139
23140         // Now safely dispatch changes to device idle controller.
23141         for (int i = 0; i < N; i++) {
23142             PendingTempWhitelist ptw = list[i];
23143             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23144                     ptw.duration, true, ptw.tag);
23145         }
23146
23147         // And now we can safely remove them from the map.
23148         synchronized(this) {
23149             for (int i = 0; i < N; i++) {
23150                 PendingTempWhitelist ptw = list[i];
23151                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23152                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23153                     mPendingTempWhitelist.removeAt(index);
23154                 }
23155             }
23156         }
23157     }
23158
23159     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23160         boolean changed = false;
23161         for (int i=mActiveUids.size()-1; i>=0; i--) {
23162             final UidRecord uidRec = mActiveUids.valueAt(i);
23163             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23164                 uidRec.curWhitelist = onWhitelist;
23165                 changed = true;
23166             }
23167         }
23168         if (changed) {
23169             updateOomAdjLocked();
23170         }
23171     }
23172
23173     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23174         boolean changed = false;
23175         final UidRecord uidRec = mActiveUids.get(uid);
23176         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23177             uidRec.curWhitelist = onWhitelist;
23178             updateOomAdjLocked();
23179         }
23180     }
23181
23182     final void trimApplications() {
23183         synchronized (this) {
23184             int i;
23185
23186             // First remove any unused application processes whose package
23187             // has been removed.
23188             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23189                 final ProcessRecord app = mRemovedProcesses.get(i);
23190                 if (app.activities.size() == 0
23191                         && app.curReceivers.isEmpty() && app.services.size() == 0) {
23192                     Slog.i(
23193                         TAG, "Exiting empty application process "
23194                         + app.toShortString() + " ("
23195                         + (app.thread != null ? app.thread.asBinder() : null)
23196                         + ")\n");
23197                     if (app.pid > 0 && app.pid != MY_PID) {
23198                         app.kill("empty", false);
23199                     } else {
23200                         try {
23201                             app.thread.scheduleExit();
23202                         } catch (Exception e) {
23203                             // Ignore exceptions.
23204                         }
23205                     }
23206                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23207                     mRemovedProcesses.remove(i);
23208
23209                     if (app.persistent) {
23210                         addAppLocked(app.info, null, false, null /* ABI override */);
23211                     }
23212                 }
23213             }
23214
23215             // Now update the oom adj for all processes.
23216             updateOomAdjLocked();
23217         }
23218     }
23219
23220     /** This method sends the specified signal to each of the persistent apps */
23221     public void signalPersistentProcesses(int sig) throws RemoteException {
23222         if (sig != SIGNAL_USR1) {
23223             throw new SecurityException("Only SIGNAL_USR1 is allowed");
23224         }
23225
23226         synchronized (this) {
23227             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23228                     != PackageManager.PERMISSION_GRANTED) {
23229                 throw new SecurityException("Requires permission "
23230                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23231             }
23232
23233             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23234                 ProcessRecord r = mLruProcesses.get(i);
23235                 if (r.thread != null && r.persistent) {
23236                     sendSignal(r.pid, sig);
23237                 }
23238             }
23239         }
23240     }
23241
23242     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23243         if (proc == null || proc == mProfileProc) {
23244             proc = mProfileProc;
23245             profileType = mProfileType;
23246             clearProfilerLocked();
23247         }
23248         if (proc == null) {
23249             return;
23250         }
23251         try {
23252             proc.thread.profilerControl(false, null, profileType);
23253         } catch (RemoteException e) {
23254             throw new IllegalStateException("Process disappeared");
23255         }
23256     }
23257
23258     private void clearProfilerLocked() {
23259         if (mProfileFd != null) {
23260             try {
23261                 mProfileFd.close();
23262             } catch (IOException e) {
23263             }
23264         }
23265         mProfileApp = null;
23266         mProfileProc = null;
23267         mProfileFile = null;
23268         mProfileType = 0;
23269         mAutoStopProfiler = false;
23270         mStreamingOutput = false;
23271         mSamplingInterval = 0;
23272     }
23273
23274     public boolean profileControl(String process, int userId, boolean start,
23275             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23276
23277         try {
23278             synchronized (this) {
23279                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23280                 // its own permission.
23281                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23282                         != PackageManager.PERMISSION_GRANTED) {
23283                     throw new SecurityException("Requires permission "
23284                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23285                 }
23286
23287                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23288                     throw new IllegalArgumentException("null profile info or fd");
23289                 }
23290
23291                 ProcessRecord proc = null;
23292                 if (process != null) {
23293                     proc = findProcessLocked(process, userId, "profileControl");
23294                 }
23295
23296                 if (start && (proc == null || proc.thread == null)) {
23297                     throw new IllegalArgumentException("Unknown process: " + process);
23298                 }
23299
23300                 if (start) {
23301                     stopProfilerLocked(null, 0);
23302                     setProfileApp(proc.info, proc.processName, profilerInfo);
23303                     mProfileProc = proc;
23304                     mProfileType = profileType;
23305                     ParcelFileDescriptor fd = profilerInfo.profileFd;
23306                     try {
23307                         fd = fd.dup();
23308                     } catch (IOException e) {
23309                         fd = null;
23310                     }
23311                     profilerInfo.profileFd = fd;
23312                     proc.thread.profilerControl(start, profilerInfo, profileType);
23313                     fd = null;
23314                     try {
23315                         mProfileFd.close();
23316                     } catch (IOException e) {
23317                     }
23318                     mProfileFd = null;
23319                 } else {
23320                     stopProfilerLocked(proc, profileType);
23321                     if (profilerInfo != null && profilerInfo.profileFd != null) {
23322                         try {
23323                             profilerInfo.profileFd.close();
23324                         } catch (IOException e) {
23325                         }
23326                     }
23327                 }
23328
23329                 return true;
23330             }
23331         } catch (RemoteException e) {
23332             throw new IllegalStateException("Process disappeared");
23333         } finally {
23334             if (profilerInfo != null && profilerInfo.profileFd != null) {
23335                 try {
23336                     profilerInfo.profileFd.close();
23337                 } catch (IOException e) {
23338                 }
23339             }
23340         }
23341     }
23342
23343     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23344         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23345                 userId, true, ALLOW_FULL_ONLY, callName, null);
23346         ProcessRecord proc = null;
23347         try {
23348             int pid = Integer.parseInt(process);
23349             synchronized (mPidsSelfLocked) {
23350                 proc = mPidsSelfLocked.get(pid);
23351             }
23352         } catch (NumberFormatException e) {
23353         }
23354
23355         if (proc == null) {
23356             ArrayMap<String, SparseArray<ProcessRecord>> all
23357                     = mProcessNames.getMap();
23358             SparseArray<ProcessRecord> procs = all.get(process);
23359             if (procs != null && procs.size() > 0) {
23360                 proc = procs.valueAt(0);
23361                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23362                     for (int i=1; i<procs.size(); i++) {
23363                         ProcessRecord thisProc = procs.valueAt(i);
23364                         if (thisProc.userId == userId) {
23365                             proc = thisProc;
23366                             break;
23367                         }
23368                     }
23369                 }
23370             }
23371         }
23372
23373         return proc;
23374     }
23375
23376     public boolean dumpHeap(String process, int userId, boolean managed,
23377             String path, ParcelFileDescriptor fd) throws RemoteException {
23378
23379         try {
23380             synchronized (this) {
23381                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23382                 // its own permission (same as profileControl).
23383                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23384                         != PackageManager.PERMISSION_GRANTED) {
23385                     throw new SecurityException("Requires permission "
23386                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23387                 }
23388
23389                 if (fd == null) {
23390                     throw new IllegalArgumentException("null fd");
23391                 }
23392
23393                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23394                 if (proc == null || proc.thread == null) {
23395                     throw new IllegalArgumentException("Unknown process: " + process);
23396                 }
23397
23398                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23399                 if (!isDebuggable) {
23400                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23401                         throw new SecurityException("Process not debuggable: " + proc);
23402                     }
23403                 }
23404
23405                 proc.thread.dumpHeap(managed, path, fd);
23406                 fd = null;
23407                 return true;
23408             }
23409         } catch (RemoteException e) {
23410             throw new IllegalStateException("Process disappeared");
23411         } finally {
23412             if (fd != null) {
23413                 try {
23414                     fd.close();
23415                 } catch (IOException e) {
23416                 }
23417             }
23418         }
23419     }
23420
23421     @Override
23422     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23423             String reportPackage) {
23424         if (processName != null) {
23425             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23426                     "setDumpHeapDebugLimit()");
23427         } else {
23428             synchronized (mPidsSelfLocked) {
23429                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23430                 if (proc == null) {
23431                     throw new SecurityException("No process found for calling pid "
23432                             + Binder.getCallingPid());
23433                 }
23434                 if (!Build.IS_DEBUGGABLE
23435                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23436                     throw new SecurityException("Not running a debuggable build");
23437                 }
23438                 processName = proc.processName;
23439                 uid = proc.uid;
23440                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23441                     throw new SecurityException("Package " + reportPackage + " is not running in "
23442                             + proc);
23443                 }
23444             }
23445         }
23446         synchronized (this) {
23447             if (maxMemSize > 0) {
23448                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23449             } else {
23450                 if (uid != 0) {
23451                     mMemWatchProcesses.remove(processName, uid);
23452                 } else {
23453                     mMemWatchProcesses.getMap().remove(processName);
23454                 }
23455             }
23456         }
23457     }
23458
23459     @Override
23460     public void dumpHeapFinished(String path) {
23461         synchronized (this) {
23462             if (Binder.getCallingPid() != mMemWatchDumpPid) {
23463                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23464                         + " does not match last pid " + mMemWatchDumpPid);
23465                 return;
23466             }
23467             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23468                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23469                         + " does not match last path " + mMemWatchDumpFile);
23470                 return;
23471             }
23472             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23473             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23474         }
23475     }
23476
23477     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23478     public void monitor() {
23479         synchronized (this) { }
23480     }
23481
23482     void onCoreSettingsChange(Bundle settings) {
23483         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23484             ProcessRecord processRecord = mLruProcesses.get(i);
23485             try {
23486                 if (processRecord.thread != null) {
23487                     processRecord.thread.setCoreSettings(settings);
23488                 }
23489             } catch (RemoteException re) {
23490                 /* ignore */
23491             }
23492         }
23493     }
23494
23495     // Multi-user methods
23496
23497     /**
23498      * Start user, if its not already running, but don't bring it to foreground.
23499      */
23500     @Override
23501     public boolean startUserInBackground(final int userId) {
23502         return mUserController.startUser(userId, /* foreground */ false);
23503     }
23504
23505     @Override
23506     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23507         return mUserController.unlockUser(userId, token, secret, listener);
23508     }
23509
23510     @Override
23511     public boolean switchUser(final int targetUserId) {
23512         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23513         int currentUserId;
23514         UserInfo targetUserInfo;
23515         synchronized (this) {
23516             currentUserId = mUserController.getCurrentUserIdLocked();
23517             targetUserInfo = mUserController.getUserInfo(targetUserId);
23518             if (targetUserId == currentUserId) {
23519                 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23520                 return true;
23521             }
23522             if (targetUserInfo == null) {
23523                 Slog.w(TAG, "No user info for user #" + targetUserId);
23524                 return false;
23525             }
23526             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23527                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23528                         + " when device is in demo mode");
23529                 return false;
23530             }
23531             if (!targetUserInfo.supportsSwitchTo()) {
23532                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23533                 return false;
23534             }
23535             if (targetUserInfo.isManagedProfile()) {
23536                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23537                 return false;
23538             }
23539             mUserController.setTargetUserIdLocked(targetUserId);
23540         }
23541         if (mUserController.mUserSwitchUiEnabled) {
23542             UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23543             Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23544             mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23545             mUiHandler.sendMessage(mHandler.obtainMessage(
23546                     START_USER_SWITCH_UI_MSG, userNames));
23547         } else {
23548             mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23549             mHandler.sendMessage(mHandler.obtainMessage(
23550                     START_USER_SWITCH_FG_MSG, targetUserId, 0));
23551         }
23552         return true;
23553     }
23554
23555     void scheduleStartProfilesLocked() {
23556         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23557             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23558                     DateUtils.SECOND_IN_MILLIS);
23559         }
23560     }
23561
23562     @Override
23563     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23564         return mUserController.stopUser(userId, force, callback);
23565     }
23566
23567     @Override
23568     public UserInfo getCurrentUser() {
23569         return mUserController.getCurrentUser();
23570     }
23571
23572     String getStartedUserState(int userId) {
23573         synchronized (this) {
23574             final UserState userState = mUserController.getStartedUserStateLocked(userId);
23575             return UserState.stateToString(userState.state);
23576         }
23577     }
23578
23579     @Override
23580     public boolean isUserRunning(int userId, int flags) {
23581         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23582                 && checkCallingPermission(INTERACT_ACROSS_USERS)
23583                     != PackageManager.PERMISSION_GRANTED) {
23584             String msg = "Permission Denial: isUserRunning() from pid="
23585                     + Binder.getCallingPid()
23586                     + ", uid=" + Binder.getCallingUid()
23587                     + " requires " + INTERACT_ACROSS_USERS;
23588             Slog.w(TAG, msg);
23589             throw new SecurityException(msg);
23590         }
23591         synchronized (this) {
23592             return mUserController.isUserRunningLocked(userId, flags);
23593         }
23594     }
23595
23596     @Override
23597     public int[] getRunningUserIds() {
23598         if (checkCallingPermission(INTERACT_ACROSS_USERS)
23599                 != PackageManager.PERMISSION_GRANTED) {
23600             String msg = "Permission Denial: isUserRunning() from pid="
23601                     + Binder.getCallingPid()
23602                     + ", uid=" + Binder.getCallingUid()
23603                     + " requires " + INTERACT_ACROSS_USERS;
23604             Slog.w(TAG, msg);
23605             throw new SecurityException(msg);
23606         }
23607         synchronized (this) {
23608             return mUserController.getStartedUserArrayLocked();
23609         }
23610     }
23611
23612     @Override
23613     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23614         mUserController.registerUserSwitchObserver(observer, name);
23615     }
23616
23617     @Override
23618     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23619         mUserController.unregisterUserSwitchObserver(observer);
23620     }
23621
23622     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23623         if (info == null) return null;
23624         ApplicationInfo newInfo = new ApplicationInfo(info);
23625         newInfo.initForUser(userId);
23626         return newInfo;
23627     }
23628
23629     public boolean isUserStopped(int userId) {
23630         synchronized (this) {
23631             return mUserController.getStartedUserStateLocked(userId) == null;
23632         }
23633     }
23634
23635     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23636         if (aInfo == null
23637                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23638             return aInfo;
23639         }
23640
23641         ActivityInfo info = new ActivityInfo(aInfo);
23642         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23643         return info;
23644     }
23645
23646     private boolean processSanityChecksLocked(ProcessRecord process) {
23647         if (process == null || process.thread == null) {
23648             return false;
23649         }
23650
23651         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23652         if (!isDebuggable) {
23653             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23654                 return false;
23655             }
23656         }
23657
23658         return true;
23659     }
23660
23661     public boolean startBinderTracking() throws RemoteException {
23662         synchronized (this) {
23663             mBinderTransactionTrackingEnabled = true;
23664             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23665             // permission (same as profileControl).
23666             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23667                     != PackageManager.PERMISSION_GRANTED) {
23668                 throw new SecurityException("Requires permission "
23669                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23670             }
23671
23672             for (int i = 0; i < mLruProcesses.size(); i++) {
23673                 ProcessRecord process = mLruProcesses.get(i);
23674                 if (!processSanityChecksLocked(process)) {
23675                     continue;
23676                 }
23677                 try {
23678                     process.thread.startBinderTracking();
23679                 } catch (RemoteException e) {
23680                     Log.v(TAG, "Process disappared");
23681                 }
23682             }
23683             return true;
23684         }
23685     }
23686
23687     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23688         try {
23689             synchronized (this) {
23690                 mBinderTransactionTrackingEnabled = false;
23691                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23692                 // permission (same as profileControl).
23693                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23694                         != PackageManager.PERMISSION_GRANTED) {
23695                     throw new SecurityException("Requires permission "
23696                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23697                 }
23698
23699                 if (fd == null) {
23700                     throw new IllegalArgumentException("null fd");
23701                 }
23702
23703                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23704                 pw.println("Binder transaction traces for all processes.\n");
23705                 for (ProcessRecord process : mLruProcesses) {
23706                     if (!processSanityChecksLocked(process)) {
23707                         continue;
23708                     }
23709
23710                     pw.println("Traces for process: " + process.processName);
23711                     pw.flush();
23712                     try {
23713                         TransferPipe tp = new TransferPipe();
23714                         try {
23715                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23716                             tp.go(fd.getFileDescriptor());
23717                         } finally {
23718                             tp.kill();
23719                         }
23720                     } catch (IOException e) {
23721                         pw.println("Failure while dumping IPC traces from " + process +
23722                                 ".  Exception: " + e);
23723                         pw.flush();
23724                     } catch (RemoteException e) {
23725                         pw.println("Got a RemoteException while dumping IPC traces from " +
23726                                 process + ".  Exception: " + e);
23727                         pw.flush();
23728                     }
23729                 }
23730                 fd = null;
23731                 return true;
23732             }
23733         } finally {
23734             if (fd != null) {
23735                 try {
23736                     fd.close();
23737                 } catch (IOException e) {
23738                 }
23739             }
23740         }
23741     }
23742
23743     @VisibleForTesting
23744     final class LocalService extends ActivityManagerInternal {
23745         @Override
23746         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23747                 int targetUserId) {
23748             synchronized (ActivityManagerService.this) {
23749                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23750                         targetPkg, intent, null, targetUserId);
23751             }
23752         }
23753
23754         @Override
23755         public String checkContentProviderAccess(String authority, int userId) {
23756             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23757         }
23758
23759         @Override
23760         public void onWakefulnessChanged(int wakefulness) {
23761             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23762         }
23763
23764         @Override
23765         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23766                 String processName, String abiOverride, int uid, Runnable crashHandler) {
23767             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23768                     processName, abiOverride, uid, crashHandler);
23769         }
23770
23771         @Override
23772         public SleepToken acquireSleepToken(String tag) {
23773             Preconditions.checkNotNull(tag);
23774
23775             synchronized (ActivityManagerService.this) {
23776                 SleepTokenImpl token = new SleepTokenImpl(tag);
23777                 mSleepTokens.add(token);
23778                 updateSleepIfNeededLocked();
23779                 return token;
23780             }
23781         }
23782
23783         @Override
23784         public ComponentName getHomeActivityForUser(int userId) {
23785             synchronized (ActivityManagerService.this) {
23786                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23787                 return homeActivity == null ? null : homeActivity.realActivity;
23788             }
23789         }
23790
23791         @Override
23792         public void onUserRemoved(int userId) {
23793             synchronized (ActivityManagerService.this) {
23794                 ActivityManagerService.this.onUserStoppedLocked(userId);
23795             }
23796         }
23797
23798         @Override
23799         public void onLocalVoiceInteractionStarted(IBinder activity,
23800                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23801             synchronized (ActivityManagerService.this) {
23802                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23803                         voiceSession, voiceInteractor);
23804             }
23805         }
23806
23807         @Override
23808         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23809             synchronized (ActivityManagerService.this) {
23810                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23811                         reasons, timestamp);
23812             }
23813         }
23814
23815         @Override
23816         public void notifyAppTransitionFinished() {
23817             synchronized (ActivityManagerService.this) {
23818                 mStackSupervisor.notifyAppTransitionDone();
23819             }
23820         }
23821
23822         @Override
23823         public void notifyAppTransitionCancelled() {
23824             synchronized (ActivityManagerService.this) {
23825                 mStackSupervisor.notifyAppTransitionDone();
23826             }
23827         }
23828
23829         @Override
23830         public List<IBinder> getTopVisibleActivities() {
23831             synchronized (ActivityManagerService.this) {
23832                 return mStackSupervisor.getTopVisibleActivities();
23833             }
23834         }
23835
23836         @Override
23837         public void notifyDockedStackMinimizedChanged(boolean minimized) {
23838             synchronized (ActivityManagerService.this) {
23839                 mStackSupervisor.setDockedStackMinimized(minimized);
23840             }
23841         }
23842
23843         @Override
23844         public void killForegroundAppsForUser(int userHandle) {
23845             synchronized (ActivityManagerService.this) {
23846                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23847                 final int NP = mProcessNames.getMap().size();
23848                 for (int ip = 0; ip < NP; ip++) {
23849                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23850                     final int NA = apps.size();
23851                     for (int ia = 0; ia < NA; ia++) {
23852                         final ProcessRecord app = apps.valueAt(ia);
23853                         if (app.persistent) {
23854                             // We don't kill persistent processes.
23855                             continue;
23856                         }
23857                         if (app.removed) {
23858                             procs.add(app);
23859                         } else if (app.userId == userHandle && app.foregroundActivities) {
23860                             app.removed = true;
23861                             procs.add(app);
23862                         }
23863                     }
23864                 }
23865
23866                 final int N = procs.size();
23867                 for (int i = 0; i < N; i++) {
23868                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
23869                 }
23870             }
23871         }
23872
23873         @Override
23874         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23875                 long duration) {
23876             if (!(target instanceof PendingIntentRecord)) {
23877                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23878                 return;
23879             }
23880             ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23881         }
23882
23883         @Override
23884         public void setDeviceIdleWhitelist(int[] appids) {
23885             synchronized (ActivityManagerService.this) {
23886                 mDeviceIdleWhitelist = appids;
23887             }
23888         }
23889
23890         @Override
23891         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23892             synchronized (ActivityManagerService.this) {
23893                 mDeviceIdleTempWhitelist = appids;
23894                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
23895             }
23896         }
23897
23898         @Override
23899         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23900                 int userId) {
23901             Preconditions.checkNotNull(values, "Configuration must not be null");
23902             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23903             synchronized (ActivityManagerService.this) {
23904                 updateConfigurationLocked(values, null, false, true, userId,
23905                         false /* deferResume */);
23906             }
23907         }
23908
23909         @Override
23910         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23911                 Bundle bOptions) {
23912             Preconditions.checkNotNull(intents, "intents");
23913             final String[] resolvedTypes = new String[intents.length];
23914             for (int i = 0; i < intents.length; i++) {
23915                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23916             }
23917
23918             // UID of the package on user userId.
23919             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23920             // packageUid may not be initialized.
23921             int packageUid = 0;
23922             try {
23923                 packageUid = AppGlobals.getPackageManager().getPackageUid(
23924                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23925             } catch (RemoteException e) {
23926                 // Shouldn't happen.
23927             }
23928
23929             synchronized (ActivityManagerService.this) {
23930                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23931                         /*resultTo*/ null, bOptions, userId);
23932             }
23933         }
23934
23935         @Override
23936         public int getUidProcessState(int uid) {
23937             return getUidState(uid);
23938         }
23939
23940         @Override
23941         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23942             synchronized (ActivityManagerService.this) {
23943
23944                 // We might change the visibilities here, so prepare an empty app transition which
23945                 // might be overridden later if we actually change visibilities.
23946                 mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23947                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23948                 mWindowManager.executeAppTransition();
23949             }
23950             if (callback != null) {
23951                 callback.run();
23952             }
23953         }
23954
23955         @Override
23956         public boolean isSystemReady() {
23957             // no need to synchronize(this) just to read & return the value
23958             return mSystemReady;
23959         }
23960
23961         @Override
23962         public void notifyKeyguardTrustedChanged() {
23963             synchronized (ActivityManagerService.this) {
23964                 if (mKeyguardController.isKeyguardShowing()) {
23965                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23966                 }
23967             }
23968         }
23969
23970         /**
23971          * Sets if the given pid has an overlay UI or not.
23972          *
23973          * @param pid The pid we are setting overlay UI for.
23974          * @param hasOverlayUi True if the process has overlay UI.
23975          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
23976          */
23977         @Override
23978         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
23979             synchronized (ActivityManagerService.this) {
23980                 final ProcessRecord pr;
23981                 synchronized (mPidsSelfLocked) {
23982                     pr = mPidsSelfLocked.get(pid);
23983                     if (pr == null) {
23984                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
23985                         return;
23986                     }
23987                 }
23988                 if (pr.hasOverlayUi == hasOverlayUi) {
23989                     return;
23990                 }
23991                 pr.hasOverlayUi = hasOverlayUi;
23992                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
23993                 updateOomAdjLocked(pr, true);
23994             }
23995         }
23996
23997         /**
23998          * Called after the network policy rules are updated by
23999          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24000          * and {@param procStateSeq}.
24001          */
24002         @Override
24003         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24004             if (DEBUG_NETWORK) {
24005                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24006                         + uid + " seq: " + procStateSeq);
24007             }
24008             UidRecord record;
24009             synchronized (ActivityManagerService.this) {
24010                 record = mActiveUids.get(uid);
24011                 if (record == null) {
24012                     if (DEBUG_NETWORK) {
24013                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24014                                 + " procStateSeq: " + procStateSeq);
24015                     }
24016                     return;
24017                 }
24018             }
24019             synchronized (record.networkStateLock) {
24020                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24021                     if (DEBUG_NETWORK) {
24022                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24023                                 + " been handled for uid: " + uid);
24024                     }
24025                     return;
24026                 }
24027                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24028                 if (record.curProcStateSeq > procStateSeq) {
24029                     if (DEBUG_NETWORK) {
24030                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24031                                 + ", curProcstateSeq: " + record.curProcStateSeq
24032                                 + ", procStateSeq: " + procStateSeq);
24033                     }
24034                     return;
24035                 }
24036                 if (record.waitingForNetwork) {
24037                     if (DEBUG_NETWORK) {
24038                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24039                                 + ", procStateSeq: " + procStateSeq);
24040                     }
24041                     record.networkStateLock.notifyAll();
24042                 }
24043             }
24044         }
24045
24046         /**
24047          * Called after virtual display Id is updated by
24048          * {@link com.android.server.vr.Vr2dDisplay} with a specific
24049          * {@param vrVr2dDisplayId}.
24050          */
24051         @Override
24052         public void setVr2dDisplayId(int vr2dDisplayId) {
24053             if (DEBUG_STACK) {
24054                 Slog.d(TAG, "setVr2dDisplayId called for: " +
24055                         vr2dDisplayId);
24056             }
24057             synchronized (ActivityManagerService.this) {
24058                 mVr2dDisplayId = vr2dDisplayId;
24059             }
24060         }
24061
24062         @Override
24063         public void saveANRState(String reason) {
24064             synchronized (ActivityManagerService.this) {
24065                 final StringWriter sw = new StringWriter();
24066                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24067                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24068                 if (reason != null) {
24069                     pw.println("  Reason: " + reason);
24070                 }
24071                 pw.println();
24072                 mActivityStarter.dump(pw, "  ");
24073                 pw.println();
24074                 pw.println("-------------------------------------------------------------------------------");
24075                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24076                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24077                         "" /* header */);
24078                 pw.println();
24079                 pw.close();
24080
24081                 mLastANRState = sw.toString();
24082             }
24083         }
24084
24085         @Override
24086         public void clearSavedANRState() {
24087             synchronized (ActivityManagerService.this) {
24088                 mLastANRState = null;
24089             }
24090         }
24091
24092         @Override
24093         public boolean hasRunningActivity(int uid, @Nullable String packageName) {
24094             if (packageName == null) return false;
24095
24096             synchronized (ActivityManagerService.this) {
24097                 for (int i = 0; i < mLruProcesses.size(); i++) {
24098                     final ProcessRecord processRecord = mLruProcesses.get(i);
24099                     if (processRecord.uid == uid) {
24100                         for (int j = 0; j < processRecord.activities.size(); j++) {
24101                             final ActivityRecord activityRecord = processRecord.activities.get(j);
24102                             if (packageName.equals(activityRecord.packageName)) {
24103                                 return true;
24104                             }
24105                         }
24106                     }
24107                 }
24108             }
24109             return false;
24110         }
24111     }
24112
24113     /**
24114      * Called by app main thread to wait for the network policy rules to get updated.
24115      *
24116      * @param procStateSeq The sequence number indicating the process state change that the main
24117      *                     thread is interested in.
24118      */
24119     @Override
24120     public void waitForNetworkStateUpdate(long procStateSeq) {
24121         final int callingUid = Binder.getCallingUid();
24122         if (DEBUG_NETWORK) {
24123             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24124         }
24125         UidRecord record;
24126         synchronized (this) {
24127             record = mActiveUids.get(callingUid);
24128             if (record == null) {
24129                 return;
24130             }
24131         }
24132         synchronized (record.networkStateLock) {
24133             if (record.lastDispatchedProcStateSeq < procStateSeq) {
24134                 if (DEBUG_NETWORK) {
24135                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24136                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24137                             + " lastProcStateSeqDispatchedToObservers: "
24138                             + record.lastDispatchedProcStateSeq);
24139                 }
24140                 return;
24141             }
24142             if (record.curProcStateSeq > procStateSeq) {
24143                 if (DEBUG_NETWORK) {
24144                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24145                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24146                             + ", procStateSeq: " + procStateSeq);
24147                 }
24148                 return;
24149             }
24150             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24151                 if (DEBUG_NETWORK) {
24152                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24153                             + procStateSeq + ", so no need to wait. Uid: "
24154                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24155                             + record.lastNetworkUpdatedProcStateSeq);
24156                 }
24157                 return;
24158             }
24159             try {
24160                 if (DEBUG_NETWORK) {
24161                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24162                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24163                 }
24164                 final long startTime = SystemClock.uptimeMillis();
24165                 record.waitingForNetwork = true;
24166                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24167                 record.waitingForNetwork = false;
24168                 final long totalTime = SystemClock.uptimeMillis() - startTime;
24169                 if (totalTime >= mWaitForNetworkTimeoutMs) {
24170                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24171                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24172                             + procStateSeq + " UidRec: " + record
24173                             + " validateUidRec: " + mValidateUids.get(callingUid));
24174                 }
24175             } catch (InterruptedException e) {
24176                 Thread.currentThread().interrupt();
24177             }
24178         }
24179     }
24180
24181     public void waitForBroadcastIdle(PrintWriter pw) {
24182         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24183         while (true) {
24184             boolean idle = true;
24185             synchronized (this) {
24186                 for (BroadcastQueue queue : mBroadcastQueues) {
24187                     if (!queue.isIdle()) {
24188                         final String msg = "Waiting for queue " + queue + " to become idle...";
24189                         pw.println(msg);
24190                         pw.flush();
24191                         Slog.v(TAG, msg);
24192                         idle = false;
24193                     }
24194                 }
24195             }
24196
24197             if (idle) {
24198                 final String msg = "All broadcast queues are idle!";
24199                 pw.println(msg);
24200                 pw.flush();
24201                 Slog.v(TAG, msg);
24202                 return;
24203             } else {
24204                 SystemClock.sleep(1000);
24205             }
24206         }
24207     }
24208
24209     /**
24210      * Return the user id of the last resumed activity.
24211      */
24212     @Override
24213     public @UserIdInt int getLastResumedActivityUserId() {
24214         enforceCallingPermission(
24215                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24216         synchronized (this) {
24217             if (mLastResumedActivity == null) {
24218                 return mUserController.getCurrentUserIdLocked();
24219             }
24220             return mLastResumedActivity.userId;
24221         }
24222     }
24223
24224     private final class SleepTokenImpl extends SleepToken {
24225         private final String mTag;
24226         private final long mAcquireTime;
24227
24228         public SleepTokenImpl(String tag) {
24229             mTag = tag;
24230             mAcquireTime = SystemClock.uptimeMillis();
24231         }
24232
24233         @Override
24234         public void release() {
24235             synchronized (ActivityManagerService.this) {
24236                 if (mSleepTokens.remove(this)) {
24237                     updateSleepIfNeededLocked();
24238                 }
24239             }
24240         }
24241
24242         @Override
24243         public String toString() {
24244             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
24245         }
24246     }
24247
24248     /**
24249      * An implementation of IAppTask, that allows an app to manage its own tasks via
24250      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24251      * only the process that calls getAppTasks() can call the AppTask methods.
24252      */
24253     class AppTaskImpl extends IAppTask.Stub {
24254         private int mTaskId;
24255         private int mCallingUid;
24256
24257         public AppTaskImpl(int taskId, int callingUid) {
24258             mTaskId = taskId;
24259             mCallingUid = callingUid;
24260         }
24261
24262         private void checkCaller() {
24263             if (mCallingUid != Binder.getCallingUid()) {
24264                 throw new SecurityException("Caller " + mCallingUid
24265                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24266             }
24267         }
24268
24269         @Override
24270         public void finishAndRemoveTask() {
24271             checkCaller();
24272
24273             synchronized (ActivityManagerService.this) {
24274                 long origId = Binder.clearCallingIdentity();
24275                 try {
24276                     // We remove the task from recents to preserve backwards
24277                     if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24278                             REMOVE_FROM_RECENTS)) {
24279                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24280                     }
24281                 } finally {
24282                     Binder.restoreCallingIdentity(origId);
24283                 }
24284             }
24285         }
24286
24287         @Override
24288         public ActivityManager.RecentTaskInfo getTaskInfo() {
24289             checkCaller();
24290
24291             synchronized (ActivityManagerService.this) {
24292                 long origId = Binder.clearCallingIdentity();
24293                 try {
24294                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24295                     if (tr == null) {
24296                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24297                     }
24298                     return createRecentTaskInfoFromTaskRecord(tr);
24299                 } finally {
24300                     Binder.restoreCallingIdentity(origId);
24301                 }
24302             }
24303         }
24304
24305         @Override
24306         public void moveToFront() {
24307             checkCaller();
24308             // Will bring task to front if it already has a root activity.
24309             final long origId = Binder.clearCallingIdentity();
24310             try {
24311                 synchronized (this) {
24312                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24313                 }
24314             } finally {
24315                 Binder.restoreCallingIdentity(origId);
24316             }
24317         }
24318
24319         @Override
24320         public int startActivity(IBinder whoThread, String callingPackage,
24321                 Intent intent, String resolvedType, Bundle bOptions) {
24322             checkCaller();
24323
24324             int callingUser = UserHandle.getCallingUserId();
24325             TaskRecord tr;
24326             IApplicationThread appThread;
24327             synchronized (ActivityManagerService.this) {
24328                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24329                 if (tr == null) {
24330                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24331                 }
24332                 appThread = IApplicationThread.Stub.asInterface(whoThread);
24333                 if (appThread == null) {
24334                     throw new IllegalArgumentException("Bad app thread " + appThread);
24335                 }
24336             }
24337             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24338                     resolvedType, null, null, null, null, 0, 0, null, null,
24339                     null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
24340         }
24341
24342         @Override
24343         public void setExcludeFromRecents(boolean exclude) {
24344             checkCaller();
24345
24346             synchronized (ActivityManagerService.this) {
24347                 long origId = Binder.clearCallingIdentity();
24348                 try {
24349                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24350                     if (tr == null) {
24351                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24352                     }
24353                     Intent intent = tr.getBaseIntent();
24354                     if (exclude) {
24355                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24356                     } else {
24357                         intent.setFlags(intent.getFlags()
24358                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24359                     }
24360                 } finally {
24361                     Binder.restoreCallingIdentity(origId);
24362                 }
24363             }
24364         }
24365     }
24366
24367     /**
24368      * Kill processes for the user with id userId and that depend on the package named packageName
24369      */
24370     @Override
24371     public void killPackageDependents(String packageName, int userId) {
24372         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24373         if (packageName == null) {
24374             throw new NullPointerException(
24375                     "Cannot kill the dependents of a package without its name.");
24376         }
24377
24378         long callingId = Binder.clearCallingIdentity();
24379         IPackageManager pm = AppGlobals.getPackageManager();
24380         int pkgUid = -1;
24381         try {
24382             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24383         } catch (RemoteException e) {
24384         }
24385         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24386             throw new IllegalArgumentException(
24387                     "Cannot kill dependents of non-existing package " + packageName);
24388         }
24389         try {
24390             synchronized(this) {
24391                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24392                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24393                         "dep: " + packageName);
24394             }
24395         } finally {
24396             Binder.restoreCallingIdentity(callingId);
24397         }
24398     }
24399
24400     @Override
24401     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24402             throws RemoteException {
24403         final long callingId = Binder.clearCallingIdentity();
24404         try {
24405             mKeyguardController.dismissKeyguard(token, callback);
24406         } finally {
24407             Binder.restoreCallingIdentity(callingId);
24408         }
24409     }
24410
24411     @Override
24412     public int restartUserInBackground(final int userId) {
24413         return mUserController.restartUser(userId, /* foreground */ false);
24414     }
24415
24416     @Override
24417     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24418         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24419                 "scheduleApplicationInfoChanged()");
24420
24421         synchronized (this) {
24422             final long origId = Binder.clearCallingIdentity();
24423             try {
24424                 updateApplicationInfoLocked(packageNames, userId);
24425             } finally {
24426                 Binder.restoreCallingIdentity(origId);
24427             }
24428         }
24429     }
24430
24431     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24432         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24433         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24434             final ProcessRecord app = mLruProcesses.get(i);
24435             if (app.thread == null) {
24436                 continue;
24437             }
24438
24439             if (userId != UserHandle.USER_ALL && app.userId != userId) {
24440                 continue;
24441             }
24442
24443             final int packageCount = app.pkgList.size();
24444             for (int j = 0; j < packageCount; j++) {
24445                 final String packageName = app.pkgList.keyAt(j);
24446                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24447                     try {
24448                         final ApplicationInfo ai = AppGlobals.getPackageManager()
24449                                 .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
24450                         if (ai != null) {
24451                             app.thread.scheduleApplicationInfoChanged(ai);
24452                         }
24453                     } catch (RemoteException e) {
24454                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24455                                     packageName, app));
24456                     }
24457                 }
24458             }
24459         }
24460     }
24461
24462     /**
24463      * Attach an agent to the specified process (proces name or PID)
24464      */
24465     public void attachAgent(String process, String path) {
24466         try {
24467             synchronized (this) {
24468                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24469                 if (proc == null || proc.thread == null) {
24470                     throw new IllegalArgumentException("Unknown process: " + process);
24471                 }
24472
24473                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24474                 if (!isDebuggable) {
24475                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24476                         throw new SecurityException("Process not debuggable: " + proc);
24477                     }
24478                 }
24479
24480                 proc.thread.attachAgent(path);
24481             }
24482         } catch (RemoteException e) {
24483             throw new IllegalStateException("Process disappeared");
24484         }
24485     }
24486
24487     @VisibleForTesting
24488     public static class Injector {
24489         private NetworkManagementInternal mNmi;
24490
24491         public Context getContext() {
24492             return null;
24493         }
24494
24495         public AppOpsService getAppOpsService(File file, Handler handler) {
24496             return new AppOpsService(file, handler);
24497         }
24498
24499         public Handler getUiHandler(ActivityManagerService service) {
24500             return service.new UiHandler();
24501         }
24502
24503         public boolean isNetworkRestrictedForUid(int uid) {
24504             if (ensureHasNetworkManagementInternal()) {
24505                 return mNmi.isNetworkRestrictedForUid(uid);
24506             }
24507             return false;
24508         }
24509
24510         private boolean ensureHasNetworkManagementInternal() {
24511             if (mNmi == null) {
24512                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24513             }
24514             return mNmi != null;
24515         }
24516     }
24517 }