OSDN Git Service

5b2e7793719936382bc2a30c96855e1d55435611
[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.MANAGE_ACTIVITY_STACKS;
24 import static android.Manifest.permission.READ_FRAME_BUFFER;
25 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
26 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
27 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
28 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
29 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
30 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
31 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
32 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
33 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
34 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
35 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
36 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
37 import static android.content.pm.PackageManager.GET_PROVIDERS;
38 import static android.content.pm.PackageManager.MATCH_ANY_USER;
39 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
40 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
41 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
42 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
43 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
44 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
45 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
46 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
47 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
48 import static android.os.Build.VERSION_CODES.N;
49 import static android.os.Process.BLUETOOTH_UID;
50 import static android.os.Process.FIRST_APPLICATION_UID;
51 import static android.os.Process.FIRST_ISOLATED_UID;
52 import static android.os.Process.LAST_ISOLATED_UID;
53 import static android.os.Process.NFC_UID;
54 import static android.os.Process.PHONE_UID;
55 import static android.os.Process.PROC_CHAR;
56 import static android.os.Process.PROC_OUT_LONG;
57 import static android.os.Process.PROC_PARENS;
58 import static android.os.Process.PROC_SPACE_TERM;
59 import static android.os.Process.ProcessStartResult;
60 import static android.os.Process.ROOT_UID;
61 import static android.os.Process.SCHED_FIFO;
62 import static android.os.Process.SCHED_OTHER;
63 import static android.os.Process.SCHED_RESET_ON_FORK;
64 import static android.os.Process.SHELL_UID;
65 import static android.os.Process.SIGNAL_QUIT;
66 import static android.os.Process.SIGNAL_USR1;
67 import static android.os.Process.SYSTEM_UID;
68 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
69 import static android.os.Process.THREAD_GROUP_DEFAULT;
70 import static android.os.Process.THREAD_GROUP_TOP_APP;
71 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
72 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
73 import static android.os.Process.getFreeMemory;
74 import static android.os.Process.getTotalMemory;
75 import static android.os.Process.isThreadInProcess;
76 import static android.os.Process.killProcess;
77 import static android.os.Process.killProcessQuiet;
78 import static android.os.Process.myPid;
79 import static android.os.Process.myUid;
80 import static android.os.Process.readProcFile;
81 import static android.os.Process.removeAllProcessGroups;
82 import static android.os.Process.sendSignal;
83 import static android.os.Process.setProcessGroup;
84 import static android.os.Process.setThreadPriority;
85 import static android.os.Process.setThreadScheduler;
86 import static android.os.Process.startWebView;
87 import static android.os.Process.zygoteProcess;
88 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
89 import static android.provider.Settings.Global.DEBUG_APP;
90 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
91 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
92 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
93 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
94 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
95 import static android.provider.Settings.System.FONT_SCALE;
96 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
97 import static android.view.Display.DEFAULT_DISPLAY;
98 import static android.view.Display.INVALID_DISPLAY;
99 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
100 import static com.android.internal.util.XmlUtils.readIntAttribute;
101 import static com.android.internal.util.XmlUtils.readLongAttribute;
102 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
103 import static com.android.internal.util.XmlUtils.writeIntAttribute;
104 import static com.android.internal.util.XmlUtils.writeLongAttribute;
105 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
106 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
107 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
139 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
140 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
164 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
165 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
166 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
167 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
168 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
169 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
171 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
172 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
173 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
174 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
175 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
178 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
179 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
180 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
182 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
183 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
186 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
187 import static org.xmlpull.v1.XmlPullParser.START_TAG;
188
189 import android.Manifest;
190 import android.Manifest.permission;
191 import android.annotation.NonNull;
192 import android.annotation.Nullable;
193 import android.annotation.UserIdInt;
194 import android.app.Activity;
195 import android.app.ActivityManager;
196 import android.app.ActivityManager.RunningTaskInfo;
197 import android.app.ActivityManager.StackId;
198 import android.app.ActivityManager.StackInfo;
199 import android.app.ActivityManager.TaskSnapshot;
200 import android.app.ActivityManager.TaskThumbnailInfo;
201 import android.app.ActivityManagerInternal;
202 import android.app.ActivityManagerInternal.SleepToken;
203 import android.app.ActivityOptions;
204 import android.app.ActivityThread;
205 import android.app.AlertDialog;
206 import android.app.AppGlobals;
207 import android.app.AppOpsManager;
208 import android.app.ApplicationErrorReport;
209 import android.app.ApplicationThreadConstants;
210 import android.app.BroadcastOptions;
211 import android.app.ContentProviderHolder;
212 import android.app.Dialog;
213 import android.app.IActivityContainer;
214 import android.app.IActivityContainerCallback;
215 import android.app.IActivityController;
216 import android.app.IActivityManager;
217 import android.app.IAppTask;
218 import android.app.IApplicationThread;
219 import android.app.IInstrumentationWatcher;
220 import android.app.INotificationManager;
221 import android.app.IProcessObserver;
222 import android.app.IServiceConnection;
223 import android.app.IStopUserCallback;
224 import android.app.ITaskStackListener;
225 import android.app.IUiAutomationConnection;
226 import android.app.IUidObserver;
227 import android.app.IUserSwitchObserver;
228 import android.app.Instrumentation;
229 import android.app.Notification;
230 import android.app.NotificationManager;
231 import android.app.PendingIntent;
232 import android.app.PictureInPictureParams;
233 import android.app.ProfilerInfo;
234 import android.app.RemoteAction;
235 import android.app.WaitResult;
236 import android.app.admin.DevicePolicyManager;
237 import android.app.assist.AssistContent;
238 import android.app.assist.AssistStructure;
239 import android.app.backup.IBackupManager;
240 import android.app.usage.UsageEvents;
241 import android.app.usage.UsageStatsManagerInternal;
242 import android.appwidget.AppWidgetManager;
243 import android.content.ActivityNotFoundException;
244 import android.content.BroadcastReceiver;
245 import android.content.ClipData;
246 import android.content.ComponentCallbacks2;
247 import android.content.ComponentName;
248 import android.content.ContentProvider;
249 import android.content.ContentResolver;
250 import android.content.Context;
251 import android.content.DialogInterface;
252 import android.content.IContentProvider;
253 import android.content.IIntentReceiver;
254 import android.content.IIntentSender;
255 import android.content.Intent;
256 import android.content.IntentFilter;
257 import android.content.IntentSender;
258 import android.content.pm.ActivityInfo;
259 import android.content.pm.ApplicationInfo;
260 import android.content.pm.ConfigurationInfo;
261 import android.content.pm.IPackageDataObserver;
262 import android.content.pm.IPackageManager;
263 import android.content.pm.InstrumentationInfo;
264 import android.content.pm.PackageInfo;
265 import android.content.pm.PackageManager;
266 import android.content.pm.PackageManager.NameNotFoundException;
267 import android.content.pm.PackageManagerInternal;
268 import android.content.pm.ParceledListSlice;
269 import android.content.pm.PathPermission;
270 import android.content.pm.PermissionInfo;
271 import android.content.pm.ProviderInfo;
272 import android.content.pm.ResolveInfo;
273 import android.content.pm.SELinuxUtil;
274 import android.content.pm.ServiceInfo;
275 import android.content.pm.UserInfo;
276 import android.content.res.CompatibilityInfo;
277 import android.content.res.Configuration;
278 import android.content.res.Resources;
279 import android.database.ContentObserver;
280 import android.graphics.Bitmap;
281 import android.graphics.Point;
282 import android.graphics.Rect;
283 import android.location.LocationManager;
284 import android.media.audiofx.AudioEffect;
285 import android.metrics.LogMaker;
286 import android.net.Proxy;
287 import android.net.ProxyInfo;
288 import android.net.Uri;
289 import android.os.BatteryStats;
290 import android.os.Binder;
291 import android.os.Build;
292 import android.os.Bundle;
293 import android.os.Debug;
294 import android.os.DropBoxManager;
295 import android.os.Environment;
296 import android.os.FactoryTest;
297 import android.os.FileObserver;
298 import android.os.FileUtils;
299 import android.os.Handler;
300 import android.os.IBinder;
301 import android.os.IDeviceIdentifiersPolicyService;
302 import android.os.IPermissionController;
303 import android.os.IProcessInfoService;
304 import android.os.IProgressListener;
305 import android.os.LocaleList;
306 import android.os.Looper;
307 import android.os.Message;
308 import android.os.Parcel;
309 import android.os.ParcelFileDescriptor;
310 import android.os.PersistableBundle;
311 import android.os.PowerManager;
312 import android.os.PowerManagerInternal;
313 import android.os.Process;
314 import android.os.RemoteCallbackList;
315 import android.os.RemoteException;
316 import android.os.ResultReceiver;
317 import android.os.ServiceManager;
318 import android.os.ShellCallback;
319 import android.os.StrictMode;
320 import android.os.SystemClock;
321 import android.os.SystemProperties;
322 import android.os.Trace;
323 import android.os.TransactionTooLargeException;
324 import android.os.UpdateLock;
325 import android.os.UserHandle;
326 import android.os.UserManager;
327 import android.os.WorkSource;
328 import android.os.storage.IStorageManager;
329 import android.os.storage.StorageManager;
330 import android.os.storage.StorageManagerInternal;
331 import android.provider.Downloads;
332 import android.provider.Settings;
333 import android.service.voice.IVoiceInteractionSession;
334 import android.service.voice.VoiceInteractionManagerInternal;
335 import android.service.voice.VoiceInteractionSession;
336 import android.telecom.TelecomManager;
337 import android.text.TextUtils;
338 import android.text.format.DateUtils;
339 import android.text.format.Time;
340 import android.text.style.SuggestionSpan;
341 import android.util.ArrayMap;
342 import android.util.ArraySet;
343 import android.util.AtomicFile;
344 import android.util.BootTimingsTraceLog;
345 import android.util.DebugUtils;
346 import android.util.DisplayMetrics;
347 import android.util.EventLog;
348 import android.util.Log;
349 import android.util.Pair;
350 import android.util.PrintWriterPrinter;
351 import android.util.Slog;
352 import android.util.SparseArray;
353 import android.util.SparseIntArray;
354 import android.util.TimeUtils;
355 import android.util.Xml;
356 import android.view.Gravity;
357 import android.view.LayoutInflater;
358 import android.view.View;
359 import android.view.WindowManager;
360
361 import com.android.server.job.JobSchedulerInternal;
362 import com.google.android.collect.Lists;
363 import com.google.android.collect.Maps;
364
365 import com.android.internal.R;
366 import com.android.internal.annotations.GuardedBy;
367 import com.android.internal.annotations.VisibleForTesting;
368 import com.android.internal.app.AssistUtils;
369 import com.android.internal.app.DumpHeapActivity;
370 import com.android.internal.app.IAppOpsCallback;
371 import com.android.internal.app.IAppOpsService;
372 import com.android.internal.app.IVoiceInteractor;
373 import com.android.internal.app.ProcessMap;
374 import com.android.internal.app.SystemUserHomeActivity;
375 import com.android.internal.app.procstats.ProcessStats;
376 import com.android.internal.logging.MetricsLogger;
377 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
378 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
379 import com.android.internal.notification.SystemNotificationChannels;
380 import com.android.internal.os.BackgroundThread;
381 import com.android.internal.os.BatteryStatsImpl;
382 import com.android.internal.os.IResultReceiver;
383 import com.android.internal.os.ProcessCpuTracker;
384 import com.android.internal.os.TransferPipe;
385 import com.android.internal.os.Zygote;
386 import com.android.internal.policy.IKeyguardDismissCallback;
387 import com.android.internal.telephony.TelephonyIntents;
388 import com.android.internal.util.ArrayUtils;
389 import com.android.internal.util.DumpUtils;
390 import com.android.internal.util.FastPrintWriter;
391 import com.android.internal.util.FastXmlSerializer;
392 import com.android.internal.util.MemInfoReader;
393 import com.android.internal.util.Preconditions;
394 import com.android.server.AppOpsService;
395 import com.android.server.AttributeCache;
396 import com.android.server.DeviceIdleController;
397 import com.android.server.IntentResolver;
398 import com.android.server.LocalServices;
399 import com.android.server.LockGuard;
400 import com.android.server.NetworkManagementInternal;
401 import com.android.server.RescueParty;
402 import com.android.server.ServiceThread;
403 import com.android.server.SystemConfig;
404 import com.android.server.SystemService;
405 import com.android.server.SystemServiceManager;
406 import com.android.server.ThreadPriorityBooster;
407 import com.android.server.Watchdog;
408 import com.android.server.am.ActivityStack.ActivityState;
409 import com.android.server.firewall.IntentFirewall;
410 import com.android.server.pm.Installer;
411 import com.android.server.pm.Installer.InstallerException;
412 import com.android.server.statusbar.StatusBarManagerInternal;
413 import com.android.server.vr.VrManagerInternal;
414 import com.android.server.wm.PinnedStackWindowController;
415 import com.android.server.wm.WindowManagerService;
416
417 import org.xmlpull.v1.XmlPullParser;
418 import org.xmlpull.v1.XmlPullParserException;
419 import org.xmlpull.v1.XmlSerializer;
420
421 import java.io.File;
422 import java.io.FileDescriptor;
423 import java.io.FileInputStream;
424 import java.io.FileNotFoundException;
425 import java.io.FileOutputStream;
426 import java.io.IOException;
427 import java.io.InputStreamReader;
428 import java.io.PrintWriter;
429 import java.io.StringWriter;
430 import java.io.UnsupportedEncodingException;
431 import java.lang.ref.WeakReference;
432 import java.nio.charset.StandardCharsets;
433 import java.text.DateFormat;
434 import java.util.ArrayList;
435 import java.util.Arrays;
436 import java.util.Collections;
437 import java.util.Comparator;
438 import java.util.Date;
439 import java.util.HashMap;
440 import java.util.HashSet;
441 import java.util.Iterator;
442 import java.util.List;
443 import java.util.Locale;
444 import java.util.Map;
445 import java.util.Objects;
446 import java.util.Set;
447 import java.util.concurrent.CountDownLatch;
448 import java.util.concurrent.atomic.AtomicBoolean;
449 import java.util.concurrent.atomic.AtomicLong;
450
451 import dalvik.system.VMRuntime;
452 import libcore.io.IoUtils;
453 import libcore.util.EmptyArray;
454
455 public class ActivityManagerService extends IActivityManager.Stub
456         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
457
458     /**
459      * Priority we boost main thread and RT of top app to.
460      */
461     public static final int TOP_APP_PRIORITY_BOOST = -10;
462
463     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
464     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
465     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
466     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
467     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
468     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
469     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
470     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
471     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
472     private static final String TAG_LRU = TAG + POSTFIX_LRU;
473     private static final String TAG_MU = TAG + POSTFIX_MU;
474     private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
475     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
476     private static final String TAG_POWER = TAG + POSTFIX_POWER;
477     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
478     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
479     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
480     private static final String TAG_PSS = TAG + POSTFIX_PSS;
481     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
482     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
483     private static final String TAG_STACK = TAG + POSTFIX_STACK;
484     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
485     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
486     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
487     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
488     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
489
490     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
491     // here so that while the job scheduler can depend on AMS, the other way around
492     // need not be the case.
493     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
494
495     /** Control over CPU and battery monitoring */
496     // write battery stats every 30 minutes.
497     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
498     static final boolean MONITOR_CPU_USAGE = true;
499     // don't sample cpu less than every 5 seconds.
500     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
501     // wait possibly forever for next cpu sample.
502     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
503     static final boolean MONITOR_THREAD_CPU_USAGE = false;
504
505     // The flags that are set for all calls we make to the package manager.
506     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
507
508     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
509
510     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
511
512     // Amount of time after a call to stopAppSwitches() during which we will
513     // prevent further untrusted switches from happening.
514     static final long APP_SWITCH_DELAY_TIME = 5*1000;
515
516     // How long we wait for a launched process to attach to the activity manager
517     // before we decide it's never going to come up for real.
518     static final int PROC_START_TIMEOUT = 10*1000;
519     // How long we wait for an attached process to publish its content providers
520     // before we decide it must be hung.
521     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
522
523     // How long we wait for a launched process to attach to the activity manager
524     // before we decide it's never going to come up for real, when the process was
525     // started with a wrapper for instrumentation (such as Valgrind) because it
526     // could take much longer than usual.
527     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
528
529     // How long we allow a receiver to run before giving up on it.
530     static final int BROADCAST_FG_TIMEOUT = 10*1000;
531     static final int BROADCAST_BG_TIMEOUT = 60*1000;
532
533     // How long we wait until we timeout on key dispatching.
534     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
535
536     // How long we wait until we timeout on key dispatching during instrumentation.
537     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
538
539     // How long to wait in getAssistContextExtras for the activity and foreground services
540     // to respond with the result.
541     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
542
543     // How long top wait when going through the modern assist (which doesn't need to block
544     // on getting this result before starting to launch its UI).
545     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
546
547     // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
548     static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
549
550     // Maximum number of persisted Uri grants a package is allowed
551     static final int MAX_PERSISTED_URI_GRANTS = 128;
552
553     static final int MY_PID = myPid();
554
555     static final String[] EMPTY_STRING_ARRAY = new String[0];
556
557     // How many bytes to write into the dropbox log before truncating
558     static final int DROPBOX_MAX_SIZE = 192 * 1024;
559     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
560     // as one line, but close enough for now.
561     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
562
563     // Access modes for handleIncomingUser.
564     static final int ALLOW_NON_FULL = 0;
565     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
566     static final int ALLOW_FULL_ONLY = 2;
567
568     // Necessary ApplicationInfo flags to mark an app as persistent
569     private static final int PERSISTENT_MASK =
570             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
571
572     // Intent sent when remote bugreport collection has been completed
573     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
574             "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
575
576     // Used to indicate that an app transition should be animated.
577     static final boolean ANIMATE = true;
578
579     // Determines whether to take full screen screenshots
580     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
581
582     /**
583      * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
584      */
585     private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
586
587     /**
588      * State indicating that there is no need for any blocking for network.
589      */
590     @VisibleForTesting
591     static final int NETWORK_STATE_NO_CHANGE = 0;
592
593     /**
594      * State indicating that the main thread needs to be informed about the network wait.
595      */
596     @VisibleForTesting
597     static final int NETWORK_STATE_BLOCK = 1;
598
599     /**
600      * State indicating that any threads waiting for network state to get updated can be unblocked.
601      */
602     @VisibleForTesting
603     static final int NETWORK_STATE_UNBLOCK = 2;
604
605     // Max character limit for a notification title. If the notification title is larger than this
606     // the notification will not be legible to the user.
607     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
608
609     private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
610
611     /** All system services */
612     SystemServiceManager mSystemServiceManager;
613     AssistUtils mAssistUtils;
614
615     private Installer mInstaller;
616
617     /** Run all ActivityStacks through this */
618     final ActivityStackSupervisor mStackSupervisor;
619     private final KeyguardController mKeyguardController;
620
621     final ActivityStarter mActivityStarter;
622
623     final TaskChangeNotificationController mTaskChangeNotificationController;
624
625     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
626
627     final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
628
629     public final IntentFirewall mIntentFirewall;
630
631     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
632     // default action automatically.  Important for devices without direct input
633     // devices.
634     private boolean mShowDialogs = true;
635
636     private final VrController mVrController;
637
638     // VR Vr2d Display Id.
639     int mVr2dDisplayId = INVALID_DISPLAY;
640
641     // Whether we should use SCHED_FIFO for UI and RenderThreads.
642     private boolean mUseFifoUiScheduling = false;
643
644     BroadcastQueue mFgBroadcastQueue;
645     BroadcastQueue mBgBroadcastQueue;
646     // Convenient for easy iteration over the queues. Foreground is first
647     // so that dispatch of foreground broadcasts gets precedence.
648     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
649
650     BroadcastStats mLastBroadcastStats;
651     BroadcastStats mCurBroadcastStats;
652
653     BroadcastQueue broadcastQueueForIntent(Intent intent) {
654         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
655         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
656                 "Broadcast intent " + intent + " on "
657                 + (isFg ? "foreground" : "background") + " queue");
658         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
659     }
660
661     /**
662      * The last resumed activity. This is identical to the current resumed activity most
663      * of the time but could be different when we're pausing one activity before we resume
664      * another activity.
665      */
666     private ActivityRecord mLastResumedActivity;
667
668     /**
669      * If non-null, we are tracking the time the user spends in the currently focused app.
670      */
671     private AppTimeTracker mCurAppTimeTracker;
672
673     /**
674      * List of intents that were used to start the most recent tasks.
675      */
676     final RecentTasks mRecentTasks;
677
678     /**
679      * For addAppTask: cached of the last activity component that was added.
680      */
681     ComponentName mLastAddedTaskComponent;
682
683     /**
684      * For addAppTask: cached of the last activity uid that was added.
685      */
686     int mLastAddedTaskUid;
687
688     /**
689      * For addAppTask: cached of the last ActivityInfo that was added.
690      */
691     ActivityInfo mLastAddedTaskActivity;
692
693     /**
694      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
695      */
696     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
697
698     /**
699      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
700      */
701     String mDeviceOwnerName;
702
703     final UserController mUserController;
704
705     final AppErrors mAppErrors;
706
707     /**
708      * Dump of the activity state at the time of the last ANR. Cleared after
709      * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
710      */
711     String mLastANRState;
712
713     /**
714      * Indicates the maximum time spent waiting for the network rules to get updated.
715      */
716     @VisibleForTesting
717     long mWaitForNetworkTimeoutMs;
718
719     public boolean canShowErrorDialogs() {
720         return mShowDialogs && !mSleeping && !mShuttingDown
721                 && !mKeyguardController.isKeyguardShowing();
722     }
723
724     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
725             THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
726
727     static void boostPriorityForLockedSection() {
728         sThreadPriorityBooster.boost();
729     }
730
731     static void resetPriorityAfterLockedSection() {
732         sThreadPriorityBooster.reset();
733     }
734
735     public class PendingAssistExtras extends Binder implements Runnable {
736         public final ActivityRecord activity;
737         public boolean isHome;
738         public final Bundle extras;
739         public final Intent intent;
740         public final String hint;
741         public final IResultReceiver receiver;
742         public final int userHandle;
743         public boolean haveResult = false;
744         public Bundle result = null;
745         public AssistStructure structure = null;
746         public AssistContent content = null;
747         public Bundle receiverExtras;
748
749         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
750                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
751             activity = _activity;
752             extras = _extras;
753             intent = _intent;
754             hint = _hint;
755             receiver = _receiver;
756             receiverExtras = _receiverExtras;
757             userHandle = _userHandle;
758         }
759
760         @Override
761         public void run() {
762             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
763             synchronized (this) {
764                 haveResult = true;
765                 notifyAll();
766             }
767             pendingAssistExtrasTimedOut(this);
768         }
769     }
770
771     final ArrayList<PendingAssistExtras> mPendingAssistExtras
772             = new ArrayList<PendingAssistExtras>();
773
774     /**
775      * Process management.
776      */
777     final ProcessList mProcessList = new ProcessList();
778
779     /**
780      * All of the applications we currently have running organized by name.
781      * The keys are strings of the application package name (as
782      * returned by the package manager), and the keys are ApplicationRecord
783      * objects.
784      */
785     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
786
787     /**
788      * Tracking long-term execution of processes to look for abuse and other
789      * bad app behavior.
790      */
791     final ProcessStatsService mProcessStats;
792
793     /**
794      * The currently running isolated processes.
795      */
796     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
797
798     /**
799      * Counter for assigning isolated process uids, to avoid frequently reusing the
800      * same ones.
801      */
802     int mNextIsolatedProcessUid = 0;
803
804     /**
805      * The currently running heavy-weight process, if any.
806      */
807     ProcessRecord mHeavyWeightProcess = null;
808
809     /**
810      * Non-persistent appId whitelist for background restrictions
811      */
812     int[] mBackgroundAppIdWhitelist = new int[] {
813             BLUETOOTH_UID
814     };
815
816     /**
817      * Broadcast actions that will always be deliverable to unlaunched/background apps
818      */
819     ArraySet<String> mBackgroundLaunchBroadcasts;
820
821     /**
822      * All of the processes we currently have running organized by pid.
823      * The keys are the pid running the application.
824      *
825      * <p>NOTE: This object is protected by its own lock, NOT the global
826      * activity manager lock!
827      */
828     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
829
830     /**
831      * All of the processes that have been forced to be important.  The key
832      * is the pid of the caller who requested it (we hold a death
833      * link on it).
834      */
835     abstract class ImportanceToken implements IBinder.DeathRecipient {
836         final int pid;
837         final IBinder token;
838         final String reason;
839
840         ImportanceToken(int _pid, IBinder _token, String _reason) {
841             pid = _pid;
842             token = _token;
843             reason = _reason;
844         }
845
846         @Override
847         public String toString() {
848             return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
849                     + " " + reason + " " + pid + " " + token + " }";
850         }
851     }
852     final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
853
854     /**
855      * List of records for processes that someone had tried to start before the
856      * system was ready.  We don't start them at that point, but ensure they
857      * are started by the time booting is complete.
858      */
859     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
860
861     /**
862      * List of persistent applications that are in the process
863      * of being started.
864      */
865     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
866
867     /**
868      * Processes that are being forcibly torn down.
869      */
870     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
871
872     /**
873      * List of running applications, sorted by recent usage.
874      * The first entry in the list is the least recently used.
875      */
876     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
877
878     /**
879      * Where in mLruProcesses that the processes hosting activities start.
880      */
881     int mLruProcessActivityStart = 0;
882
883     /**
884      * Where in mLruProcesses that the processes hosting services start.
885      * This is after (lower index) than mLruProcessesActivityStart.
886      */
887     int mLruProcessServiceStart = 0;
888
889     /**
890      * List of processes that should gc as soon as things are idle.
891      */
892     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
893
894     /**
895      * Processes we want to collect PSS data from.
896      */
897     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
898
899     private boolean mBinderTransactionTrackingEnabled = false;
900
901     /**
902      * Last time we requested PSS data of all processes.
903      */
904     long mLastFullPssTime = SystemClock.uptimeMillis();
905
906     /**
907      * If set, the next time we collect PSS data we should do a full collection
908      * with data from native processes and the kernel.
909      */
910     boolean mFullPssPending = false;
911
912     /**
913      * This is the process holding what we currently consider to be
914      * the "home" activity.
915      */
916     ProcessRecord mHomeProcess;
917
918     /**
919      * This is the process holding the activity the user last visited that
920      * is in a different process from the one they are currently in.
921      */
922     ProcessRecord mPreviousProcess;
923
924     /**
925      * The time at which the previous process was last visible.
926      */
927     long mPreviousProcessVisibleTime;
928
929     /**
930      * Track all uids that have actively running processes.
931      */
932     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
933
934     /**
935      * This is for verifying the UID report flow.
936      */
937     static final boolean VALIDATE_UID_STATES = true;
938     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
939
940     /**
941      * Packages that the user has asked to have run in screen size
942      * compatibility mode instead of filling the screen.
943      */
944     final CompatModePackages mCompatModePackages;
945
946     /**
947      * Set of IntentSenderRecord objects that are currently active.
948      */
949     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
950             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
951
952     /**
953      * Fingerprints (hashCode()) of stack traces that we've
954      * already logged DropBox entries for.  Guarded by itself.  If
955      * something (rogue user app) forces this over
956      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
957      */
958     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
959     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
960
961     /**
962      * Strict Mode background batched logging state.
963      *
964      * The string buffer is guarded by itself, and its lock is also
965      * used to determine if another batched write is already
966      * in-flight.
967      */
968     private final StringBuilder mStrictModeBuffer = new StringBuilder();
969
970     /**
971      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
972      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
973      */
974     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
975
976     /**
977      * Resolver for broadcast intents to registered receivers.
978      * Holds BroadcastFilter (subclass of IntentFilter).
979      */
980     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
981             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
982         @Override
983         protected boolean allowFilterResult(
984                 BroadcastFilter filter, List<BroadcastFilter> dest) {
985             IBinder target = filter.receiverList.receiver.asBinder();
986             for (int i = dest.size() - 1; i >= 0; i--) {
987                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
988                     return false;
989                 }
990             }
991             return true;
992         }
993
994         @Override
995         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
996             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
997                     || userId == filter.owningUserId) {
998                 return super.newResult(filter, match, userId);
999             }
1000             return null;
1001         }
1002
1003         @Override
1004         protected BroadcastFilter[] newArray(int size) {
1005             return new BroadcastFilter[size];
1006         }
1007
1008         @Override
1009         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1010             return packageName.equals(filter.packageName);
1011         }
1012     };
1013
1014     /**
1015      * State of all active sticky broadcasts per user.  Keys are the action of the
1016      * sticky Intent, values are an ArrayList of all broadcasted intents with
1017      * that action (which should usually be one).  The SparseArray is keyed
1018      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1019      * for stickies that are sent to all users.
1020      */
1021     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1022             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1023
1024     final ActiveServices mServices;
1025
1026     final static class Association {
1027         final int mSourceUid;
1028         final String mSourceProcess;
1029         final int mTargetUid;
1030         final ComponentName mTargetComponent;
1031         final String mTargetProcess;
1032
1033         int mCount;
1034         long mTime;
1035
1036         int mNesting;
1037         long mStartTime;
1038
1039         // states of the source process when the bind occurred.
1040         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1041         long mLastStateUptime;
1042         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1043                 - ActivityManager.MIN_PROCESS_STATE+1];
1044
1045         Association(int sourceUid, String sourceProcess, int targetUid,
1046                 ComponentName targetComponent, String targetProcess) {
1047             mSourceUid = sourceUid;
1048             mSourceProcess = sourceProcess;
1049             mTargetUid = targetUid;
1050             mTargetComponent = targetComponent;
1051             mTargetProcess = targetProcess;
1052         }
1053     }
1054
1055     /**
1056      * When service association tracking is enabled, this is all of the associations we
1057      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1058      * -> association data.
1059      */
1060     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1061             mAssociations = new SparseArray<>();
1062     boolean mTrackingAssociations;
1063
1064     /**
1065      * Backup/restore process management
1066      */
1067     String mBackupAppName = null;
1068     BackupRecord mBackupTarget = null;
1069
1070     final ProviderMap mProviderMap;
1071
1072     /**
1073      * List of content providers who have clients waiting for them.  The
1074      * application is currently being launched and the provider will be
1075      * removed from this list once it is published.
1076      */
1077     final ArrayList<ContentProviderRecord> mLaunchingProviders
1078             = new ArrayList<ContentProviderRecord>();
1079
1080     /**
1081      * File storing persisted {@link #mGrantedUriPermissions}.
1082      */
1083     private final AtomicFile mGrantFile;
1084
1085     /** XML constants used in {@link #mGrantFile} */
1086     private static final String TAG_URI_GRANTS = "uri-grants";
1087     private static final String TAG_URI_GRANT = "uri-grant";
1088     private static final String ATTR_USER_HANDLE = "userHandle";
1089     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1090     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1091     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1092     private static final String ATTR_TARGET_PKG = "targetPkg";
1093     private static final String ATTR_URI = "uri";
1094     private static final String ATTR_MODE_FLAGS = "modeFlags";
1095     private static final String ATTR_CREATED_TIME = "createdTime";
1096     private static final String ATTR_PREFIX = "prefix";
1097
1098     /**
1099      * Global set of specific {@link Uri} permissions that have been granted.
1100      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1101      * to {@link UriPermission#uri} to {@link UriPermission}.
1102      */
1103     @GuardedBy("this")
1104     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1105             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1106
1107     public static class GrantUri {
1108         public final int sourceUserId;
1109         public final Uri uri;
1110         public boolean prefix;
1111
1112         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1113             this.sourceUserId = sourceUserId;
1114             this.uri = uri;
1115             this.prefix = prefix;
1116         }
1117
1118         @Override
1119         public int hashCode() {
1120             int hashCode = 1;
1121             hashCode = 31 * hashCode + sourceUserId;
1122             hashCode = 31 * hashCode + uri.hashCode();
1123             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1124             return hashCode;
1125         }
1126
1127         @Override
1128         public boolean equals(Object o) {
1129             if (o instanceof GrantUri) {
1130                 GrantUri other = (GrantUri) o;
1131                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1132                         && prefix == other.prefix;
1133             }
1134             return false;
1135         }
1136
1137         @Override
1138         public String toString() {
1139             String result = uri.toString() + " [user " + sourceUserId + "]";
1140             if (prefix) result += " [prefix]";
1141             return result;
1142         }
1143
1144         public String toSafeString() {
1145             String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1146             if (prefix) result += " [prefix]";
1147             return result;
1148         }
1149
1150         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1151             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1152                     ContentProvider.getUriWithoutUserId(uri), false);
1153         }
1154     }
1155
1156     CoreSettingsObserver mCoreSettingsObserver;
1157
1158     FontScaleSettingObserver mFontScaleSettingObserver;
1159
1160     private final class FontScaleSettingObserver extends ContentObserver {
1161         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1162
1163         public FontScaleSettingObserver() {
1164             super(mHandler);
1165             ContentResolver resolver = mContext.getContentResolver();
1166             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1167         }
1168
1169         @Override
1170         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1171             if (mFontScaleUri.equals(uri)) {
1172                 updateFontScaleIfNeeded(userId);
1173             }
1174         }
1175     }
1176
1177     /**
1178      * Thread-local storage used to carry caller permissions over through
1179      * indirect content-provider access.
1180      */
1181     private class Identity {
1182         public final IBinder token;
1183         public final int pid;
1184         public final int uid;
1185
1186         Identity(IBinder _token, int _pid, int _uid) {
1187             token = _token;
1188             pid = _pid;
1189             uid = _uid;
1190         }
1191     }
1192
1193     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1194
1195     /**
1196      * All information we have collected about the runtime performance of
1197      * any user id that can impact battery performance.
1198      */
1199     final BatteryStatsService mBatteryStatsService;
1200
1201     /**
1202      * Information about component usage
1203      */
1204     UsageStatsManagerInternal mUsageStatsService;
1205
1206     /**
1207      * Access to DeviceIdleController service.
1208      */
1209     DeviceIdleController.LocalService mLocalDeviceIdleController;
1210
1211     /**
1212      * Set of app ids that are whitelisted for device idle and thus background check.
1213      */
1214     int[] mDeviceIdleWhitelist = new int[0];
1215
1216     /**
1217      * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1218      */
1219     int[] mDeviceIdleTempWhitelist = new int[0];
1220
1221     static final class PendingTempWhitelist {
1222         final int targetUid;
1223         final long duration;
1224         final String tag;
1225
1226         PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1227             targetUid = _targetUid;
1228             duration = _duration;
1229             tag = _tag;
1230         }
1231     }
1232
1233     final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1234
1235     /**
1236      * Information about and control over application operations
1237      */
1238     final AppOpsService mAppOpsService;
1239
1240     /** Current sequencing integer of the configuration, for skipping old configurations. */
1241     private int mConfigurationSeq;
1242
1243     /**
1244      * Temp object used when global and/or display override configuration is updated. It is also
1245      * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1246      * anyone...
1247      */
1248     private Configuration mTempConfig = new Configuration();
1249
1250     private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1251             new UpdateConfigurationResult();
1252     private static final class UpdateConfigurationResult {
1253         // Configuration changes that were updated.
1254         int changes;
1255         // If the activity was relaunched to match the new configuration.
1256         boolean activityRelaunched;
1257
1258         void reset() {
1259             changes = 0;
1260             activityRelaunched = false;
1261         }
1262     }
1263
1264     boolean mSuppressResizeConfigChanges;
1265
1266     /**
1267      * Hardware-reported OpenGLES version.
1268      */
1269     final int GL_ES_VERSION;
1270
1271     /**
1272      * List of initialization arguments to pass to all processes when binding applications to them.
1273      * For example, references to the commonly used services.
1274      */
1275     HashMap<String, IBinder> mAppBindArgs;
1276     HashMap<String, IBinder> mIsolatedAppBindArgs;
1277
1278     /**
1279      * Temporary to avoid allocations.  Protected by main lock.
1280      */
1281     final StringBuilder mStringBuilder = new StringBuilder(256);
1282
1283     /**
1284      * Used to control how we initialize the service.
1285      */
1286     ComponentName mTopComponent;
1287     String mTopAction = Intent.ACTION_MAIN;
1288     String mTopData;
1289
1290     volatile boolean mProcessesReady = false;
1291     volatile boolean mSystemReady = false;
1292     volatile boolean mOnBattery = false;
1293     volatile int mFactoryTest;
1294
1295     @GuardedBy("this") boolean mBooting = false;
1296     @GuardedBy("this") boolean mCallFinishBooting = false;
1297     @GuardedBy("this") boolean mBootAnimationComplete = false;
1298     @GuardedBy("this") boolean mLaunchWarningShown = false;
1299     @GuardedBy("this") boolean mCheckedForSetup = false;
1300
1301     final Context mContext;
1302
1303     /**
1304      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1305      * change at runtime. Use mContext for non-UI purposes.
1306      */
1307     final Context mUiContext;
1308
1309     /**
1310      * The time at which we will allow normal application switches again,
1311      * after a call to {@link #stopAppSwitches()}.
1312      */
1313     long mAppSwitchesAllowedTime;
1314
1315     /**
1316      * This is set to true after the first switch after mAppSwitchesAllowedTime
1317      * is set; any switches after that will clear the time.
1318      */
1319     boolean mDidAppSwitch;
1320
1321     /**
1322      * Last time (in realtime) at which we checked for power usage.
1323      */
1324     long mLastPowerCheckRealtime;
1325
1326     /**
1327      * Last time (in uptime) at which we checked for power usage.
1328      */
1329     long mLastPowerCheckUptime;
1330
1331     /**
1332      * Set while we are wanting to sleep, to prevent any
1333      * activities from being started/resumed.
1334      *
1335      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1336      *
1337      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1338      * while in the sleep state until there is a pending transition out of sleep, in which case
1339      * mSleeping is set to false, and remains false while awake.
1340      *
1341      * Whether mSleeping can quickly toggled between true/false without the device actually
1342      * display changing states is undefined.
1343      */
1344     private boolean mSleeping = false;
1345
1346     /**
1347      * The process state used for processes that are running the top activities.
1348      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1349      */
1350     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1351
1352     /**
1353      * Set while we are running a voice interaction.  This overrides
1354      * sleeping while it is active.
1355      */
1356     private IVoiceInteractionSession mRunningVoice;
1357
1358     /**
1359      * For some direct access we need to power manager.
1360      */
1361     PowerManagerInternal mLocalPowerManager;
1362
1363     /**
1364      * We want to hold a wake lock while running a voice interaction session, since
1365      * this may happen with the screen off and we need to keep the CPU running to
1366      * be able to continue to interact with the user.
1367      */
1368     PowerManager.WakeLock mVoiceWakeLock;
1369
1370     /**
1371      * State of external calls telling us if the device is awake or asleep.
1372      */
1373     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1374
1375     /**
1376      * A list of tokens that cause the top activity to be put to sleep.
1377      * They are used by components that may hide and block interaction with underlying
1378      * activities.
1379      */
1380     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1381
1382     /**
1383      * Set if we are shutting down the system, similar to sleeping.
1384      */
1385     boolean mShuttingDown = false;
1386
1387     /**
1388      * Current sequence id for oom_adj computation traversal.
1389      */
1390     int mAdjSeq = 0;
1391
1392     /**
1393      * Current sequence id for process LRU updating.
1394      */
1395     int mLruSeq = 0;
1396
1397     /**
1398      * Keep track of the non-cached/empty process we last found, to help
1399      * determine how to distribute cached/empty processes next time.
1400      */
1401     int mNumNonCachedProcs = 0;
1402
1403     /**
1404      * Keep track of the number of cached hidden procs, to balance oom adj
1405      * distribution between those and empty procs.
1406      */
1407     int mNumCachedHiddenProcs = 0;
1408
1409     /**
1410      * Keep track of the number of service processes we last found, to
1411      * determine on the next iteration which should be B services.
1412      */
1413     int mNumServiceProcs = 0;
1414     int mNewNumAServiceProcs = 0;
1415     int mNewNumServiceProcs = 0;
1416
1417     /**
1418      * Allow the current computed overall memory level of the system to go down?
1419      * This is set to false when we are killing processes for reasons other than
1420      * memory management, so that the now smaller process list will not be taken as
1421      * an indication that memory is tighter.
1422      */
1423     boolean mAllowLowerMemLevel = false;
1424
1425     /**
1426      * The last computed memory level, for holding when we are in a state that
1427      * processes are going away for other reasons.
1428      */
1429     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1430
1431     /**
1432      * The last total number of process we have, to determine if changes actually look
1433      * like a shrinking number of process due to lower RAM.
1434      */
1435     int mLastNumProcesses;
1436
1437     /**
1438      * The uptime of the last time we performed idle maintenance.
1439      */
1440     long mLastIdleTime = SystemClock.uptimeMillis();
1441
1442     /**
1443      * Total time spent with RAM that has been added in the past since the last idle time.
1444      */
1445     long mLowRamTimeSinceLastIdle = 0;
1446
1447     /**
1448      * If RAM is currently low, when that horrible situation started.
1449      */
1450     long mLowRamStartTime = 0;
1451
1452     /**
1453      * For reporting to battery stats the current top application.
1454      */
1455     private String mCurResumedPackage = null;
1456     private int mCurResumedUid = -1;
1457
1458     /**
1459      * For reporting to battery stats the apps currently running foreground
1460      * service.  The ProcessMap is package/uid tuples; each of these contain
1461      * an array of the currently foreground processes.
1462      */
1463     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1464             = new ProcessMap<ArrayList<ProcessRecord>>();
1465
1466     /**
1467      * Set if the systemServer made a call to enterSafeMode.
1468      */
1469     boolean mSafeMode;
1470
1471     /**
1472      * If true, we are running under a test environment so will sample PSS from processes
1473      * much more rapidly to try to collect better data when the tests are rapidly
1474      * running through apps.
1475      */
1476     boolean mTestPssMode = false;
1477
1478     String mDebugApp = null;
1479     boolean mWaitForDebugger = false;
1480     boolean mDebugTransient = false;
1481     String mOrigDebugApp = null;
1482     boolean mOrigWaitForDebugger = false;
1483     boolean mAlwaysFinishActivities = false;
1484     boolean mForceResizableActivities;
1485     /**
1486      * Flag that indicates if multi-window is enabled.
1487      *
1488      * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1489      * in {@link com.android.internal.R.bool.config_supportsMultiWindow} config or
1490      * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1491      * At least one of the forms of multi-window must be enabled in order for this flag to be
1492      * initialized to 'true'.
1493      *
1494      * @see #mSupportsSplitScreenMultiWindow
1495      * @see #mSupportsFreeformWindowManagement
1496      * @see #mSupportsPictureInPicture
1497      * @see #mSupportsMultiDisplay
1498      */
1499     boolean mSupportsMultiWindow;
1500     boolean mSupportsSplitScreenMultiWindow;
1501     boolean mSupportsFreeformWindowManagement;
1502     boolean mSupportsPictureInPicture;
1503     boolean mSupportsMultiDisplay;
1504     boolean mSupportsLeanbackOnly;
1505     IActivityController mController = null;
1506     boolean mControllerIsAMonkey = false;
1507     String mProfileApp = null;
1508     ProcessRecord mProfileProc = null;
1509     String mProfileFile;
1510     ParcelFileDescriptor mProfileFd;
1511     int mSamplingInterval = 0;
1512     boolean mAutoStopProfiler = false;
1513     boolean mStreamingOutput = false;
1514     int mProfileType = 0;
1515     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1516     String mMemWatchDumpProcName;
1517     String mMemWatchDumpFile;
1518     int mMemWatchDumpPid;
1519     int mMemWatchDumpUid;
1520     String mTrackAllocationApp = null;
1521     String mNativeDebuggingApp = null;
1522
1523     final long[] mTmpLong = new long[2];
1524
1525     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1526
1527     /**
1528      * A global counter for generating sequence numbers.
1529      * This value will be used when incrementing sequence numbers in individual uidRecords.
1530      *
1531      * Having a global counter ensures that seq numbers are monotonically increasing for a
1532      * particular uid even when the uidRecord is re-created.
1533      */
1534     @GuardedBy("this")
1535     @VisibleForTesting
1536     long mProcStateSeqCounter = 0;
1537
1538     private final Injector mInjector;
1539
1540     static final class ProcessChangeItem {
1541         static final int CHANGE_ACTIVITIES = 1<<0;
1542         int changes;
1543         int uid;
1544         int pid;
1545         int processState;
1546         boolean foregroundActivities;
1547     }
1548
1549     static final class UidObserverRegistration {
1550         final int uid;
1551         final String pkg;
1552         final int which;
1553         final int cutpoint;
1554
1555         final SparseIntArray lastProcStates;
1556
1557         UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1558             uid = _uid;
1559             pkg = _pkg;
1560             which = _which;
1561             cutpoint = _cutpoint;
1562             if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1563                 lastProcStates = new SparseIntArray();
1564             } else {
1565                 lastProcStates = null;
1566             }
1567         }
1568     }
1569
1570     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1571     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1572
1573     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1574     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1575
1576     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1577     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1578
1579     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1580     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1581
1582     /**
1583      * Runtime CPU use collection thread.  This object's lock is used to
1584      * perform synchronization with the thread (notifying it to run).
1585      */
1586     final Thread mProcessCpuThread;
1587
1588     /**
1589      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1590      * Must acquire this object's lock when accessing it.
1591      * NOTE: this lock will be held while doing long operations (trawling
1592      * through all processes in /proc), so it should never be acquired by
1593      * any critical paths such as when holding the main activity manager lock.
1594      */
1595     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1596             MONITOR_THREAD_CPU_USAGE);
1597     final AtomicLong mLastCpuTime = new AtomicLong(0);
1598     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1599     final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1600
1601     long mLastWriteTime = 0;
1602
1603     /**
1604      * Used to retain an update lock when the foreground activity is in
1605      * immersive mode.
1606      */
1607     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1608
1609     /**
1610      * Set to true after the system has finished booting.
1611      */
1612     boolean mBooted = false;
1613
1614     WindowManagerService mWindowManager;
1615     final ActivityThread mSystemThread;
1616
1617     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1618         final ProcessRecord mApp;
1619         final int mPid;
1620         final IApplicationThread mAppThread;
1621
1622         AppDeathRecipient(ProcessRecord app, int pid,
1623                 IApplicationThread thread) {
1624             if (DEBUG_ALL) Slog.v(
1625                 TAG, "New death recipient " + this
1626                 + " for thread " + thread.asBinder());
1627             mApp = app;
1628             mPid = pid;
1629             mAppThread = thread;
1630         }
1631
1632         @Override
1633         public void binderDied() {
1634             if (DEBUG_ALL) Slog.v(
1635                 TAG, "Death received in " + this
1636                 + " for thread " + mAppThread.asBinder());
1637             synchronized(ActivityManagerService.this) {
1638                 appDiedLocked(mApp, mPid, mAppThread, true);
1639             }
1640         }
1641     }
1642
1643     static final int SHOW_ERROR_UI_MSG = 1;
1644     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1645     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1646     static final int UPDATE_CONFIGURATION_MSG = 4;
1647     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1648     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1649     static final int SERVICE_TIMEOUT_MSG = 12;
1650     static final int UPDATE_TIME_ZONE = 13;
1651     static final int SHOW_UID_ERROR_UI_MSG = 14;
1652     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1653     static final int PROC_START_TIMEOUT_MSG = 20;
1654     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1655     static final int KILL_APPLICATION_MSG = 22;
1656     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1657     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1658     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1659     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1660     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1661     static final int CLEAR_DNS_CACHE_MSG = 28;
1662     static final int UPDATE_HTTP_PROXY_MSG = 29;
1663     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1664     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1665     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1666     static final int REPORT_MEM_USAGE_MSG = 33;
1667     static final int REPORT_USER_SWITCH_MSG = 34;
1668     static final int CONTINUE_USER_SWITCH_MSG = 35;
1669     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1670     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1671     static final int PERSIST_URI_GRANTS_MSG = 38;
1672     static final int REQUEST_ALL_PSS_MSG = 39;
1673     static final int START_PROFILES_MSG = 40;
1674     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1675     static final int SYSTEM_USER_START_MSG = 42;
1676     static final int SYSTEM_USER_CURRENT_MSG = 43;
1677     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1678     static final int FINISH_BOOTING_MSG = 45;
1679     static final int START_USER_SWITCH_UI_MSG = 46;
1680     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1681     static final int DISMISS_DIALOG_UI_MSG = 48;
1682     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1683     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1684     static final int DELETE_DUMPHEAP_MSG = 51;
1685     static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1686     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1687     static final int REPORT_TIME_TRACKER_MSG = 54;
1688     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1689     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1690     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1691     static final int IDLE_UIDS_MSG = 58;
1692     static final int SYSTEM_USER_UNLOCK_MSG = 59;
1693     static final int LOG_STACK_STATE = 60;
1694     static final int VR_MODE_CHANGE_MSG = 61;
1695     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1696     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1697     static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1698     static final int NOTIFY_VR_SLEEPING_MSG = 65;
1699     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1700     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1701     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1702     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1703     static final int START_USER_SWITCH_FG_MSG = 712;
1704
1705     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1706     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1707     static final int FIRST_COMPAT_MODE_MSG = 300;
1708     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1709
1710     static ServiceThread sKillThread = null;
1711     static KillHandler sKillHandler = null;
1712
1713     CompatModeDialog mCompatModeDialog;
1714     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1715     long mLastMemUsageReportTime = 0;
1716
1717     /**
1718      * Flag whether the current user is a "monkey", i.e. whether
1719      * the UI is driven by a UI automation tool.
1720      */
1721     private boolean mUserIsMonkey;
1722
1723     /** Flag whether the device has a Recents UI */
1724     boolean mHasRecents;
1725
1726     /** The dimensions of the thumbnails in the Recents UI. */
1727     int mThumbnailWidth;
1728     int mThumbnailHeight;
1729     float mFullscreenThumbnailScale;
1730
1731     final ServiceThread mHandlerThread;
1732     final MainHandler mHandler;
1733     final Handler mUiHandler;
1734
1735     final ActivityManagerConstants mConstants;
1736
1737     PackageManagerInternal mPackageManagerInt;
1738
1739     // VoiceInteraction session ID that changes for each new request except when
1740     // being called for multiwindow assist in a single session.
1741     private int mViSessionId = 1000;
1742
1743     final boolean mPermissionReviewRequired;
1744
1745     /**
1746      * Current global configuration information. Contains general settings for the entire system,
1747      * also corresponds to the merged configuration of the default display.
1748      */
1749     Configuration getGlobalConfiguration() {
1750         return mStackSupervisor.getConfiguration();
1751     }
1752
1753     final class KillHandler extends Handler {
1754         static final int KILL_PROCESS_GROUP_MSG = 4000;
1755
1756         public KillHandler(Looper looper) {
1757             super(looper, null, true);
1758         }
1759
1760         @Override
1761         public void handleMessage(Message msg) {
1762             switch (msg.what) {
1763                 case KILL_PROCESS_GROUP_MSG:
1764                 {
1765                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1766                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1767                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1768                 }
1769                 break;
1770
1771                 default:
1772                     super.handleMessage(msg);
1773             }
1774         }
1775     }
1776
1777     final class UiHandler extends Handler {
1778         public UiHandler() {
1779             super(com.android.server.UiThread.get().getLooper(), null, true);
1780         }
1781
1782         @Override
1783         public void handleMessage(Message msg) {
1784             switch (msg.what) {
1785             case SHOW_ERROR_UI_MSG: {
1786                 mAppErrors.handleShowAppErrorUi(msg);
1787                 ensureBootCompleted();
1788             } break;
1789             case SHOW_NOT_RESPONDING_UI_MSG: {
1790                 mAppErrors.handleShowAnrUi(msg);
1791                 ensureBootCompleted();
1792             } break;
1793             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1794                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1795                 synchronized (ActivityManagerService.this) {
1796                     ProcessRecord proc = (ProcessRecord) data.get("app");
1797                     if (proc == null) {
1798                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1799                         break;
1800                     }
1801                     if (proc.crashDialog != null) {
1802                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1803                         return;
1804                     }
1805                     AppErrorResult res = (AppErrorResult) data.get("result");
1806                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1807                         Dialog d = new StrictModeViolationDialog(mUiContext,
1808                                 ActivityManagerService.this, res, proc);
1809                         d.show();
1810                         proc.crashDialog = d;
1811                     } else {
1812                         // The device is asleep, so just pretend that the user
1813                         // saw a crash dialog and hit "force quit".
1814                         res.set(0);
1815                     }
1816                 }
1817                 ensureBootCompleted();
1818             } break;
1819             case SHOW_FACTORY_ERROR_UI_MSG: {
1820                 Dialog d = new FactoryErrorDialog(
1821                         mUiContext, msg.getData().getCharSequence("msg"));
1822                 d.show();
1823                 ensureBootCompleted();
1824             } break;
1825             case WAIT_FOR_DEBUGGER_UI_MSG: {
1826                 synchronized (ActivityManagerService.this) {
1827                     ProcessRecord app = (ProcessRecord)msg.obj;
1828                     if (msg.arg1 != 0) {
1829                         if (!app.waitedForDebugger) {
1830                             Dialog d = new AppWaitingForDebuggerDialog(
1831                                     ActivityManagerService.this,
1832                                     mUiContext, app);
1833                             app.waitDialog = d;
1834                             app.waitedForDebugger = true;
1835                             d.show();
1836                         }
1837                     } else {
1838                         if (app.waitDialog != null) {
1839                             app.waitDialog.dismiss();
1840                             app.waitDialog = null;
1841                         }
1842                     }
1843                 }
1844             } break;
1845             case SHOW_UID_ERROR_UI_MSG: {
1846                 if (mShowDialogs) {
1847                     AlertDialog d = new BaseErrorDialog(mUiContext);
1848                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1849                     d.setCancelable(false);
1850                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1851                     d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1852                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1853                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1854                     d.show();
1855                 }
1856             } break;
1857             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1858                 if (mShowDialogs) {
1859                     AlertDialog d = new BaseErrorDialog(mUiContext);
1860                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1861                     d.setCancelable(false);
1862                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1863                     d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1864                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1865                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1866                     d.show();
1867                 }
1868             } break;
1869             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1870                 synchronized (ActivityManagerService.this) {
1871                     ActivityRecord ar = (ActivityRecord) msg.obj;
1872                     if (mCompatModeDialog != null) {
1873                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1874                                 ar.info.applicationInfo.packageName)) {
1875                             return;
1876                         }
1877                         mCompatModeDialog.dismiss();
1878                         mCompatModeDialog = null;
1879                     }
1880                     if (ar != null && false) {
1881                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1882                                 ar.packageName)) {
1883                             int mode = mCompatModePackages.computeCompatModeLocked(
1884                                     ar.info.applicationInfo);
1885                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1886                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1887                                 mCompatModeDialog = new CompatModeDialog(
1888                                         ActivityManagerService.this, mUiContext,
1889                                         ar.info.applicationInfo);
1890                                 mCompatModeDialog.show();
1891                             }
1892                         }
1893                     }
1894                 }
1895                 break;
1896             }
1897             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1898                 synchronized (ActivityManagerService.this) {
1899                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1900                     if (mUnsupportedDisplaySizeDialog != null) {
1901                         mUnsupportedDisplaySizeDialog.dismiss();
1902                         mUnsupportedDisplaySizeDialog = null;
1903                     }
1904                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1905                             ar.packageName)) {
1906                         // TODO(multi-display): Show dialog on appropriate display.
1907                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1908                                 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1909                         mUnsupportedDisplaySizeDialog.show();
1910                     }
1911                 }
1912                 break;
1913             }
1914             case START_USER_SWITCH_UI_MSG: {
1915                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1916                 break;
1917             }
1918             case DISMISS_DIALOG_UI_MSG: {
1919                 final Dialog d = (Dialog) msg.obj;
1920                 d.dismiss();
1921                 break;
1922             }
1923             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1924                 dispatchProcessesChanged();
1925                 break;
1926             }
1927             case DISPATCH_PROCESS_DIED_UI_MSG: {
1928                 final int pid = msg.arg1;
1929                 final int uid = msg.arg2;
1930                 dispatchProcessDied(pid, uid);
1931                 break;
1932             }
1933             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1934                 dispatchUidsChanged();
1935             } break;
1936             case PUSH_TEMP_WHITELIST_UI_MSG: {
1937                 pushTempWhitelist();
1938             } break;
1939             }
1940         }
1941     }
1942
1943     final class MainHandler extends Handler {
1944         public MainHandler(Looper looper) {
1945             super(looper, null, true);
1946         }
1947
1948         @Override
1949         public void handleMessage(Message msg) {
1950             switch (msg.what) {
1951             case UPDATE_CONFIGURATION_MSG: {
1952                 final ContentResolver resolver = mContext.getContentResolver();
1953                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1954                         msg.arg1);
1955             } break;
1956             case GC_BACKGROUND_PROCESSES_MSG: {
1957                 synchronized (ActivityManagerService.this) {
1958                     performAppGcsIfAppropriateLocked();
1959                 }
1960             } break;
1961             case SERVICE_TIMEOUT_MSG: {
1962                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1963             } break;
1964             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1965                 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1966             } break;
1967             case SERVICE_FOREGROUND_CRASH_MSG: {
1968                 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1969             } break;
1970             case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1971                 RemoteCallbackList<IResultReceiver> callbacks
1972                         = (RemoteCallbackList<IResultReceiver>)msg.obj;
1973                 int N = callbacks.beginBroadcast();
1974                 for (int i = 0; i < N; i++) {
1975                     try {
1976                         callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1977                     } catch (RemoteException e) {
1978                     }
1979                 }
1980                 callbacks.finishBroadcast();
1981             } break;
1982             case UPDATE_TIME_ZONE: {
1983                 synchronized (ActivityManagerService.this) {
1984                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1985                         ProcessRecord r = mLruProcesses.get(i);
1986                         if (r.thread != null) {
1987                             try {
1988                                 r.thread.updateTimeZone();
1989                             } catch (RemoteException ex) {
1990                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1991                             }
1992                         }
1993                     }
1994                 }
1995             } break;
1996             case CLEAR_DNS_CACHE_MSG: {
1997                 synchronized (ActivityManagerService.this) {
1998                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1999                         ProcessRecord r = mLruProcesses.get(i);
2000                         if (r.thread != null) {
2001                             try {
2002                                 r.thread.clearDnsCache();
2003                             } catch (RemoteException ex) {
2004                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2005                             }
2006                         }
2007                     }
2008                 }
2009             } break;
2010             case UPDATE_HTTP_PROXY_MSG: {
2011                 ProxyInfo proxy = (ProxyInfo)msg.obj;
2012                 String host = "";
2013                 String port = "";
2014                 String exclList = "";
2015                 Uri pacFileUrl = Uri.EMPTY;
2016                 if (proxy != null) {
2017                     host = proxy.getHost();
2018                     port = Integer.toString(proxy.getPort());
2019                     exclList = proxy.getExclusionListAsString();
2020                     pacFileUrl = proxy.getPacFileUrl();
2021                 }
2022                 synchronized (ActivityManagerService.this) {
2023                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2024                         ProcessRecord r = mLruProcesses.get(i);
2025                         if (r.thread != null) {
2026                             try {
2027                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2028                             } catch (RemoteException ex) {
2029                                 Slog.w(TAG, "Failed to update http proxy for: " +
2030                                         r.info.processName);
2031                             }
2032                         }
2033                     }
2034                 }
2035             } break;
2036             case PROC_START_TIMEOUT_MSG: {
2037                 ProcessRecord app = (ProcessRecord)msg.obj;
2038                 synchronized (ActivityManagerService.this) {
2039                     processStartTimedOutLocked(app);
2040                 }
2041             } break;
2042             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2043                 ProcessRecord app = (ProcessRecord)msg.obj;
2044                 synchronized (ActivityManagerService.this) {
2045                     processContentProviderPublishTimedOutLocked(app);
2046                 }
2047             } break;
2048             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2049                 synchronized (ActivityManagerService.this) {
2050                     mActivityStarter.doPendingActivityLaunchesLocked(true);
2051                 }
2052             } break;
2053             case KILL_APPLICATION_MSG: {
2054                 synchronized (ActivityManagerService.this) {
2055                     final int appId = msg.arg1;
2056                     final int userId = msg.arg2;
2057                     Bundle bundle = (Bundle)msg.obj;
2058                     String pkg = bundle.getString("pkg");
2059                     String reason = bundle.getString("reason");
2060                     forceStopPackageLocked(pkg, appId, false, false, true, false,
2061                             false, userId, reason);
2062                 }
2063             } break;
2064             case FINALIZE_PENDING_INTENT_MSG: {
2065                 ((PendingIntentRecord)msg.obj).completeFinalize();
2066             } break;
2067             case POST_HEAVY_NOTIFICATION_MSG: {
2068                 INotificationManager inm = NotificationManager.getService();
2069                 if (inm == null) {
2070                     return;
2071                 }
2072
2073                 ActivityRecord root = (ActivityRecord)msg.obj;
2074                 ProcessRecord process = root.app;
2075                 if (process == null) {
2076                     return;
2077                 }
2078
2079                 try {
2080                     Context context = mContext.createPackageContext(process.info.packageName, 0);
2081                     String text = mContext.getString(R.string.heavy_weight_notification,
2082                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
2083                     Notification notification =
2084                             new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2085                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2086                             .setWhen(0)
2087                             .setOngoing(true)
2088                             .setTicker(text)
2089                             .setColor(mContext.getColor(
2090                                     com.android.internal.R.color.system_notification_accent_color))
2091                             .setContentTitle(text)
2092                             .setContentText(
2093                                     mContext.getText(R.string.heavy_weight_notification_detail))
2094                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2095                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2096                                     new UserHandle(root.userId)))
2097                             .build();
2098                     try {
2099                         inm.enqueueNotificationWithTag("android", "android", null,
2100                                 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2101                                 notification, root.userId);
2102                     } catch (RuntimeException e) {
2103                         Slog.w(ActivityManagerService.TAG,
2104                                 "Error showing notification for heavy-weight app", e);
2105                     } catch (RemoteException e) {
2106                     }
2107                 } catch (NameNotFoundException e) {
2108                     Slog.w(TAG, "Unable to create context for heavy notification", e);
2109                 }
2110             } break;
2111             case CANCEL_HEAVY_NOTIFICATION_MSG: {
2112                 INotificationManager inm = NotificationManager.getService();
2113                 if (inm == null) {
2114                     return;
2115                 }
2116                 try {
2117                     inm.cancelNotificationWithTag("android", null,
2118                             SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2119                 } catch (RuntimeException e) {
2120                     Slog.w(ActivityManagerService.TAG,
2121                             "Error canceling notification for service", e);
2122                 } catch (RemoteException e) {
2123                 }
2124             } break;
2125             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2126                 synchronized (ActivityManagerService.this) {
2127                     checkExcessivePowerUsageLocked(true);
2128                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2129                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2130                     sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
2131                 }
2132             } break;
2133             case REPORT_MEM_USAGE_MSG: {
2134                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2135                 Thread thread = new Thread() {
2136                     @Override public void run() {
2137                         reportMemUsage(memInfos);
2138                     }
2139                 };
2140                 thread.start();
2141                 break;
2142             }
2143             case START_USER_SWITCH_FG_MSG: {
2144                 mUserController.startUserInForeground(msg.arg1);
2145                 break;
2146             }
2147             case REPORT_USER_SWITCH_MSG: {
2148                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2149                 break;
2150             }
2151             case CONTINUE_USER_SWITCH_MSG: {
2152                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2153                 break;
2154             }
2155             case USER_SWITCH_TIMEOUT_MSG: {
2156                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2157                 break;
2158             }
2159             case IMMERSIVE_MODE_LOCK_MSG: {
2160                 final boolean nextState = (msg.arg1 != 0);
2161                 if (mUpdateLock.isHeld() != nextState) {
2162                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2163                             "Applying new update lock state '" + nextState
2164                             + "' for " + (ActivityRecord)msg.obj);
2165                     if (nextState) {
2166                         mUpdateLock.acquire();
2167                     } else {
2168                         mUpdateLock.release();
2169                     }
2170                 }
2171                 break;
2172             }
2173             case PERSIST_URI_GRANTS_MSG: {
2174                 writeGrantedUriPermissions();
2175                 break;
2176             }
2177             case REQUEST_ALL_PSS_MSG: {
2178                 synchronized (ActivityManagerService.this) {
2179                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2180                 }
2181                 break;
2182             }
2183             case START_PROFILES_MSG: {
2184                 synchronized (ActivityManagerService.this) {
2185                     mUserController.startProfilesLocked();
2186                 }
2187                 break;
2188             }
2189             case UPDATE_TIME_PREFERENCE_MSG: {
2190                 // The user's time format preference might have changed.
2191                 // For convenience we re-use the Intent extra values.
2192                 synchronized (ActivityManagerService.this) {
2193                     for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2194                         ProcessRecord r = mLruProcesses.get(i);
2195                         if (r.thread != null) {
2196                             try {
2197                                 r.thread.updateTimePrefs(msg.arg1);
2198                             } catch (RemoteException ex) {
2199                                 Slog.w(TAG, "Failed to update preferences for: "
2200                                         + r.info.processName);
2201                             }
2202                         }
2203                     }
2204                 }
2205                 break;
2206             }
2207             case SYSTEM_USER_START_MSG: {
2208                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2209                         Integer.toString(msg.arg1), msg.arg1);
2210                 mSystemServiceManager.startUser(msg.arg1);
2211                 break;
2212             }
2213             case SYSTEM_USER_UNLOCK_MSG: {
2214                 final int userId = msg.arg1;
2215                 mSystemServiceManager.unlockUser(userId);
2216                 synchronized (ActivityManagerService.this) {
2217                     mRecentTasks.loadUserRecentsLocked(userId);
2218                 }
2219                 if (userId == UserHandle.USER_SYSTEM) {
2220                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2221                 }
2222                 installEncryptionUnawareProviders(userId);
2223                 mUserController.finishUserUnlocked((UserState) msg.obj);
2224                 break;
2225             }
2226             case SYSTEM_USER_CURRENT_MSG: {
2227                 mBatteryStatsService.noteEvent(
2228                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2229                         Integer.toString(msg.arg2), msg.arg2);
2230                 mBatteryStatsService.noteEvent(
2231                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2232                         Integer.toString(msg.arg1), msg.arg1);
2233                 mSystemServiceManager.switchUser(msg.arg1);
2234                 break;
2235             }
2236             case ENTER_ANIMATION_COMPLETE_MSG: {
2237                 synchronized (ActivityManagerService.this) {
2238                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2239                     if (r != null && r.app != null && r.app.thread != null) {
2240                         try {
2241                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2242                         } catch (RemoteException e) {
2243                         }
2244                     }
2245                 }
2246                 break;
2247             }
2248             case FINISH_BOOTING_MSG: {
2249                 if (msg.arg1 != 0) {
2250                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2251                     finishBooting();
2252                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2253                 }
2254                 if (msg.arg2 != 0) {
2255                     enableScreenAfterBoot();
2256                 }
2257                 break;
2258             }
2259             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2260                 try {
2261                     Locale l = (Locale) msg.obj;
2262                     IBinder service = ServiceManager.getService("mount");
2263                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2264                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2265                     storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2266                 } catch (RemoteException e) {
2267                     Log.e(TAG, "Error storing locale for decryption UI", e);
2268                 }
2269                 break;
2270             }
2271             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2272                 final int uid = msg.arg1;
2273                 final byte[] firstPacket = (byte[]) msg.obj;
2274
2275                 synchronized (mPidsSelfLocked) {
2276                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2277                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2278                         if (p.uid == uid) {
2279                             try {
2280                                 p.thread.notifyCleartextNetwork(firstPacket);
2281                             } catch (RemoteException ignored) {
2282                             }
2283                         }
2284                     }
2285                 }
2286                 break;
2287             }
2288             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2289                 final String procName;
2290                 final int uid;
2291                 final long memLimit;
2292                 final String reportPackage;
2293                 synchronized (ActivityManagerService.this) {
2294                     procName = mMemWatchDumpProcName;
2295                     uid = mMemWatchDumpUid;
2296                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2297                     if (val == null) {
2298                         val = mMemWatchProcesses.get(procName, 0);
2299                     }
2300                     if (val != null) {
2301                         memLimit = val.first;
2302                         reportPackage = val.second;
2303                     } else {
2304                         memLimit = 0;
2305                         reportPackage = null;
2306                     }
2307                 }
2308                 if (procName == null) {
2309                     return;
2310                 }
2311
2312                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2313                         "Showing dump heap notification from " + procName + "/" + uid);
2314
2315                 INotificationManager inm = NotificationManager.getService();
2316                 if (inm == null) {
2317                     return;
2318                 }
2319
2320                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2321
2322
2323                 Intent deleteIntent = new Intent();
2324                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2325                 Intent intent = new Intent();
2326                 intent.setClassName("android", DumpHeapActivity.class.getName());
2327                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2328                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2329                 if (reportPackage != null) {
2330                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2331                 }
2332                 int userId = UserHandle.getUserId(uid);
2333                 Notification notification =
2334                         new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2335                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2336                         .setWhen(0)
2337                         .setOngoing(true)
2338                         .setAutoCancel(true)
2339                         .setTicker(text)
2340                         .setColor(mContext.getColor(
2341                                 com.android.internal.R.color.system_notification_accent_color))
2342                         .setContentTitle(text)
2343                         .setContentText(
2344                                 mContext.getText(R.string.dump_heap_notification_detail))
2345                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2346                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2347                                 new UserHandle(userId)))
2348                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2349                                 deleteIntent, 0, UserHandle.SYSTEM))
2350                         .build();
2351
2352                 try {
2353                     inm.enqueueNotificationWithTag("android", "android", null,
2354                             SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2355                             notification, userId);
2356                 } catch (RuntimeException e) {
2357                     Slog.w(ActivityManagerService.TAG,
2358                             "Error showing notification for dump heap", e);
2359                 } catch (RemoteException e) {
2360                 }
2361             } break;
2362             case DELETE_DUMPHEAP_MSG: {
2363                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2364                         null, DumpHeapActivity.JAVA_URI,
2365                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2366                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2367                         UserHandle.myUserId());
2368                 synchronized (ActivityManagerService.this) {
2369                     mMemWatchDumpFile = null;
2370                     mMemWatchDumpProcName = null;
2371                     mMemWatchDumpPid = -1;
2372                     mMemWatchDumpUid = -1;
2373                 }
2374             } break;
2375             case FOREGROUND_PROFILE_CHANGED_MSG: {
2376                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2377             } break;
2378             case REPORT_TIME_TRACKER_MSG: {
2379                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2380                 tracker.deliverResult(mContext);
2381             } break;
2382             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2383                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2384             } break;
2385             case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2386                 mUserController.dispatchLockedBootComplete(msg.arg1);
2387             } break;
2388             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2389                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2390                 try {
2391                     connection.shutdown();
2392                 } catch (RemoteException e) {
2393                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2394                 }
2395                 // Only a UiAutomation can set this flag and now that
2396                 // it is finished we make sure it is reset to its default.
2397                 mUserIsMonkey = false;
2398             } break;
2399             case IDLE_UIDS_MSG: {
2400                 idleUids();
2401             } break;
2402             case VR_MODE_CHANGE_MSG: {
2403                 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2404                     return;
2405                 }
2406                 synchronized (ActivityManagerService.this) {
2407                     final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2408                     mWindowManager.disableNonVrUi(disableNonVrUi);
2409                     if (disableNonVrUi) {
2410                         // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2411                         // then remove the pinned stack.
2412                         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2413                                 PINNED_STACK_ID);
2414                         if (pinnedStack != null) {
2415                             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2416                         }
2417                     }
2418                 }
2419             } break;
2420             case NOTIFY_VR_SLEEPING_MSG: {
2421                 notifyVrManagerOfSleepState(msg.arg1 != 0);
2422             } break;
2423             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2424                 synchronized (ActivityManagerService.this) {
2425                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2426                         ProcessRecord r = mLruProcesses.get(i);
2427                         if (r.thread != null) {
2428                             try {
2429                                 r.thread.handleTrustStorageUpdate();
2430                             } catch (RemoteException ex) {
2431                                 Slog.w(TAG, "Failed to handle trust storage update for: " +
2432                                         r.info.processName);
2433                             }
2434                         }
2435                     }
2436                 }
2437             } break;
2438             }
2439         }
2440     };
2441
2442     static final int COLLECT_PSS_BG_MSG = 1;
2443
2444     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2445         @Override
2446         public void handleMessage(Message msg) {
2447             switch (msg.what) {
2448             case COLLECT_PSS_BG_MSG: {
2449                 long start = SystemClock.uptimeMillis();
2450                 MemInfoReader memInfo = null;
2451                 synchronized (ActivityManagerService.this) {
2452                     if (mFullPssPending) {
2453                         mFullPssPending = false;
2454                         memInfo = new MemInfoReader();
2455                     }
2456                 }
2457                 if (memInfo != null) {
2458                     updateCpuStatsNow();
2459                     long nativeTotalPss = 0;
2460                     final List<ProcessCpuTracker.Stats> stats;
2461                     synchronized (mProcessCpuTracker) {
2462                         stats = mProcessCpuTracker.getStats( (st)-> {
2463                             return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2464                         });
2465                     }
2466                     final int N = stats.size();
2467                     for (int j = 0; j < N; j++) {
2468                         synchronized (mPidsSelfLocked) {
2469                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2470                                 // This is one of our own processes; skip it.
2471                                 continue;
2472                             }
2473                         }
2474                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2475                     }
2476                     memInfo.readMemInfo();
2477                     synchronized (ActivityManagerService.this) {
2478                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2479                                 + (SystemClock.uptimeMillis()-start) + "ms");
2480                         final long cachedKb = memInfo.getCachedSizeKb();
2481                         final long freeKb = memInfo.getFreeSizeKb();
2482                         final long zramKb = memInfo.getZramTotalSizeKb();
2483                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2484                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2485                                 kernelKb*1024, nativeTotalPss*1024);
2486                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2487                                 nativeTotalPss);
2488                     }
2489                 }
2490
2491                 int num = 0;
2492                 long[] tmp = new long[2];
2493                 do {
2494                     ProcessRecord proc;
2495                     int procState;
2496                     int pid;
2497                     long lastPssTime;
2498                     synchronized (ActivityManagerService.this) {
2499                         if (mPendingPssProcesses.size() <= 0) {
2500                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2501                                     "Collected PSS of " + num + " processes in "
2502                                     + (SystemClock.uptimeMillis() - start) + "ms");
2503                             mPendingPssProcesses.clear();
2504                             return;
2505                         }
2506                         proc = mPendingPssProcesses.remove(0);
2507                         procState = proc.pssProcState;
2508                         lastPssTime = proc.lastPssTime;
2509                         if (proc.thread != null && procState == proc.setProcState
2510                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2511                                         < SystemClock.uptimeMillis()) {
2512                             pid = proc.pid;
2513                         } else {
2514                             proc = null;
2515                             pid = 0;
2516                         }
2517                     }
2518                     if (proc != null) {
2519                         long pss = Debug.getPss(pid, tmp, null);
2520                         synchronized (ActivityManagerService.this) {
2521                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2522                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2523                                 num++;
2524                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2525                                         SystemClock.uptimeMillis());
2526                             }
2527                         }
2528                     }
2529                 } while (true);
2530             }
2531             }
2532         }
2533     };
2534
2535     public void setSystemProcess() {
2536         try {
2537             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2538             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2539             ServiceManager.addService("meminfo", new MemBinder(this));
2540             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2541             ServiceManager.addService("dbinfo", new DbBinder(this));
2542             if (MONITOR_CPU_USAGE) {
2543                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2544             }
2545             ServiceManager.addService("permission", new PermissionController(this));
2546             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2547
2548             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2549                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2550             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2551
2552             synchronized (this) {
2553                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2554                 app.persistent = true;
2555                 app.pid = MY_PID;
2556                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2557                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2558                 synchronized (mPidsSelfLocked) {
2559                     mPidsSelfLocked.put(app.pid, app);
2560                 }
2561                 updateLruProcessLocked(app, false, null);
2562                 updateOomAdjLocked();
2563             }
2564         } catch (PackageManager.NameNotFoundException e) {
2565             throw new RuntimeException(
2566                     "Unable to find android system package", e);
2567         }
2568     }
2569
2570     public void setWindowManager(WindowManagerService wm) {
2571         mWindowManager = wm;
2572         mStackSupervisor.setWindowManager(wm);
2573         mActivityStarter.setWindowManager(wm);
2574     }
2575
2576     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2577         mUsageStatsService = usageStatsManager;
2578     }
2579
2580     public void startObservingNativeCrashes() {
2581         final NativeCrashListener ncl = new NativeCrashListener(this);
2582         ncl.start();
2583     }
2584
2585     public IAppOpsService getAppOpsService() {
2586         return mAppOpsService;
2587     }
2588
2589     static class MemBinder extends Binder {
2590         ActivityManagerService mActivityManagerService;
2591         MemBinder(ActivityManagerService activityManagerService) {
2592             mActivityManagerService = activityManagerService;
2593         }
2594
2595         @Override
2596         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2597             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2598                     "meminfo", pw)) return;
2599             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2600         }
2601     }
2602
2603     static class GraphicsBinder extends Binder {
2604         ActivityManagerService mActivityManagerService;
2605         GraphicsBinder(ActivityManagerService activityManagerService) {
2606             mActivityManagerService = activityManagerService;
2607         }
2608
2609         @Override
2610         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2611             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2612                     "gfxinfo", pw)) return;
2613             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2614         }
2615     }
2616
2617     static class DbBinder extends Binder {
2618         ActivityManagerService mActivityManagerService;
2619         DbBinder(ActivityManagerService activityManagerService) {
2620             mActivityManagerService = activityManagerService;
2621         }
2622
2623         @Override
2624         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2625             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2626                     "dbinfo", pw)) return;
2627             mActivityManagerService.dumpDbInfo(fd, pw, args);
2628         }
2629     }
2630
2631     static class CpuBinder extends Binder {
2632         ActivityManagerService mActivityManagerService;
2633         CpuBinder(ActivityManagerService activityManagerService) {
2634             mActivityManagerService = activityManagerService;
2635         }
2636
2637         @Override
2638         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2639             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2640                     "cpuinfo", pw)) return;
2641             synchronized (mActivityManagerService.mProcessCpuTracker) {
2642                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2643                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2644                         SystemClock.uptimeMillis()));
2645             }
2646         }
2647     }
2648
2649     public static final class Lifecycle extends SystemService {
2650         private final ActivityManagerService mService;
2651
2652         public Lifecycle(Context context) {
2653             super(context);
2654             mService = new ActivityManagerService(context);
2655         }
2656
2657         @Override
2658         public void onStart() {
2659             mService.start();
2660         }
2661
2662         public ActivityManagerService getService() {
2663             return mService;
2664         }
2665     }
2666
2667     @VisibleForTesting
2668     public ActivityManagerService(Injector injector) {
2669         mInjector = injector;
2670         mContext = mInjector.getContext();
2671         mUiContext = null;
2672         GL_ES_VERSION = 0;
2673         mActivityStarter = null;
2674         mAppErrors = null;
2675         mAppOpsService = mInjector.getAppOpsService(null, null);
2676         mBatteryStatsService = null;
2677         mCompatModePackages = null;
2678         mConstants = null;
2679         mGrantFile = null;
2680         mHandler = null;
2681         mHandlerThread = null;
2682         mIntentFirewall = null;
2683         mKeyguardController = null;
2684         mPermissionReviewRequired = false;
2685         mProcessCpuThread = null;
2686         mProcessStats = null;
2687         mProviderMap = null;
2688         mRecentTasks = null;
2689         mServices = null;
2690         mStackSupervisor = null;
2691         mSystemThread = null;
2692         mTaskChangeNotificationController = null;
2693         mUiHandler = injector.getUiHandler(null);
2694         mUserController = null;
2695         mVrController = null;
2696     }
2697
2698     // Note: This method is invoked on the main thread but may need to attach various
2699     // handlers to other threads.  So take care to be explicit about the looper.
2700     public ActivityManagerService(Context systemContext) {
2701         LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2702         mInjector = new Injector();
2703         mContext = systemContext;
2704
2705         mFactoryTest = FactoryTest.getMode();
2706         mSystemThread = ActivityThread.currentActivityThread();
2707         mUiContext = mSystemThread.getSystemUiContext();
2708
2709         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2710
2711         mPermissionReviewRequired = mContext.getResources().getBoolean(
2712                 com.android.internal.R.bool.config_permissionReviewRequired);
2713
2714         mHandlerThread = new ServiceThread(TAG,
2715                 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2716         mHandlerThread.start();
2717         mHandler = new MainHandler(mHandlerThread.getLooper());
2718         mUiHandler = mInjector.getUiHandler(this);
2719
2720         mConstants = new ActivityManagerConstants(this, mHandler);
2721
2722         /* static; one-time init here */
2723         if (sKillHandler == null) {
2724             sKillThread = new ServiceThread(TAG + ":kill",
2725                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2726             sKillThread.start();
2727             sKillHandler = new KillHandler(sKillThread.getLooper());
2728         }
2729
2730         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2731                 "foreground", BROADCAST_FG_TIMEOUT, false);
2732         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2733                 "background", BROADCAST_BG_TIMEOUT, true);
2734         mBroadcastQueues[0] = mFgBroadcastQueue;
2735         mBroadcastQueues[1] = mBgBroadcastQueue;
2736
2737         mServices = new ActiveServices(this);
2738         mProviderMap = new ProviderMap(this);
2739         mAppErrors = new AppErrors(mUiContext, this);
2740
2741         // TODO: Move creation of battery stats service outside of activity manager service.
2742         File dataDir = Environment.getDataDirectory();
2743         File systemDir = new File(dataDir, "system");
2744         systemDir.mkdirs();
2745         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2746         mBatteryStatsService.getActiveStatistics().readLocked();
2747         mBatteryStatsService.scheduleWriteToDisk();
2748         mOnBattery = DEBUG_POWER ? true
2749                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2750         mBatteryStatsService.getActiveStatistics().setCallback(this);
2751
2752         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2753
2754         mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2755         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2756                 new IAppOpsCallback.Stub() {
2757                     @Override public void opChanged(int op, int uid, String packageName) {
2758                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2759                             if (mAppOpsService.checkOperation(op, uid, packageName)
2760                                     != AppOpsManager.MODE_ALLOWED) {
2761                                 runInBackgroundDisabled(uid);
2762                             }
2763                         }
2764                     }
2765                 });
2766
2767         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2768
2769         mUserController = new UserController(this);
2770
2771         mVrController = new VrController(this);
2772
2773         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2774             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2775
2776         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2777             mUseFifoUiScheduling = true;
2778         }
2779
2780         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2781         mTempConfig.setToDefaults();
2782         mTempConfig.setLocales(LocaleList.getDefault());
2783         mConfigurationSeq = mTempConfig.seq = 1;
2784         mStackSupervisor = createStackSupervisor();
2785         mStackSupervisor.onConfigurationChanged(mTempConfig);
2786         mKeyguardController = mStackSupervisor.mKeyguardController;
2787         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2788         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2789         mTaskChangeNotificationController =
2790                 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2791         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2792         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2793
2794         mProcessCpuThread = new Thread("CpuTracker") {
2795             @Override
2796             public void run() {
2797                 synchronized (mProcessCpuTracker) {
2798                     mProcessCpuInitLatch.countDown();
2799                     mProcessCpuTracker.init();
2800                 }
2801                 while (true) {
2802                     try {
2803                         try {
2804                             synchronized(this) {
2805                                 final long now = SystemClock.uptimeMillis();
2806                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2807                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2808                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2809                                 //        + ", write delay=" + nextWriteDelay);
2810                                 if (nextWriteDelay < nextCpuDelay) {
2811                                     nextCpuDelay = nextWriteDelay;
2812                                 }
2813                                 if (nextCpuDelay > 0) {
2814                                     mProcessCpuMutexFree.set(true);
2815                                     this.wait(nextCpuDelay);
2816                                 }
2817                             }
2818                         } catch (InterruptedException e) {
2819                         }
2820                         updateCpuStatsNow();
2821                     } catch (Exception e) {
2822                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2823                     }
2824                 }
2825             }
2826         };
2827
2828         Watchdog.getInstance().addMonitor(this);
2829         Watchdog.getInstance().addThread(mHandler);
2830     }
2831
2832     protected ActivityStackSupervisor createStackSupervisor() {
2833         return new ActivityStackSupervisor(this, mHandler.getLooper());
2834     }
2835
2836     public void setSystemServiceManager(SystemServiceManager mgr) {
2837         mSystemServiceManager = mgr;
2838     }
2839
2840     public void setInstaller(Installer installer) {
2841         mInstaller = installer;
2842     }
2843
2844     private void start() {
2845         removeAllProcessGroups();
2846         mProcessCpuThread.start();
2847
2848         mBatteryStatsService.publish(mContext);
2849         mAppOpsService.publish(mContext);
2850         Slog.d("AppOps", "AppOpsService published");
2851         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2852         // Wait for the synchronized block started in mProcessCpuThread,
2853         // so that any other acccess to mProcessCpuTracker from main thread
2854         // will be blocked during mProcessCpuTracker initialization.
2855         try {
2856             mProcessCpuInitLatch.await();
2857         } catch (InterruptedException e) {
2858             Slog.wtf(TAG, "Interrupted wait during start", e);
2859             Thread.currentThread().interrupt();
2860             throw new IllegalStateException("Interrupted wait during start");
2861         }
2862     }
2863
2864     void onUserStoppedLocked(int userId) {
2865         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2866     }
2867
2868     public void initPowerManagement() {
2869         mStackSupervisor.initPowerManagement();
2870         mBatteryStatsService.initPowerManagement();
2871         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2872         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2873         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2874         mVoiceWakeLock.setReferenceCounted(false);
2875     }
2876
2877     private ArraySet<String> getBackgroundLaunchBroadcasts() {
2878         if (mBackgroundLaunchBroadcasts == null) {
2879             mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2880         }
2881         return mBackgroundLaunchBroadcasts;
2882     }
2883
2884     @Override
2885     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2886             throws RemoteException {
2887         if (code == SYSPROPS_TRANSACTION) {
2888             // We need to tell all apps about the system property change.
2889             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2890             synchronized(this) {
2891                 final int NP = mProcessNames.getMap().size();
2892                 for (int ip=0; ip<NP; ip++) {
2893                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2894                     final int NA = apps.size();
2895                     for (int ia=0; ia<NA; ia++) {
2896                         ProcessRecord app = apps.valueAt(ia);
2897                         if (app.thread != null) {
2898                             procs.add(app.thread.asBinder());
2899                         }
2900                     }
2901                 }
2902             }
2903
2904             int N = procs.size();
2905             for (int i=0; i<N; i++) {
2906                 Parcel data2 = Parcel.obtain();
2907                 try {
2908                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2909                             Binder.FLAG_ONEWAY);
2910                 } catch (RemoteException e) {
2911                 }
2912                 data2.recycle();
2913             }
2914         }
2915         try {
2916             return super.onTransact(code, data, reply, flags);
2917         } catch (RuntimeException e) {
2918             // The activity manager only throws security exceptions, so let's
2919             // log all others.
2920             if (!(e instanceof SecurityException)) {
2921                 Slog.wtf(TAG, "Activity Manager Crash."
2922                         + " UID:" + Binder.getCallingUid()
2923                         + " PID:" + Binder.getCallingPid()
2924                         + " TRANS:" + code, e);
2925             }
2926             throw e;
2927         }
2928     }
2929
2930     void updateCpuStats() {
2931         final long now = SystemClock.uptimeMillis();
2932         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2933             return;
2934         }
2935         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2936             synchronized (mProcessCpuThread) {
2937                 mProcessCpuThread.notify();
2938             }
2939         }
2940     }
2941
2942     void updateCpuStatsNow() {
2943         synchronized (mProcessCpuTracker) {
2944             mProcessCpuMutexFree.set(false);
2945             final long now = SystemClock.uptimeMillis();
2946             boolean haveNewCpuStats = false;
2947
2948             if (MONITOR_CPU_USAGE &&
2949                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2950                 mLastCpuTime.set(now);
2951                 mProcessCpuTracker.update();
2952                 if (mProcessCpuTracker.hasGoodLastStats()) {
2953                     haveNewCpuStats = true;
2954                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2955                     //Slog.i(TAG, "Total CPU usage: "
2956                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2957
2958                     // Slog the cpu usage if the property is set.
2959                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2960                         int user = mProcessCpuTracker.getLastUserTime();
2961                         int system = mProcessCpuTracker.getLastSystemTime();
2962                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2963                         int irq = mProcessCpuTracker.getLastIrqTime();
2964                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2965                         int idle = mProcessCpuTracker.getLastIdleTime();
2966
2967                         int total = user + system + iowait + irq + softIrq + idle;
2968                         if (total == 0) total = 1;
2969
2970                         EventLog.writeEvent(EventLogTags.CPU,
2971                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2972                                 (user * 100) / total,
2973                                 (system * 100) / total,
2974                                 (iowait * 100) / total,
2975                                 (irq * 100) / total,
2976                                 (softIrq * 100) / total);
2977                     }
2978                 }
2979             }
2980
2981             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2982             synchronized(bstats) {
2983                 synchronized(mPidsSelfLocked) {
2984                     if (haveNewCpuStats) {
2985                         if (bstats.startAddingCpuLocked()) {
2986                             int totalUTime = 0;
2987                             int totalSTime = 0;
2988                             final int N = mProcessCpuTracker.countStats();
2989                             for (int i=0; i<N; i++) {
2990                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2991                                 if (!st.working) {
2992                                     continue;
2993                                 }
2994                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2995                                 totalUTime += st.rel_utime;
2996                                 totalSTime += st.rel_stime;
2997                                 if (pr != null) {
2998                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2999                                     if (ps == null || !ps.isActive()) {
3000                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3001                                                 pr.info.uid, pr.processName);
3002                                     }
3003                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3004                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
3005                                 } else {
3006                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3007                                     if (ps == null || !ps.isActive()) {
3008                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
3009                                                 bstats.mapUid(st.uid), st.name);
3010                                     }
3011                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3012                                 }
3013                             }
3014                             final int userTime = mProcessCpuTracker.getLastUserTime();
3015                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
3016                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3017                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
3018                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3019                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
3020                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3021                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3022                         }
3023                     }
3024                 }
3025
3026                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3027                     mLastWriteTime = now;
3028                     mBatteryStatsService.scheduleWriteToDisk();
3029                 }
3030             }
3031         }
3032     }
3033
3034     @Override
3035     public void batteryNeedsCpuUpdate() {
3036         updateCpuStatsNow();
3037     }
3038
3039     @Override
3040     public void batteryPowerChanged(boolean onBattery) {
3041         // When plugging in, update the CPU stats first before changing
3042         // the plug state.
3043         updateCpuStatsNow();
3044         synchronized (this) {
3045             synchronized(mPidsSelfLocked) {
3046                 mOnBattery = DEBUG_POWER ? true : onBattery;
3047             }
3048         }
3049     }
3050
3051     @Override
3052     public void batterySendBroadcast(Intent intent) {
3053         synchronized (this) {
3054             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3055                     AppOpsManager.OP_NONE, null, false, false,
3056                     -1, SYSTEM_UID, UserHandle.USER_ALL);
3057         }
3058     }
3059
3060     /**
3061      * Initialize the application bind args. These are passed to each
3062      * process when the bindApplication() IPC is sent to the process. They're
3063      * lazily setup to make sure the services are running when they're asked for.
3064      */
3065     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3066         // Isolated processes won't get this optimization, so that we don't
3067         // violate the rules about which services they have access to.
3068         if (isolated) {
3069             if (mIsolatedAppBindArgs == null) {
3070                 mIsolatedAppBindArgs = new HashMap<>();
3071                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3072             }
3073             return mIsolatedAppBindArgs;
3074         }
3075
3076         if (mAppBindArgs == null) {
3077             mAppBindArgs = new HashMap<>();
3078
3079             // Setup the application init args
3080             mAppBindArgs.put("package", ServiceManager.getService("package"));
3081             mAppBindArgs.put("window", ServiceManager.getService("window"));
3082             mAppBindArgs.put(Context.ALARM_SERVICE,
3083                     ServiceManager.getService(Context.ALARM_SERVICE));
3084         }
3085         return mAppBindArgs;
3086     }
3087
3088     /**
3089      * Update AMS states when an activity is resumed. This should only be called by
3090      * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3091      */
3092     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3093         final TaskRecord task = r.getTask();
3094         if (task.isApplicationTask()) {
3095             if (mCurAppTimeTracker != r.appTimeTracker) {
3096                 // We are switching app tracking.  Complete the current one.
3097                 if (mCurAppTimeTracker != null) {
3098                     mCurAppTimeTracker.stop();
3099                     mHandler.obtainMessage(
3100                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3101                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3102                     mCurAppTimeTracker = null;
3103                 }
3104                 if (r.appTimeTracker != null) {
3105                     mCurAppTimeTracker = r.appTimeTracker;
3106                     startTimeTrackingFocusedActivityLocked();
3107                 }
3108             } else {
3109                 startTimeTrackingFocusedActivityLocked();
3110             }
3111         } else {
3112             r.appTimeTracker = null;
3113         }
3114         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3115         // TODO: Probably not, because we don't want to resume voice on switching
3116         // back to this activity
3117         if (task.voiceInteractor != null) {
3118             startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3119         } else {
3120             finishRunningVoiceLocked();
3121
3122             if (mLastResumedActivity != null) {
3123                 final IVoiceInteractionSession session;
3124
3125                 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3126                 if (lastResumedActivityTask != null
3127                         && lastResumedActivityTask.voiceSession != null) {
3128                     session = lastResumedActivityTask.voiceSession;
3129                 } else {
3130                     session = mLastResumedActivity.voiceSession;
3131                 }
3132
3133                 if (session != null) {
3134                     // We had been in a voice interaction session, but now focused has
3135                     // move to something different.  Just finish the session, we can't
3136                     // return to it and retain the proper state and synchronization with
3137                     // the voice interaction service.
3138                     finishVoiceTask(session);
3139                 }
3140             }
3141         }
3142
3143         if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3144             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3145             mHandler.obtainMessage(
3146                     FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3147         }
3148         mLastResumedActivity = r;
3149
3150         mWindowManager.setFocusedApp(r.appToken, true);
3151
3152         applyUpdateLockStateLocked(r);
3153         applyUpdateVrModeLocked(r);
3154
3155         EventLogTags.writeAmSetResumedActivity(
3156                 r == null ? -1 : r.userId,
3157                 r == null ? "NULL" : r.shortComponentName,
3158                 reason);
3159     }
3160
3161     @Override
3162     public void setFocusedStack(int stackId) {
3163         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3164         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3165         final long callingId = Binder.clearCallingIdentity();
3166         try {
3167             synchronized (this) {
3168                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3169                 if (stack == null) {
3170                     return;
3171                 }
3172                 final ActivityRecord r = stack.topRunningActivityLocked();
3173                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3174                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3175                 }
3176             }
3177         } finally {
3178             Binder.restoreCallingIdentity(callingId);
3179         }
3180     }
3181
3182     @Override
3183     public void setFocusedTask(int taskId) {
3184         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3185         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3186         final long callingId = Binder.clearCallingIdentity();
3187         try {
3188             synchronized (this) {
3189                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3190                 if (task == null) {
3191                     return;
3192                 }
3193                 final ActivityRecord r = task.topRunningActivityLocked();
3194                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3195                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3196                 }
3197             }
3198         } finally {
3199             Binder.restoreCallingIdentity(callingId);
3200         }
3201     }
3202
3203     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3204     @Override
3205     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3206         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3207         mTaskChangeNotificationController.registerTaskStackListener(listener);
3208     }
3209
3210     /**
3211      * Unregister a task stack listener so that it stops receiving callbacks.
3212      */
3213     @Override
3214     public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3215          enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3216          mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3217      }
3218
3219     @Override
3220     public void notifyActivityDrawn(IBinder token) {
3221         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3222         synchronized (this) {
3223             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3224             if (r != null) {
3225                 r.getStack().notifyActivityDrawnLocked(r);
3226             }
3227         }
3228     }
3229
3230     final void applyUpdateLockStateLocked(ActivityRecord r) {
3231         // Modifications to the UpdateLock state are done on our handler, outside
3232         // the activity manager's locks.  The new state is determined based on the
3233         // state *now* of the relevant activity record.  The object is passed to
3234         // the handler solely for logging detail, not to be consulted/modified.
3235         final boolean nextState = r != null && r.immersive;
3236         mHandler.sendMessage(
3237                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3238     }
3239
3240     final void applyUpdateVrModeLocked(ActivityRecord r) {
3241         mHandler.sendMessage(
3242                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3243     }
3244
3245     private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3246         mHandler.sendMessage(
3247                 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3248     }
3249
3250     private void notifyVrManagerOfSleepState(boolean isSleeping) {
3251         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3252         if (vrService == null) {
3253             return;
3254         }
3255         vrService.onSleepStateChanged(isSleeping);
3256     }
3257
3258     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3259         Message msg = Message.obtain();
3260         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3261         msg.obj = r.getTask().askedCompatMode ? null : r;
3262         mUiHandler.sendMessage(msg);
3263     }
3264
3265     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3266         final Configuration globalConfig = getGlobalConfiguration();
3267         if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3268                 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3269             final Message msg = Message.obtain();
3270             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3271             msg.obj = r;
3272             mUiHandler.sendMessage(msg);
3273         }
3274     }
3275
3276     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3277             String what, Object obj, ProcessRecord srcApp) {
3278         app.lastActivityTime = now;
3279
3280         if (app.activities.size() > 0) {
3281             // Don't want to touch dependent processes that are hosting activities.
3282             return index;
3283         }
3284
3285         int lrui = mLruProcesses.lastIndexOf(app);
3286         if (lrui < 0) {
3287             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3288                     + what + " " + obj + " from " + srcApp);
3289             return index;
3290         }
3291
3292         if (lrui >= index) {
3293             // Don't want to cause this to move dependent processes *back* in the
3294             // list as if they were less frequently used.
3295             return index;
3296         }
3297
3298         if (lrui >= mLruProcessActivityStart) {
3299             // Don't want to touch dependent processes that are hosting activities.
3300             return index;
3301         }
3302
3303         mLruProcesses.remove(lrui);
3304         if (index > 0) {
3305             index--;
3306         }
3307         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3308                 + " in LRU list: " + app);
3309         mLruProcesses.add(index, app);
3310         return index;
3311     }
3312
3313     static void killProcessGroup(int uid, int pid) {
3314         if (sKillHandler != null) {
3315             sKillHandler.sendMessage(
3316                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3317         } else {
3318             Slog.w(TAG, "Asked to kill process group before system bringup!");
3319             Process.killProcessGroup(uid, pid);
3320         }
3321     }
3322
3323     final void removeLruProcessLocked(ProcessRecord app) {
3324         int lrui = mLruProcesses.lastIndexOf(app);
3325         if (lrui >= 0) {
3326             if (!app.killed) {
3327                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3328                 killProcessQuiet(app.pid);
3329                 killProcessGroup(app.uid, app.pid);
3330             }
3331             if (lrui <= mLruProcessActivityStart) {
3332                 mLruProcessActivityStart--;
3333             }
3334             if (lrui <= mLruProcessServiceStart) {
3335                 mLruProcessServiceStart--;
3336             }
3337             mLruProcesses.remove(lrui);
3338         }
3339     }
3340
3341     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3342             ProcessRecord client) {
3343         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3344                 || app.treatLikeActivity;
3345         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3346         if (!activityChange && hasActivity) {
3347             // The process has activities, so we are only allowing activity-based adjustments
3348             // to move it.  It should be kept in the front of the list with other
3349             // processes that have activities, and we don't want those to change their
3350             // order except due to activity operations.
3351             return;
3352         }
3353
3354         mLruSeq++;
3355         final long now = SystemClock.uptimeMillis();
3356         app.lastActivityTime = now;
3357
3358         // First a quick reject: if the app is already at the position we will
3359         // put it, then there is nothing to do.
3360         if (hasActivity) {
3361             final int N = mLruProcesses.size();
3362             if (N > 0 && mLruProcesses.get(N-1) == app) {
3363                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3364                 return;
3365             }
3366         } else {
3367             if (mLruProcessServiceStart > 0
3368                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3369                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3370                 return;
3371             }
3372         }
3373
3374         int lrui = mLruProcesses.lastIndexOf(app);
3375
3376         if (app.persistent && lrui >= 0) {
3377             // We don't care about the position of persistent processes, as long as
3378             // they are in the list.
3379             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3380             return;
3381         }
3382
3383         /* In progress: compute new position first, so we can avoid doing work
3384            if the process is not actually going to move.  Not yet working.
3385         int addIndex;
3386         int nextIndex;
3387         boolean inActivity = false, inService = false;
3388         if (hasActivity) {
3389             // Process has activities, put it at the very tipsy-top.
3390             addIndex = mLruProcesses.size();
3391             nextIndex = mLruProcessServiceStart;
3392             inActivity = true;
3393         } else if (hasService) {
3394             // Process has services, put it at the top of the service list.
3395             addIndex = mLruProcessActivityStart;
3396             nextIndex = mLruProcessServiceStart;
3397             inActivity = true;
3398             inService = true;
3399         } else  {
3400             // Process not otherwise of interest, it goes to the top of the non-service area.
3401             addIndex = mLruProcessServiceStart;
3402             if (client != null) {
3403                 int clientIndex = mLruProcesses.lastIndexOf(client);
3404                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3405                         + app);
3406                 if (clientIndex >= 0 && addIndex > clientIndex) {
3407                     addIndex = clientIndex;
3408                 }
3409             }
3410             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3411         }
3412
3413         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3414                 + mLruProcessActivityStart + "): " + app);
3415         */
3416
3417         if (lrui >= 0) {
3418             if (lrui < mLruProcessActivityStart) {
3419                 mLruProcessActivityStart--;
3420             }
3421             if (lrui < mLruProcessServiceStart) {
3422                 mLruProcessServiceStart--;
3423             }
3424             /*
3425             if (addIndex > lrui) {
3426                 addIndex--;
3427             }
3428             if (nextIndex > lrui) {
3429                 nextIndex--;
3430             }
3431             */
3432             mLruProcesses.remove(lrui);
3433         }
3434
3435         /*
3436         mLruProcesses.add(addIndex, app);
3437         if (inActivity) {
3438             mLruProcessActivityStart++;
3439         }
3440         if (inService) {
3441             mLruProcessActivityStart++;
3442         }
3443         */
3444
3445         int nextIndex;
3446         if (hasActivity) {
3447             final int N = mLruProcesses.size();
3448             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3449                 // Process doesn't have activities, but has clients with
3450                 // activities...  move it up, but one below the top (the top
3451                 // should always have a real activity).
3452                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3453                         "Adding to second-top of LRU activity list: " + app);
3454                 mLruProcesses.add(N - 1, app);
3455                 // To keep it from spamming the LRU list (by making a bunch of clients),
3456                 // we will push down any other entries owned by the app.
3457                 final int uid = app.info.uid;
3458                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3459                     ProcessRecord subProc = mLruProcesses.get(i);
3460                     if (subProc.info.uid == uid) {
3461                         // We want to push this one down the list.  If the process after
3462                         // it is for the same uid, however, don't do so, because we don't
3463                         // want them internally to be re-ordered.
3464                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3465                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3466                                     "Pushing uid " + uid + " swapping at " + i + ": "
3467                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3468                             ProcessRecord tmp = mLruProcesses.get(i);
3469                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3470                             mLruProcesses.set(i - 1, tmp);
3471                             i--;
3472                         }
3473                     } else {
3474                         // A gap, we can stop here.
3475                         break;
3476                     }
3477                 }
3478             } else {
3479                 // Process has activities, put it at the very tipsy-top.
3480                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3481                 mLruProcesses.add(app);
3482             }
3483             nextIndex = mLruProcessServiceStart;
3484         } else if (hasService) {
3485             // Process has services, put it at the top of the service list.
3486             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3487             mLruProcesses.add(mLruProcessActivityStart, app);
3488             nextIndex = mLruProcessServiceStart;
3489             mLruProcessActivityStart++;
3490         } else  {
3491             // Process not otherwise of interest, it goes to the top of the non-service area.
3492             int index = mLruProcessServiceStart;
3493             if (client != null) {
3494                 // If there is a client, don't allow the process to be moved up higher
3495                 // in the list than that client.
3496                 int clientIndex = mLruProcesses.lastIndexOf(client);
3497                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3498                         + " when updating " + app);
3499                 if (clientIndex <= lrui) {
3500                     // Don't allow the client index restriction to push it down farther in the
3501                     // list than it already is.
3502                     clientIndex = lrui;
3503                 }
3504                 if (clientIndex >= 0 && index > clientIndex) {
3505                     index = clientIndex;
3506                 }
3507             }
3508             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3509             mLruProcesses.add(index, app);
3510             nextIndex = index-1;
3511             mLruProcessActivityStart++;
3512             mLruProcessServiceStart++;
3513         }
3514
3515         // If the app is currently using a content provider or service,
3516         // bump those processes as well.
3517         for (int j=app.connections.size()-1; j>=0; j--) {
3518             ConnectionRecord cr = app.connections.valueAt(j);
3519             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3520                     && cr.binding.service.app != null
3521                     && cr.binding.service.app.lruSeq != mLruSeq
3522                     && !cr.binding.service.app.persistent) {
3523                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3524                         "service connection", cr, app);
3525             }
3526         }
3527         for (int j=app.conProviders.size()-1; j>=0; j--) {
3528             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3529             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3530                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3531                         "provider reference", cpr, app);
3532             }
3533         }
3534     }
3535
3536     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3537         if (uid == SYSTEM_UID) {
3538             // The system gets to run in any process.  If there are multiple
3539             // processes with the same uid, just pick the first (this
3540             // should never happen).
3541             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3542             if (procs == null) return null;
3543             final int procCount = procs.size();
3544             for (int i = 0; i < procCount; i++) {
3545                 final int procUid = procs.keyAt(i);
3546                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3547                     // Don't use an app process or different user process for system component.
3548                     continue;
3549                 }
3550                 return procs.valueAt(i);
3551             }
3552         }
3553         ProcessRecord proc = mProcessNames.get(processName, uid);
3554         if (false && proc != null && !keepIfLarge
3555                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3556                 && proc.lastCachedPss >= 4000) {
3557             // Turn this condition on to cause killing to happen regularly, for testing.
3558             if (proc.baseProcessTracker != null) {
3559                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3560             }
3561             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3562         } else if (proc != null && !keepIfLarge
3563                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3564                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3565             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3566             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3567                 if (proc.baseProcessTracker != null) {
3568                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3569                 }
3570                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3571             }
3572         }
3573         return proc;
3574     }
3575
3576     void notifyPackageUse(String packageName, int reason) {
3577         IPackageManager pm = AppGlobals.getPackageManager();
3578         try {
3579             pm.notifyPackageUse(packageName, reason);
3580         } catch (RemoteException e) {
3581         }
3582     }
3583
3584     boolean isNextTransitionForward() {
3585         int transit = mWindowManager.getPendingAppTransition();
3586         return transit == TRANSIT_ACTIVITY_OPEN
3587                 || transit == TRANSIT_TASK_OPEN
3588                 || transit == TRANSIT_TASK_TO_FRONT;
3589     }
3590
3591     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3592             String processName, String abiOverride, int uid, Runnable crashHandler) {
3593         synchronized(this) {
3594             ApplicationInfo info = new ApplicationInfo();
3595             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3596             // For isolated processes, the former contains the parent's uid and the latter the
3597             // actual uid of the isolated process.
3598             // In the special case introduced by this method (which is, starting an isolated
3599             // process directly from the SystemServer without an actual parent app process) the
3600             // closest thing to a parent's uid is SYSTEM_UID.
3601             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3602             // the |isolated| logic in the ProcessRecord constructor.
3603             info.uid = SYSTEM_UID;
3604             info.processName = processName;
3605             info.className = entryPoint;
3606             info.packageName = "android";
3607             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3608             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3609                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3610                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3611                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3612                     crashHandler);
3613             return proc != null ? proc.pid : 0;
3614         }
3615     }
3616
3617     final ProcessRecord startProcessLocked(String processName,
3618             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3619             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3620             boolean isolated, boolean keepIfLarge) {
3621         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3622                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3623                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3624                 null /* crashHandler */);
3625     }
3626
3627     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3628             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3629             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3630             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3631         long startTime = SystemClock.elapsedRealtime();
3632         ProcessRecord app;
3633         if (!isolated) {
3634             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3635             checkTime(startTime, "startProcess: after getProcessRecord");
3636
3637             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3638                 // If we are in the background, then check to see if this process
3639                 // is bad.  If so, we will just silently fail.
3640                 if (mAppErrors.isBadProcessLocked(info)) {
3641                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3642                             + "/" + info.processName);
3643                     return null;
3644                 }
3645             } else {
3646                 // When the user is explicitly starting a process, then clear its
3647                 // crash count so that we won't make it bad until they see at
3648                 // least one crash dialog again, and make the process good again
3649                 // if it had been bad.
3650                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3651                         + "/" + info.processName);
3652                 mAppErrors.resetProcessCrashTimeLocked(info);
3653                 if (mAppErrors.isBadProcessLocked(info)) {
3654                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3655                             UserHandle.getUserId(info.uid), info.uid,
3656                             info.processName);
3657                     mAppErrors.clearBadProcessLocked(info);
3658                     if (app != null) {
3659                         app.bad = false;
3660                     }
3661                 }
3662             }
3663         } else {
3664             // If this is an isolated process, it can't re-use an existing process.
3665             app = null;
3666         }
3667
3668         // We don't have to do anything more if:
3669         // (1) There is an existing application record; and
3670         // (2) The caller doesn't think it is dead, OR there is no thread
3671         //     object attached to it so we know it couldn't have crashed; and
3672         // (3) There is a pid assigned to it, so it is either starting or
3673         //     already running.
3674         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3675                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3676                 + " thread=" + (app != null ? app.thread : null)
3677                 + " pid=" + (app != null ? app.pid : -1));
3678         if (app != null && app.pid > 0) {
3679             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3680                 // We already have the app running, or are waiting for it to
3681                 // come up (we have a pid but not yet its thread), so keep it.
3682                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3683                 // If this is a new package in the process, add the package to the list
3684                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3685                 checkTime(startTime, "startProcess: done, added package to proc");
3686                 return app;
3687             }
3688
3689             // An application record is attached to a previous process,
3690             // clean it up now.
3691             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3692             checkTime(startTime, "startProcess: bad proc running, killing");
3693             killProcessGroup(app.uid, app.pid);
3694             handleAppDiedLocked(app, true, true);
3695             checkTime(startTime, "startProcess: done killing old proc");
3696         }
3697
3698         String hostingNameStr = hostingName != null
3699                 ? hostingName.flattenToShortString() : null;
3700
3701         if (app == null) {
3702             checkTime(startTime, "startProcess: creating new process record");
3703             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3704             if (app == null) {
3705                 Slog.w(TAG, "Failed making new process record for "
3706                         + processName + "/" + info.uid + " isolated=" + isolated);
3707                 return null;
3708             }
3709             app.crashHandler = crashHandler;
3710             checkTime(startTime, "startProcess: done creating new process record");
3711         } else {
3712             // If this is a new package in the process, add the package to the list
3713             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3714             checkTime(startTime, "startProcess: added package to existing proc");
3715         }
3716
3717         // If the system is not ready yet, then hold off on starting this
3718         // process until it is.
3719         if (!mProcessesReady
3720                 && !isAllowedWhileBooting(info)
3721                 && !allowWhileBooting) {
3722             if (!mProcessesOnHold.contains(app)) {
3723                 mProcessesOnHold.add(app);
3724             }
3725             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3726                     "System not ready, putting on hold: " + app);
3727             checkTime(startTime, "startProcess: returning with proc on hold");
3728             return app;
3729         }
3730
3731         checkTime(startTime, "startProcess: stepping in to startProcess");
3732         startProcessLocked(
3733                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3734         checkTime(startTime, "startProcess: done starting proc!");
3735         return (app.pid != 0) ? app : null;
3736     }
3737
3738     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3739         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3740     }
3741
3742     private final void startProcessLocked(ProcessRecord app,
3743             String hostingType, String hostingNameStr) {
3744         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3745                 null /* entryPoint */, null /* entryPointArgs */);
3746     }
3747
3748     private final void startProcessLocked(ProcessRecord app, String hostingType,
3749             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3750         long startTime = SystemClock.elapsedRealtime();
3751         if (app.pid > 0 && app.pid != MY_PID) {
3752             checkTime(startTime, "startProcess: removing from pids map");
3753             synchronized (mPidsSelfLocked) {
3754                 mPidsSelfLocked.remove(app.pid);
3755                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3756             }
3757             checkTime(startTime, "startProcess: done removing from pids map");
3758             app.setPid(0);
3759         }
3760
3761         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3762                 "startProcessLocked removing on hold: " + app);
3763         mProcessesOnHold.remove(app);
3764
3765         checkTime(startTime, "startProcess: starting to update cpu stats");
3766         updateCpuStats();
3767         checkTime(startTime, "startProcess: done updating cpu stats");
3768
3769         try {
3770             try {
3771                 final int userId = UserHandle.getUserId(app.uid);
3772                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3773             } catch (RemoteException e) {
3774                 throw e.rethrowAsRuntimeException();
3775             }
3776
3777             int uid = app.uid;
3778             int[] gids = null;
3779             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3780             if (!app.isolated) {
3781                 int[] permGids = null;
3782                 try {
3783                     checkTime(startTime, "startProcess: getting gids from package manager");
3784                     final IPackageManager pm = AppGlobals.getPackageManager();
3785                     permGids = pm.getPackageGids(app.info.packageName,
3786                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3787                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
3788                             StorageManagerInternal.class);
3789                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3790                             app.info.packageName);
3791                 } catch (RemoteException e) {
3792                     throw e.rethrowAsRuntimeException();
3793                 }
3794
3795                 /*
3796                  * Add shared application and profile GIDs so applications can share some
3797                  * resources like shared libraries and access user-wide resources
3798                  */
3799                 if (ArrayUtils.isEmpty(permGids)) {
3800                     gids = new int[3];
3801                 } else {
3802                     gids = new int[permGids.length + 3];
3803                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
3804                 }
3805                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3806                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3807                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3808             }
3809             checkTime(startTime, "startProcess: building args");
3810             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3811                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3812                         && mTopComponent != null
3813                         && app.processName.equals(mTopComponent.getPackageName())) {
3814                     uid = 0;
3815                 }
3816                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3817                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3818                     uid = 0;
3819                 }
3820             }
3821             int debugFlags = 0;
3822             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3823                 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3824                 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3825                 // Also turn on CheckJNI for debuggable apps. It's quite
3826                 // awkward to turn on otherwise.
3827                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3828             }
3829             // Run the app in safe mode if its manifest requests so or the
3830             // system is booted in safe mode.
3831             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3832                 mSafeMode == true) {
3833                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3834             }
3835             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3836                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3837             }
3838             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3839             if ("true".equals(genDebugInfoProperty)) {
3840                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3841             }
3842             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3843                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3844             }
3845             if ("1".equals(SystemProperties.get("debug.assert"))) {
3846                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3847             }
3848             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3849                 // Enable all debug flags required by the native debugger.
3850                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3851                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3852                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3853                 mNativeDebuggingApp = null;
3854             }
3855
3856             String invokeWith = null;
3857             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3858                 // Debuggable apps may include a wrapper script with their library directory.
3859                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3860                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3861                 try {
3862                     if (new File(wrapperFileName).exists()) {
3863                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3864                     }
3865                 } finally {
3866                     StrictMode.setThreadPolicy(oldPolicy);
3867                 }
3868             }
3869
3870             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3871             if (requiredAbi == null) {
3872                 requiredAbi = Build.SUPPORTED_ABIS[0];
3873             }
3874
3875             String instructionSet = null;
3876             if (app.info.primaryCpuAbi != null) {
3877                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3878             }
3879
3880             app.gids = gids;
3881             app.requiredAbi = requiredAbi;
3882             app.instructionSet = instructionSet;
3883
3884             // the per-user SELinux context must be set
3885             if (TextUtils.isEmpty(app.info.seInfoUser)) {
3886                 Slog.wtf(TAG, "SELinux tag not defined",
3887                         new IllegalStateException("SELinux tag not defined for "
3888                         + app.info.packageName + " (uid " + app.uid + ")"));
3889             }
3890             final String seInfo = app.info.seInfo
3891                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3892             // Start the process.  It will either succeed and return a result containing
3893             // the PID of the new process, or else throw a RuntimeException.
3894             boolean isActivityProcess = (entryPoint == null);
3895             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3896             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3897                     app.processName);
3898             checkTime(startTime, "startProcess: asking zygote to start proc");
3899             ProcessStartResult startResult;
3900             if (hostingType.equals("webview_service")) {
3901                 startResult = startWebView(entryPoint,
3902                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3903                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3904                         app.info.dataDir, null, entryPointArgs);
3905             } else {
3906                 startResult = Process.start(entryPoint,
3907                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3908                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3909                         app.info.dataDir, invokeWith, entryPointArgs);
3910             }
3911             checkTime(startTime, "startProcess: returned from zygote!");
3912             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3913
3914             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3915             checkTime(startTime, "startProcess: done updating battery stats");
3916
3917             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3918                     UserHandle.getUserId(uid), startResult.pid, uid,
3919                     app.processName, hostingType,
3920                     hostingNameStr != null ? hostingNameStr : "");
3921
3922             try {
3923                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3924                         seInfo, app.info.sourceDir, startResult.pid);
3925             } catch (RemoteException ex) {
3926                 // Ignore
3927             }
3928
3929             if (app.persistent) {
3930                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3931             }
3932
3933             checkTime(startTime, "startProcess: building log message");
3934             StringBuilder buf = mStringBuilder;
3935             buf.setLength(0);
3936             buf.append("Start proc ");
3937             buf.append(startResult.pid);
3938             buf.append(':');
3939             buf.append(app.processName);
3940             buf.append('/');
3941             UserHandle.formatUid(buf, uid);
3942             if (!isActivityProcess) {
3943                 buf.append(" [");
3944                 buf.append(entryPoint);
3945                 buf.append("]");
3946             }
3947             buf.append(" for ");
3948             buf.append(hostingType);
3949             if (hostingNameStr != null) {
3950                 buf.append(" ");
3951                 buf.append(hostingNameStr);
3952             }
3953             Slog.i(TAG, buf.toString());
3954             app.setPid(startResult.pid);
3955             app.usingWrapper = startResult.usingWrapper;
3956             app.removed = false;
3957             app.killed = false;
3958             app.killedByAm = false;
3959             checkTime(startTime, "startProcess: starting to update pids map");
3960             ProcessRecord oldApp;
3961             synchronized (mPidsSelfLocked) {
3962                 oldApp = mPidsSelfLocked.get(startResult.pid);
3963             }
3964             // If there is already an app occupying that pid that hasn't been cleaned up
3965             if (oldApp != null && !app.isolated) {
3966                 // Clean up anything relating to this pid first
3967                 Slog.w(TAG, "Reusing pid " + startResult.pid
3968                         + " while app is still mapped to it");
3969                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3970                         true /*replacingPid*/);
3971             }
3972             synchronized (mPidsSelfLocked) {
3973                 this.mPidsSelfLocked.put(startResult.pid, app);
3974                 if (isActivityProcess) {
3975                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3976                     msg.obj = app;
3977                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3978                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3979                 }
3980             }
3981             checkTime(startTime, "startProcess: done updating pids map");
3982         } catch (RuntimeException e) {
3983             Slog.e(TAG, "Failure starting process " + app.processName, e);
3984
3985             // Something went very wrong while trying to start this process; one
3986             // common case is when the package is frozen due to an active
3987             // upgrade. To recover, clean up any active bookkeeping related to
3988             // starting this process. (We already invoked this method once when
3989             // the package was initially frozen through KILL_APPLICATION_MSG, so
3990             // it doesn't hurt to use it again.)
3991             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3992                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3993         }
3994     }
3995
3996     void updateUsageStats(ActivityRecord component, boolean resumed) {
3997         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3998                 "updateUsageStats: comp=" + component + "res=" + resumed);
3999         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4000         if (resumed) {
4001             if (mUsageStatsService != null) {
4002                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4003                         UsageEvents.Event.MOVE_TO_FOREGROUND);
4004             }
4005             synchronized (stats) {
4006                 stats.noteActivityResumedLocked(component.app.uid);
4007             }
4008         } else {
4009             if (mUsageStatsService != null) {
4010                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4011                         UsageEvents.Event.MOVE_TO_BACKGROUND);
4012             }
4013             synchronized (stats) {
4014                 stats.noteActivityPausedLocked(component.app.uid);
4015             }
4016         }
4017     }
4018
4019     Intent getHomeIntent() {
4020         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4021         intent.setComponent(mTopComponent);
4022         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4023         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4024             intent.addCategory(Intent.CATEGORY_HOME);
4025         }
4026         return intent;
4027     }
4028
4029     boolean startHomeActivityLocked(int userId, String reason) {
4030         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4031                 && mTopAction == null) {
4032             // We are running in factory test mode, but unable to find
4033             // the factory test app, so just sit around displaying the
4034             // error message and don't try to start anything.
4035             return false;
4036         }
4037         Intent intent = getHomeIntent();
4038         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4039         if (aInfo != null) {
4040             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4041             // Don't do this if the home app is currently being
4042             // instrumented.
4043             aInfo = new ActivityInfo(aInfo);
4044             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4045             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4046                     aInfo.applicationInfo.uid, true);
4047             if (app == null || app.instr == null) {
4048                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4049                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
4050             }
4051         } else {
4052             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4053         }
4054
4055         return true;
4056     }
4057
4058     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4059         ActivityInfo ai = null;
4060         ComponentName comp = intent.getComponent();
4061         try {
4062             if (comp != null) {
4063                 // Factory test.
4064                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4065             } else {
4066                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4067                         intent,
4068                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4069                         flags, userId);
4070
4071                 if (info != null) {
4072                     ai = info.activityInfo;
4073                 }
4074             }
4075         } catch (RemoteException e) {
4076             // ignore
4077         }
4078
4079         return ai;
4080     }
4081
4082     /**
4083      * Starts the "new version setup screen" if appropriate.
4084      */
4085     void startSetupActivityLocked() {
4086         // Only do this once per boot.
4087         if (mCheckedForSetup) {
4088             return;
4089         }
4090
4091         // We will show this screen if the current one is a different
4092         // version than the last one shown, and we are not running in
4093         // low-level factory test mode.
4094         final ContentResolver resolver = mContext.getContentResolver();
4095         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4096                 Settings.Global.getInt(resolver,
4097                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4098             mCheckedForSetup = true;
4099
4100             // See if we should be showing the platform update setup UI.
4101             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4102             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4103                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4104             if (!ris.isEmpty()) {
4105                 final ResolveInfo ri = ris.get(0);
4106                 String vers = ri.activityInfo.metaData != null
4107                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4108                         : null;
4109                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4110                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4111                             Intent.METADATA_SETUP_VERSION);
4112                 }
4113                 String lastVers = Settings.Secure.getString(
4114                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4115                 if (vers != null && !vers.equals(lastVers)) {
4116                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4117                     intent.setComponent(new ComponentName(
4118                             ri.activityInfo.packageName, ri.activityInfo.name));
4119                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4120                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4121                             null, 0, 0, 0, null, false, false, null, null, null,
4122                             "startSetupActivity");
4123                 }
4124             }
4125         }
4126     }
4127
4128     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4129         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4130     }
4131
4132     void enforceNotIsolatedCaller(String caller) {
4133         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4134             throw new SecurityException("Isolated process not allowed to call " + caller);
4135         }
4136     }
4137
4138     void enforceShellRestriction(String restriction, int userHandle) {
4139         if (Binder.getCallingUid() == SHELL_UID) {
4140             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4141                 throw new SecurityException("Shell does not have permission to access user "
4142                         + userHandle);
4143             }
4144         }
4145     }
4146
4147     @Override
4148     public int getFrontActivityScreenCompatMode() {
4149         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4150         synchronized (this) {
4151             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4152         }
4153     }
4154
4155     @Override
4156     public void setFrontActivityScreenCompatMode(int mode) {
4157         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4158                 "setFrontActivityScreenCompatMode");
4159         synchronized (this) {
4160             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4161         }
4162     }
4163
4164     @Override
4165     public int getPackageScreenCompatMode(String packageName) {
4166         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4167         synchronized (this) {
4168             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4169         }
4170     }
4171
4172     @Override
4173     public void setPackageScreenCompatMode(String packageName, int mode) {
4174         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4175                 "setPackageScreenCompatMode");
4176         synchronized (this) {
4177             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4178         }
4179     }
4180
4181     @Override
4182     public boolean getPackageAskScreenCompat(String packageName) {
4183         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4184         synchronized (this) {
4185             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4186         }
4187     }
4188
4189     @Override
4190     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4191         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4192                 "setPackageAskScreenCompat");
4193         synchronized (this) {
4194             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4195         }
4196     }
4197
4198     private boolean hasUsageStatsPermission(String callingPackage) {
4199         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4200                 Binder.getCallingUid(), callingPackage);
4201         if (mode == AppOpsManager.MODE_DEFAULT) {
4202             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4203                     == PackageManager.PERMISSION_GRANTED;
4204         }
4205         return mode == AppOpsManager.MODE_ALLOWED;
4206     }
4207
4208     @Override
4209     public int getPackageProcessState(String packageName, String callingPackage) {
4210         if (!hasUsageStatsPermission(callingPackage)) {
4211             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4212                     "getPackageProcessState");
4213         }
4214
4215         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4216         synchronized (this) {
4217             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4218                 final ProcessRecord proc = mLruProcesses.get(i);
4219                 if (procState > proc.setProcState) {
4220                     if (proc.pkgList.containsKey(packageName) ||
4221                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4222                         procState = proc.setProcState;
4223                     }
4224                 }
4225             }
4226         }
4227         return procState;
4228     }
4229
4230     @Override
4231     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4232             throws RemoteException {
4233         synchronized (this) {
4234             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4235             if (app == null) {
4236                 throw new IllegalArgumentException("Unknown process: " + process);
4237             }
4238             if (app.thread == null) {
4239                 throw new IllegalArgumentException("Process has no app thread");
4240             }
4241             if (app.trimMemoryLevel >= level) {
4242                 throw new IllegalArgumentException(
4243                         "Unable to set a higher trim level than current level");
4244             }
4245             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4246                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4247                 throw new IllegalArgumentException("Unable to set a background trim level "
4248                     + "on a foreground process");
4249             }
4250             app.thread.scheduleTrimMemory(level);
4251             app.trimMemoryLevel = level;
4252             return true;
4253         }
4254     }
4255
4256     private void dispatchProcessesChanged() {
4257         int N;
4258         synchronized (this) {
4259             N = mPendingProcessChanges.size();
4260             if (mActiveProcessChanges.length < N) {
4261                 mActiveProcessChanges = new ProcessChangeItem[N];
4262             }
4263             mPendingProcessChanges.toArray(mActiveProcessChanges);
4264             mPendingProcessChanges.clear();
4265             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4266                     "*** Delivering " + N + " process changes");
4267         }
4268
4269         int i = mProcessObservers.beginBroadcast();
4270         while (i > 0) {
4271             i--;
4272             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4273             if (observer != null) {
4274                 try {
4275                     for (int j=0; j<N; j++) {
4276                         ProcessChangeItem item = mActiveProcessChanges[j];
4277                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4278                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4279                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4280                                     + item.uid + ": " + item.foregroundActivities);
4281                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4282                                     item.foregroundActivities);
4283                         }
4284                     }
4285                 } catch (RemoteException e) {
4286                 }
4287             }
4288         }
4289         mProcessObservers.finishBroadcast();
4290
4291         synchronized (this) {
4292             for (int j=0; j<N; j++) {
4293                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4294             }
4295         }
4296     }
4297
4298     private void dispatchProcessDied(int pid, int uid) {
4299         int i = mProcessObservers.beginBroadcast();
4300         while (i > 0) {
4301             i--;
4302             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4303             if (observer != null) {
4304                 try {
4305                     observer.onProcessDied(pid, uid);
4306                 } catch (RemoteException e) {
4307                 }
4308             }
4309         }
4310         mProcessObservers.finishBroadcast();
4311     }
4312
4313     @VisibleForTesting
4314     void dispatchUidsChanged() {
4315         int N;
4316         synchronized (this) {
4317             N = mPendingUidChanges.size();
4318             if (mActiveUidChanges.length < N) {
4319                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4320             }
4321             for (int i=0; i<N; i++) {
4322                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4323                 mActiveUidChanges[i] = change;
4324                 if (change.uidRecord != null) {
4325                     change.uidRecord.pendingChange = null;
4326                     change.uidRecord = null;
4327                 }
4328             }
4329             mPendingUidChanges.clear();
4330             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4331                     "*** Delivering " + N + " uid changes");
4332         }
4333
4334         int i = mUidObservers.beginBroadcast();
4335         while (i > 0) {
4336             i--;
4337             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4338                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4339         }
4340         mUidObservers.finishBroadcast();
4341
4342         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4343             for (int j = 0; j < N; ++j) {
4344                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4345                 if (item.change == UidRecord.CHANGE_GONE
4346                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4347                     mValidateUids.remove(item.uid);
4348                 } else {
4349                     UidRecord validateUid = mValidateUids.get(item.uid);
4350                     if (validateUid == null) {
4351                         validateUid = new UidRecord(item.uid);
4352                         mValidateUids.put(item.uid, validateUid);
4353                     }
4354                     if (item.change == UidRecord.CHANGE_IDLE) {
4355                         validateUid.idle = true;
4356                     } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4357                         validateUid.idle = false;
4358                     }
4359                     validateUid.curProcState = validateUid.setProcState = item.processState;
4360                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4361                 }
4362             }
4363         }
4364
4365         synchronized (this) {
4366             for (int j = 0; j < N; j++) {
4367                 mAvailUidChanges.add(mActiveUidChanges[j]);
4368             }
4369         }
4370     }
4371
4372     private void dispatchUidsChangedForObserver(IUidObserver observer,
4373             UidObserverRegistration reg, int changesSize) {
4374         if (observer == null) {
4375             return;
4376         }
4377         try {
4378             for (int j = 0; j < changesSize; j++) {
4379                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4380                 final int change = item.change;
4381                 if (change == UidRecord.CHANGE_IDLE
4382                         || change == UidRecord.CHANGE_GONE_IDLE) {
4383                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4384                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4385                                 "UID idle uid=" + item.uid);
4386                         observer.onUidIdle(item.uid, item.ephemeral);
4387                     }
4388                 } else if (change == UidRecord.CHANGE_ACTIVE) {
4389                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4390                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4391                                 "UID active uid=" + item.uid);
4392                         observer.onUidActive(item.uid);
4393                     }
4394                 }
4395                 if (change == UidRecord.CHANGE_GONE
4396                         || change == UidRecord.CHANGE_GONE_IDLE) {
4397                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4398                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4399                                 "UID gone uid=" + item.uid);
4400                         observer.onUidGone(item.uid, item.ephemeral);
4401                     }
4402                     if (reg.lastProcStates != null) {
4403                         reg.lastProcStates.delete(item.uid);
4404                     }
4405                 } else {
4406                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4407                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4408                                 "UID CHANGED uid=" + item.uid
4409                                         + ": " + item.processState);
4410                         boolean doReport = true;
4411                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4412                             final int lastState = reg.lastProcStates.get(item.uid,
4413                                     ActivityManager.PROCESS_STATE_UNKNOWN);
4414                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4415                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
4416                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
4417                                 doReport = lastAboveCut != newAboveCut;
4418                             } else {
4419                                 doReport = item.processState
4420                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
4421                             }
4422                         }
4423                         if (doReport) {
4424                             if (reg.lastProcStates != null) {
4425                                 reg.lastProcStates.put(item.uid, item.processState);
4426                             }
4427                             observer.onUidStateChanged(item.uid, item.processState,
4428                                     item.procStateSeq);
4429                         }
4430                     }
4431                 }
4432             }
4433         } catch (RemoteException e) {
4434         }
4435     }
4436
4437     @Override
4438     public final int startActivity(IApplicationThread caller, String callingPackage,
4439             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4440             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4441         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4442                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4443                 UserHandle.getCallingUserId());
4444     }
4445
4446     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4447         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4448         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4449                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4450                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4451
4452         // TODO: Switch to user app stacks here.
4453         String mimeType = intent.getType();
4454         final Uri data = intent.getData();
4455         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4456             mimeType = getProviderMimeType(data, userId);
4457         }
4458         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4459
4460         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4461         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null,
4462                 null, null, 0, 0, null, null, null, null, false, userId, container, null,
4463                 "startActivity");
4464     }
4465
4466     @Override
4467     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4468             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4469             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4470         enforceNotIsolatedCaller("startActivity");
4471         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4472                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4473         // TODO: Switch to user app stacks here.
4474         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4475                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4476                 profilerInfo, null, null, bOptions, false, userId, null, null,
4477                 "startActivityAsUser");
4478     }
4479
4480     @Override
4481     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4482             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4483             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4484             int userId) {
4485
4486         // This is very dangerous -- it allows you to perform a start activity (including
4487         // permission grants) as any app that may launch one of your own activities.  So
4488         // we will only allow this to be done from activities that are part of the core framework,
4489         // and then only when they are running as the system.
4490         final ActivityRecord sourceRecord;
4491         final int targetUid;
4492         final String targetPackage;
4493         synchronized (this) {
4494             if (resultTo == null) {
4495                 throw new SecurityException("Must be called from an activity");
4496             }
4497             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4498             if (sourceRecord == null) {
4499                 throw new SecurityException("Called with bad activity token: " + resultTo);
4500             }
4501             if (!sourceRecord.info.packageName.equals("android")) {
4502                 throw new SecurityException(
4503                         "Must be called from an activity that is declared in the android package");
4504             }
4505             if (sourceRecord.app == null) {
4506                 throw new SecurityException("Called without a process attached to activity");
4507             }
4508             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4509                 // This is still okay, as long as this activity is running under the
4510                 // uid of the original calling activity.
4511                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4512                     throw new SecurityException(
4513                             "Calling activity in uid " + sourceRecord.app.uid
4514                                     + " must be system uid or original calling uid "
4515                                     + sourceRecord.launchedFromUid);
4516                 }
4517             }
4518             if (ignoreTargetSecurity) {
4519                 if (intent.getComponent() == null) {
4520                     throw new SecurityException(
4521                             "Component must be specified with ignoreTargetSecurity");
4522                 }
4523                 if (intent.getSelector() != null) {
4524                     throw new SecurityException(
4525                             "Selector not allowed with ignoreTargetSecurity");
4526                 }
4527             }
4528             targetUid = sourceRecord.launchedFromUid;
4529             targetPackage = sourceRecord.launchedFromPackage;
4530         }
4531
4532         if (userId == UserHandle.USER_NULL) {
4533             userId = UserHandle.getUserId(sourceRecord.app.uid);
4534         }
4535
4536         // TODO: Switch to user app stacks here.
4537         try {
4538             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4539                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4540                     null, null, bOptions, ignoreTargetSecurity, userId, null, null,
4541                     "startActivityAsCaller");
4542             return ret;
4543         } catch (SecurityException e) {
4544             // XXX need to figure out how to propagate to original app.
4545             // A SecurityException here is generally actually a fault of the original
4546             // calling activity (such as a fairly granting permissions), so propagate it
4547             // back to them.
4548             /*
4549             StringBuilder msg = new StringBuilder();
4550             msg.append("While launching");
4551             msg.append(intent.toString());
4552             msg.append(": ");
4553             msg.append(e.getMessage());
4554             */
4555             throw e;
4556         }
4557     }
4558
4559     @Override
4560     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4561             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4562             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4563         enforceNotIsolatedCaller("startActivityAndWait");
4564         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4565                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4566         WaitResult res = new WaitResult();
4567         // TODO: Switch to user app stacks here.
4568         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4569                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4570                 bOptions, false, userId, null, null, "startActivityAndWait");
4571         return res;
4572     }
4573
4574     @Override
4575     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4576             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4577             int startFlags, Configuration config, Bundle bOptions, int userId) {
4578         enforceNotIsolatedCaller("startActivityWithConfig");
4579         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4580                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4581         // TODO: Switch to user app stacks here.
4582         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4583                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4584                 null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig");
4585         return ret;
4586     }
4587
4588     @Override
4589     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4590             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4591             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4592             throws TransactionTooLargeException {
4593         enforceNotIsolatedCaller("startActivityIntentSender");
4594         // Refuse possible leaked file descriptors
4595         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4596             throw new IllegalArgumentException("File descriptors passed in Intent");
4597         }
4598
4599         if (!(target instanceof PendingIntentRecord)) {
4600             throw new IllegalArgumentException("Bad PendingIntent object");
4601         }
4602
4603         PendingIntentRecord pir = (PendingIntentRecord)target;
4604
4605         synchronized (this) {
4606             // If this is coming from the currently resumed activity, it is
4607             // effectively saying that app switches are allowed at this point.
4608             final ActivityStack stack = getFocusedStack();
4609             if (stack.mResumedActivity != null &&
4610                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4611                 mAppSwitchesAllowedTime = 0;
4612             }
4613         }
4614         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4615                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4616         return ret;
4617     }
4618
4619     @Override
4620     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4621             Intent intent, String resolvedType, IVoiceInteractionSession session,
4622             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4623             Bundle bOptions, int userId) {
4624         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4625                 != PackageManager.PERMISSION_GRANTED) {
4626             String msg = "Permission Denial: startVoiceActivity() from pid="
4627                     + Binder.getCallingPid()
4628                     + ", uid=" + Binder.getCallingUid()
4629                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4630             Slog.w(TAG, msg);
4631             throw new SecurityException(msg);
4632         }
4633         if (session == null || interactor == null) {
4634             throw new NullPointerException("null session or interactor");
4635         }
4636         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4637                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4638         // TODO: Switch to user app stacks here.
4639         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4640                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4641                 null, bOptions, false, userId, null, null, "startVoiceActivity");
4642     }
4643
4644     @Override
4645     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4646             Intent intent, String resolvedType, Bundle bOptions, int userId) {
4647         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4648                 != PackageManager.PERMISSION_GRANTED) {
4649             final String msg = "Permission Denial: startAssistantActivity() from pid="
4650                     + Binder.getCallingPid()
4651                     + ", uid=" + Binder.getCallingUid()
4652                     + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4653             Slog.w(TAG, msg);
4654             throw new SecurityException(msg);
4655         }
4656         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4657                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4658         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4659                 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4660                 userId, null, null, "startAssistantActivity");
4661     }
4662
4663     @Override
4664     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4665             throws RemoteException {
4666         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4667         synchronized (this) {
4668             ActivityRecord activity = getFocusedStack().topActivity();
4669             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4670                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4671             }
4672             if (mRunningVoice != null || activity.getTask().voiceSession != null
4673                     || activity.voiceSession != null) {
4674                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4675                 return;
4676             }
4677             if (activity.pendingVoiceInteractionStart) {
4678                 Slog.w(TAG, "Pending start of voice interaction already.");
4679                 return;
4680             }
4681             activity.pendingVoiceInteractionStart = true;
4682         }
4683         LocalServices.getService(VoiceInteractionManagerInternal.class)
4684                 .startLocalVoiceInteraction(callingActivity, options);
4685     }
4686
4687     @Override
4688     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4689         LocalServices.getService(VoiceInteractionManagerInternal.class)
4690                 .stopLocalVoiceInteraction(callingActivity);
4691     }
4692
4693     @Override
4694     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4695         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4696                 .supportsLocalVoiceInteraction();
4697     }
4698
4699     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4700             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4701         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4702         if (activityToCallback == null) return;
4703         activityToCallback.setVoiceSessionLocked(voiceSession);
4704
4705         // Inform the activity
4706         try {
4707             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4708                     voiceInteractor);
4709             long token = Binder.clearCallingIdentity();
4710             try {
4711                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4712             } finally {
4713                 Binder.restoreCallingIdentity(token);
4714             }
4715             // TODO: VI Should we cache the activity so that it's easier to find later
4716             // rather than scan through all the stacks and activities?
4717         } catch (RemoteException re) {
4718             activityToCallback.clearVoiceSessionLocked();
4719             // TODO: VI Should this terminate the voice session?
4720         }
4721     }
4722
4723     @Override
4724     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4725         synchronized (this) {
4726             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4727                 if (keepAwake) {
4728                     mVoiceWakeLock.acquire();
4729                 } else {
4730                     mVoiceWakeLock.release();
4731                 }
4732             }
4733         }
4734     }
4735
4736     @Override
4737     public boolean startNextMatchingActivity(IBinder callingActivity,
4738             Intent intent, Bundle bOptions) {
4739         // Refuse possible leaked file descriptors
4740         if (intent != null && intent.hasFileDescriptors() == true) {
4741             throw new IllegalArgumentException("File descriptors passed in Intent");
4742         }
4743         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4744
4745         synchronized (this) {
4746             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4747             if (r == null) {
4748                 ActivityOptions.abort(options);
4749                 return false;
4750             }
4751             if (r.app == null || r.app.thread == null) {
4752                 // The caller is not running...  d'oh!
4753                 ActivityOptions.abort(options);
4754                 return false;
4755             }
4756             intent = new Intent(intent);
4757             // The caller is not allowed to change the data.
4758             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4759             // And we are resetting to find the next component...
4760             intent.setComponent(null);
4761
4762             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4763
4764             ActivityInfo aInfo = null;
4765             try {
4766                 List<ResolveInfo> resolves =
4767                     AppGlobals.getPackageManager().queryIntentActivities(
4768                             intent, r.resolvedType,
4769                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4770                             UserHandle.getCallingUserId()).getList();
4771
4772                 // Look for the original activity in the list...
4773                 final int N = resolves != null ? resolves.size() : 0;
4774                 for (int i=0; i<N; i++) {
4775                     ResolveInfo rInfo = resolves.get(i);
4776                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4777                             && rInfo.activityInfo.name.equals(r.info.name)) {
4778                         // We found the current one...  the next matching is
4779                         // after it.
4780                         i++;
4781                         if (i<N) {
4782                             aInfo = resolves.get(i).activityInfo;
4783                         }
4784                         if (debug) {
4785                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4786                                     + "/" + r.info.name);
4787                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4788                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4789                         }
4790                         break;
4791                     }
4792                 }
4793             } catch (RemoteException e) {
4794             }
4795
4796             if (aInfo == null) {
4797                 // Nobody who is next!
4798                 ActivityOptions.abort(options);
4799                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4800                 return false;
4801             }
4802
4803             intent.setComponent(new ComponentName(
4804                     aInfo.applicationInfo.packageName, aInfo.name));
4805             intent.setFlags(intent.getFlags()&~(
4806                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4807                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4808                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4809                     Intent.FLAG_ACTIVITY_NEW_TASK));
4810
4811             // Okay now we need to start the new activity, replacing the
4812             // currently running activity.  This is a little tricky because
4813             // we want to start the new one as if the current one is finished,
4814             // but not finish the current one first so that there is no flicker.
4815             // And thus...
4816             final boolean wasFinishing = r.finishing;
4817             r.finishing = true;
4818
4819             // Propagate reply information over to the new activity.
4820             final ActivityRecord resultTo = r.resultTo;
4821             final String resultWho = r.resultWho;
4822             final int requestCode = r.requestCode;
4823             r.resultTo = null;
4824             if (resultTo != null) {
4825                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4826             }
4827
4828             final long origId = Binder.clearCallingIdentity();
4829             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4830                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4831                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4832                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4833                     false, false, null, null, null, "startNextMatchingActivity");
4834             Binder.restoreCallingIdentity(origId);
4835
4836             r.finishing = wasFinishing;
4837             if (res != ActivityManager.START_SUCCESS) {
4838                 return false;
4839             }
4840             return true;
4841         }
4842     }
4843
4844     @Override
4845     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4846         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4847             String msg = "Permission Denial: startActivityFromRecents called without " +
4848                     START_TASKS_FROM_RECENTS;
4849             Slog.w(TAG, msg);
4850             throw new SecurityException(msg);
4851         }
4852         final long origId = Binder.clearCallingIdentity();
4853         try {
4854             synchronized (this) {
4855                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4856             }
4857         } finally {
4858             Binder.restoreCallingIdentity(origId);
4859         }
4860     }
4861
4862     final int startActivityInPackage(int uid, String callingPackage,
4863             Intent intent, String resolvedType, IBinder resultTo,
4864             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4865             IActivityContainer container, TaskRecord inTask, String reason) {
4866
4867         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4868                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4869
4870         // TODO: Switch to user app stacks here.
4871         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4872                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4873                 null, null, null, bOptions, false, userId, container, inTask, reason);
4874         return ret;
4875     }
4876
4877     @Override
4878     public final int startActivities(IApplicationThread caller, String callingPackage,
4879             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4880             int userId) {
4881         final String reason = "startActivities";
4882         enforceNotIsolatedCaller(reason);
4883         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4884                 userId, false, ALLOW_FULL_ONLY, reason, null);
4885         // TODO: Switch to user app stacks here.
4886         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4887                 resolvedTypes, resultTo, bOptions, userId, reason);
4888         return ret;
4889     }
4890
4891     final int startActivitiesInPackage(int uid, String callingPackage,
4892             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4893             Bundle bOptions, int userId) {
4894
4895         final String reason = "startActivityInPackage";
4896         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4897                 userId, false, ALLOW_FULL_ONLY, reason, null);
4898         // TODO: Switch to user app stacks here.
4899         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4900                 resultTo, bOptions, userId, reason);
4901         return ret;
4902     }
4903
4904     @Override
4905     public void reportActivityFullyDrawn(IBinder token) {
4906         synchronized (this) {
4907             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4908             if (r == null) {
4909                 return;
4910             }
4911             r.reportFullyDrawnLocked();
4912         }
4913     }
4914
4915     @Override
4916     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4917         synchronized (this) {
4918             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4919             if (r == null) {
4920                 return;
4921             }
4922             final long origId = Binder.clearCallingIdentity();
4923             try {
4924                 r.setRequestedOrientation(requestedOrientation);
4925             } finally {
4926                 Binder.restoreCallingIdentity(origId);
4927             }
4928         }
4929     }
4930
4931     @Override
4932     public int getRequestedOrientation(IBinder token) {
4933         synchronized (this) {
4934             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4935             if (r == null) {
4936                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4937             }
4938             return r.getRequestedOrientation();
4939         }
4940     }
4941
4942     @Override
4943     public final void requestActivityRelaunch(IBinder token) {
4944         synchronized(this) {
4945             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4946             if (r == null) {
4947                 return;
4948             }
4949             final long origId = Binder.clearCallingIdentity();
4950             try {
4951                 r.forceNewConfig = true;
4952                 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4953                         true /* preserveWindow */);
4954             } finally {
4955                 Binder.restoreCallingIdentity(origId);
4956             }
4957         }
4958     }
4959
4960     /**
4961      * This is the internal entry point for handling Activity.finish().
4962      *
4963      * @param token The Binder token referencing the Activity we want to finish.
4964      * @param resultCode Result code, if any, from this Activity.
4965      * @param resultData Result data (Intent), if any, from this Activity.
4966      * @param finishTask Whether to finish the task associated with this Activity.
4967      *
4968      * @return Returns true if the activity successfully finished, or false if it is still running.
4969      */
4970     @Override
4971     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4972             int finishTask) {
4973         // Refuse possible leaked file descriptors
4974         if (resultData != null && resultData.hasFileDescriptors() == true) {
4975             throw new IllegalArgumentException("File descriptors passed in Intent");
4976         }
4977
4978         synchronized(this) {
4979             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4980             if (r == null) {
4981                 return true;
4982             }
4983             // Keep track of the root activity of the task before we finish it
4984             TaskRecord tr = r.getTask();
4985             ActivityRecord rootR = tr.getRootActivity();
4986             if (rootR == null) {
4987                 Slog.w(TAG, "Finishing task with all activities already finished");
4988             }
4989             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4990             // finish.
4991             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4992                     mStackSupervisor.isLastLockedTask(tr)) {
4993                 Slog.i(TAG, "Not finishing task in lock task mode");
4994                 mStackSupervisor.showLockTaskToast();
4995                 return false;
4996             }
4997             if (mController != null) {
4998                 // Find the first activity that is not finishing.
4999                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5000                 if (next != null) {
5001                     // ask watcher if this is allowed
5002                     boolean resumeOK = true;
5003                     try {
5004                         resumeOK = mController.activityResuming(next.packageName);
5005                     } catch (RemoteException e) {
5006                         mController = null;
5007                         Watchdog.getInstance().setActivityController(null);
5008                     }
5009
5010                     if (!resumeOK) {
5011                         Slog.i(TAG, "Not finishing activity because controller resumed");
5012                         return false;
5013                     }
5014                 }
5015             }
5016             final long origId = Binder.clearCallingIdentity();
5017             try {
5018                 boolean res;
5019                 final boolean finishWithRootActivity =
5020                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5021                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5022                         || (finishWithRootActivity && r == rootR)) {
5023                     // If requested, remove the task that is associated to this activity only if it
5024                     // was the root activity in the task. The result code and data is ignored
5025                     // because we don't support returning them across task boundaries. Also, to
5026                     // keep backwards compatibility we remove the task from recents when finishing
5027                     // task with root activity.
5028                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5029                     if (!res) {
5030                         Slog.i(TAG, "Removing task failed to finish activity");
5031                     }
5032                 } else {
5033                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5034                             resultData, "app-request", true);
5035                     if (!res) {
5036                         Slog.i(TAG, "Failed to finish by app-request");
5037                     }
5038                 }
5039                 return res;
5040             } finally {
5041                 Binder.restoreCallingIdentity(origId);
5042             }
5043         }
5044     }
5045
5046     @Override
5047     public final void finishHeavyWeightApp() {
5048         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5049                 != PackageManager.PERMISSION_GRANTED) {
5050             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5051                     + Binder.getCallingPid()
5052                     + ", uid=" + Binder.getCallingUid()
5053                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5054             Slog.w(TAG, msg);
5055             throw new SecurityException(msg);
5056         }
5057
5058         synchronized(this) {
5059             if (mHeavyWeightProcess == null) {
5060                 return;
5061             }
5062
5063             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5064             for (int i = 0; i < activities.size(); i++) {
5065                 ActivityRecord r = activities.get(i);
5066                 if (!r.finishing && r.isInStackLocked()) {
5067                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5068                             null, "finish-heavy", true);
5069                 }
5070             }
5071
5072             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5073                     mHeavyWeightProcess.userId, 0));
5074             mHeavyWeightProcess = null;
5075         }
5076     }
5077
5078     @Override
5079     public void crashApplication(int uid, int initialPid, String packageName, int userId,
5080             String message) {
5081         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5082                 != PackageManager.PERMISSION_GRANTED) {
5083             String msg = "Permission Denial: crashApplication() from pid="
5084                     + Binder.getCallingPid()
5085                     + ", uid=" + Binder.getCallingUid()
5086                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5087             Slog.w(TAG, msg);
5088             throw new SecurityException(msg);
5089         }
5090
5091         synchronized(this) {
5092             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5093         }
5094     }
5095
5096     @Override
5097     public final void finishSubActivity(IBinder token, String resultWho,
5098             int requestCode) {
5099         synchronized(this) {
5100             final long origId = Binder.clearCallingIdentity();
5101             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5102             if (r != null) {
5103                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5104             }
5105             Binder.restoreCallingIdentity(origId);
5106         }
5107     }
5108
5109     @Override
5110     public boolean finishActivityAffinity(IBinder token) {
5111         synchronized(this) {
5112             final long origId = Binder.clearCallingIdentity();
5113             try {
5114                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5115                 if (r == null) {
5116                     return false;
5117                 }
5118
5119                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5120                 // can finish.
5121                 final TaskRecord task = r.getTask();
5122                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5123                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5124                     mStackSupervisor.showLockTaskToast();
5125                     return false;
5126                 }
5127                 return task.getStack().finishActivityAffinityLocked(r);
5128             } finally {
5129                 Binder.restoreCallingIdentity(origId);
5130             }
5131         }
5132     }
5133
5134     @Override
5135     public void finishVoiceTask(IVoiceInteractionSession session) {
5136         synchronized (this) {
5137             final long origId = Binder.clearCallingIdentity();
5138             try {
5139                 // TODO: VI Consider treating local voice interactions and voice tasks
5140                 // differently here
5141                 mStackSupervisor.finishVoiceTask(session);
5142             } finally {
5143                 Binder.restoreCallingIdentity(origId);
5144             }
5145         }
5146
5147     }
5148
5149     @Override
5150     public boolean releaseActivityInstance(IBinder token) {
5151         synchronized(this) {
5152             final long origId = Binder.clearCallingIdentity();
5153             try {
5154                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5155                 if (r == null) {
5156                     return false;
5157                 }
5158                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5159             } finally {
5160                 Binder.restoreCallingIdentity(origId);
5161             }
5162         }
5163     }
5164
5165     @Override
5166     public void releaseSomeActivities(IApplicationThread appInt) {
5167         synchronized(this) {
5168             final long origId = Binder.clearCallingIdentity();
5169             try {
5170                 ProcessRecord app = getRecordForAppLocked(appInt);
5171                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5172             } finally {
5173                 Binder.restoreCallingIdentity(origId);
5174             }
5175         }
5176     }
5177
5178     @Override
5179     public boolean willActivityBeVisible(IBinder token) {
5180         synchronized(this) {
5181             ActivityStack stack = ActivityRecord.getStackLocked(token);
5182             if (stack != null) {
5183                 return stack.willActivityBeVisibleLocked(token);
5184             }
5185             return false;
5186         }
5187     }
5188
5189     @Override
5190     public void overridePendingTransition(IBinder token, String packageName,
5191             int enterAnim, int exitAnim) {
5192         synchronized(this) {
5193             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5194             if (self == null) {
5195                 return;
5196             }
5197
5198             final long origId = Binder.clearCallingIdentity();
5199
5200             if (self.state == ActivityState.RESUMED
5201                     || self.state == ActivityState.PAUSING) {
5202                 mWindowManager.overridePendingAppTransition(packageName,
5203                         enterAnim, exitAnim, null);
5204             }
5205
5206             Binder.restoreCallingIdentity(origId);
5207         }
5208     }
5209
5210     /**
5211      * Main function for removing an existing process from the activity manager
5212      * as a result of that process going away.  Clears out all connections
5213      * to the process.
5214      */
5215     private final void handleAppDiedLocked(ProcessRecord app,
5216             boolean restarting, boolean allowRestart) {
5217         int pid = app.pid;
5218         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5219                 false /*replacingPid*/);
5220         if (!kept && !restarting) {
5221             removeLruProcessLocked(app);
5222             if (pid > 0) {
5223                 ProcessList.remove(pid);
5224             }
5225         }
5226
5227         if (mProfileProc == app) {
5228             clearProfilerLocked();
5229         }
5230
5231         // Remove this application's activities from active lists.
5232         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5233
5234         app.activities.clear();
5235
5236         if (app.instr != null) {
5237             Slog.w(TAG, "Crash of app " + app.processName
5238                   + " running instrumentation " + app.instr.mClass);
5239             Bundle info = new Bundle();
5240             info.putString("shortMsg", "Process crashed.");
5241             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5242         }
5243
5244         mWindowManager.deferSurfaceLayout();
5245         try {
5246             if (!restarting && hasVisibleActivities
5247                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5248                 // If there was nothing to resume, and we are not already restarting this process, but
5249                 // there is a visible activity that is hosted by the process...  then make sure all
5250                 // visible activities are running, taking care of restarting this process.
5251                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5252             }
5253         } finally {
5254             mWindowManager.continueSurfaceLayout();
5255         }
5256     }
5257
5258     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5259         final IBinder threadBinder = thread.asBinder();
5260         // Find the application record.
5261         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5262             final ProcessRecord rec = mLruProcesses.get(i);
5263             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5264                 return i;
5265             }
5266         }
5267         return -1;
5268     }
5269
5270     final ProcessRecord getRecordForAppLocked(
5271             IApplicationThread thread) {
5272         if (thread == null) {
5273             return null;
5274         }
5275
5276         int appIndex = getLRURecordIndexForAppLocked(thread);
5277         if (appIndex >= 0) {
5278             return mLruProcesses.get(appIndex);
5279         }
5280
5281         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5282         // double-check that.
5283         final IBinder threadBinder = thread.asBinder();
5284         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5285         for (int i = pmap.size()-1; i >= 0; i--) {
5286             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5287             for (int j = procs.size()-1; j >= 0; j--) {
5288                 final ProcessRecord proc = procs.valueAt(j);
5289                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5290                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5291                             + proc);
5292                     return proc;
5293                 }
5294             }
5295         }
5296
5297         return null;
5298     }
5299
5300     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5301         // If there are no longer any background processes running,
5302         // and the app that died was not running instrumentation,
5303         // then tell everyone we are now low on memory.
5304         boolean haveBg = false;
5305         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5306             ProcessRecord rec = mLruProcesses.get(i);
5307             if (rec.thread != null
5308                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5309                 haveBg = true;
5310                 break;
5311             }
5312         }
5313
5314         if (!haveBg) {
5315             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5316             if (doReport) {
5317                 long now = SystemClock.uptimeMillis();
5318                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5319                     doReport = false;
5320                 } else {
5321                     mLastMemUsageReportTime = now;
5322                 }
5323             }
5324             final ArrayList<ProcessMemInfo> memInfos
5325                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5326             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5327             long now = SystemClock.uptimeMillis();
5328             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5329                 ProcessRecord rec = mLruProcesses.get(i);
5330                 if (rec == dyingProc || rec.thread == null) {
5331                     continue;
5332                 }
5333                 if (doReport) {
5334                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5335                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5336                 }
5337                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5338                     // The low memory report is overriding any current
5339                     // state for a GC request.  Make sure to do
5340                     // heavy/important/visible/foreground processes first.
5341                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5342                         rec.lastRequestedGc = 0;
5343                     } else {
5344                         rec.lastRequestedGc = rec.lastLowMemory;
5345                     }
5346                     rec.reportLowMemory = true;
5347                     rec.lastLowMemory = now;
5348                     mProcessesToGc.remove(rec);
5349                     addProcessToGcListLocked(rec);
5350                 }
5351             }
5352             if (doReport) {
5353                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5354                 mHandler.sendMessage(msg);
5355             }
5356             scheduleAppGcsLocked();
5357         }
5358     }
5359
5360     final void appDiedLocked(ProcessRecord app) {
5361        appDiedLocked(app, app.pid, app.thread, false);
5362     }
5363
5364     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5365             boolean fromBinderDied) {
5366         // First check if this ProcessRecord is actually active for the pid.
5367         synchronized (mPidsSelfLocked) {
5368             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5369             if (curProc != app) {
5370                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5371                 return;
5372             }
5373         }
5374
5375         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5376         synchronized (stats) {
5377             stats.noteProcessDiedLocked(app.info.uid, pid);
5378         }
5379
5380         if (!app.killed) {
5381             if (!fromBinderDied) {
5382                 killProcessQuiet(pid);
5383             }
5384             killProcessGroup(app.uid, pid);
5385             app.killed = true;
5386         }
5387
5388         // Clean up already done if the process has been re-started.
5389         if (app.pid == pid && app.thread != null &&
5390                 app.thread.asBinder() == thread.asBinder()) {
5391             boolean doLowMem = app.instr == null;
5392             boolean doOomAdj = doLowMem;
5393             if (!app.killedByAm) {
5394                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5395                         + ProcessList.makeOomAdjString(app.setAdj)
5396                         + ProcessList.makeProcStateString(app.setProcState));
5397                 mAllowLowerMemLevel = true;
5398             } else {
5399                 // Note that we always want to do oom adj to update our state with the
5400                 // new number of procs.
5401                 mAllowLowerMemLevel = false;
5402                 doLowMem = false;
5403             }
5404             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5405                     app.setAdj, app.setProcState);
5406             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5407                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5408             handleAppDiedLocked(app, false, true);
5409
5410             if (doOomAdj) {
5411                 updateOomAdjLocked();
5412             }
5413             if (doLowMem) {
5414                 doLowMemReportIfNeededLocked(app);
5415             }
5416         } else if (app.pid != pid) {
5417             // A new process has already been started.
5418             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5419                     + ") has died and restarted (pid " + app.pid + ").");
5420             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5421         } else if (DEBUG_PROCESSES) {
5422             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5423                     + thread.asBinder());
5424         }
5425     }
5426
5427     /**
5428      * If a stack trace dump file is configured, dump process stack traces.
5429      * @param clearTraces causes the dump file to be erased prior to the new
5430      *    traces being written, if true; when false, the new traces will be
5431      *    appended to any existing file content.
5432      * @param firstPids of dalvik VM processes to dump stack traces for first
5433      * @param lastPids of dalvik VM processes to dump stack traces for last
5434      * @param nativePids optional list of native pids to dump stack crawls
5435      */
5436     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5437             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5438             ArrayList<Integer> nativePids) {
5439         ArrayList<Integer> extraPids = null;
5440
5441         // Measure CPU usage as soon as we're called in order to get a realistic sampling
5442         // of the top users at the time of the request.
5443         if (processCpuTracker != null) {
5444             processCpuTracker.init();
5445             try {
5446                 Thread.sleep(200);
5447             } catch (InterruptedException ignored) {
5448             }
5449
5450             processCpuTracker.update();
5451
5452             // We'll take the stack crawls of just the top apps using CPU.
5453             final int N = processCpuTracker.countWorkingStats();
5454             extraPids = new ArrayList<>();
5455             for (int i = 0; i < N && extraPids.size() < 5; i++) {
5456                 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5457                 if (lastPids.indexOfKey(stats.pid) >= 0) {
5458                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5459
5460                     extraPids.add(stats.pid);
5461                 } else if (DEBUG_ANR) {
5462                     Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5463                             + stats.pid);
5464                 }
5465             }
5466         }
5467
5468         boolean useTombstonedForJavaTraces = false;
5469         File tracesFile;
5470
5471         final String tracesDir = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5472         if (tracesDir.isEmpty()) {
5473             // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5474             // dumping scheme. All traces are written to a global trace file (usually
5475             // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5476             // the file if requested.
5477             //
5478             // This mode of operation will be removed in the near future.
5479
5480
5481             String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5482             if (globalTracesPath.isEmpty()) {
5483                 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5484                 return null;
5485             }
5486
5487             tracesFile = new File(globalTracesPath);
5488             try {
5489                 if (clearTraces && tracesFile.exists()) {
5490                     tracesFile.delete();
5491                 }
5492
5493                 tracesFile.createNewFile();
5494                 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5495             } catch (IOException e) {
5496                 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5497                 return null;
5498             }
5499         } else {
5500             // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5501             // Each set of ANR traces is written to a separate file and dumpstate will process
5502             // all such files and add them to a captured bug report if they're recent enough.
5503             //
5504             // NOTE: We should consider creating the file in native code atomically once we've
5505             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5506             // can be removed.
5507             try {
5508                 tracesFile = File.createTempFile("anr_", "", new File(tracesDir));
5509                 FileUtils.setPermissions(tracesFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5510             } catch (IOException ioe) {
5511                 Slog.w(TAG, "Unable to create ANR traces file: ", ioe);
5512                 return null;
5513             }
5514
5515             useTombstonedForJavaTraces = true;
5516         }
5517
5518         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5519                 useTombstonedForJavaTraces);
5520         return tracesFile;
5521     }
5522
5523     /**
5524      * Legacy code, do not use. Existing users will be deleted.
5525      *
5526      * @deprecated
5527      */
5528     @Deprecated
5529     public static class DumpStackFileObserver extends FileObserver {
5530         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5531         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5532
5533         private final String mTracesPath;
5534         private boolean mClosed;
5535
5536         public DumpStackFileObserver(String tracesPath) {
5537             super(tracesPath, FileObserver.CLOSE_WRITE);
5538             mTracesPath = tracesPath;
5539         }
5540
5541         @Override
5542         public synchronized void onEvent(int event, String path) {
5543             mClosed = true;
5544             notify();
5545         }
5546
5547         public long dumpWithTimeout(int pid, long timeout) {
5548             sendSignal(pid, SIGNAL_QUIT);
5549             final long start = SystemClock.elapsedRealtime();
5550
5551             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5552             synchronized (this) {
5553                 try {
5554                     wait(waitTime); // Wait for traces file to be closed.
5555                 } catch (InterruptedException e) {
5556                     Slog.wtf(TAG, e);
5557                 }
5558             }
5559
5560             // This avoids a corner case of passing a negative time to the native
5561             // trace in case we've already hit the overall timeout.
5562             final long timeWaited = SystemClock.elapsedRealtime() - start;
5563             if (timeWaited >= timeout) {
5564                 return timeWaited;
5565             }
5566
5567             if (!mClosed) {
5568                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5569                        ". Attempting native stack collection.");
5570
5571                 final long nativeDumpTimeoutMs = Math.min(
5572                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5573
5574                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5575                         (int) (nativeDumpTimeoutMs / 1000));
5576             }
5577
5578             final long end = SystemClock.elapsedRealtime();
5579             mClosed = false;
5580
5581             return (end - start);
5582         }
5583     }
5584
5585     /**
5586      * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5587      * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5588      * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5589      * attempting to obtain native traces in the case of a failure. Returns the total time spent
5590      * capturing traces.
5591      */
5592     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5593         final long timeStart = SystemClock.elapsedRealtime();
5594         if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5595             Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5596                     (NATIVE_DUMP_TIMEOUT_MS / 1000));
5597         }
5598
5599         return SystemClock.elapsedRealtime() - timeStart;
5600     }
5601
5602     private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5603             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5604             boolean useTombstonedForJavaTraces) {
5605
5606         // We don't need any sort of inotify based monitoring when we're dumping traces via
5607         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5608         // control of all writes to the file in question.
5609         final DumpStackFileObserver observer;
5610         if (useTombstonedForJavaTraces) {
5611             observer = null;
5612         } else {
5613             // Use a FileObserver to detect when traces finish writing.
5614             // The order of traces is considered important to maintain for legibility.
5615             observer = new DumpStackFileObserver(tracesFile);
5616         }
5617
5618         // We must complete all stack dumps within 20 seconds.
5619         long remainingTime = 20 * 1000;
5620         try {
5621             if (observer != null) {
5622                 observer.startWatching();
5623             }
5624
5625             // First collect all of the stacks of the most important pids.
5626             if (firstPids != null) {
5627                 int num = firstPids.size();
5628                 for (int i = 0; i < num; i++) {
5629                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5630                             + firstPids.get(i));
5631                     final long timeTaken;
5632                     if (useTombstonedForJavaTraces) {
5633                         timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5634                     } else {
5635                         timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5636                     }
5637
5638                     remainingTime -= timeTaken;
5639                     if (remainingTime <= 0) {
5640                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5641                             "); deadline exceeded.");
5642                         return;
5643                     }
5644
5645                     if (DEBUG_ANR) {
5646                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5647                     }
5648                 }
5649             }
5650
5651             // Next collect the stacks of the native pids
5652             if (nativePids != null) {
5653                 for (int pid : nativePids) {
5654                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5655                     final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5656
5657                     final long start = SystemClock.elapsedRealtime();
5658                     Debug.dumpNativeBacktraceToFileTimeout(
5659                             pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5660                     final long timeTaken = SystemClock.elapsedRealtime() - start;
5661
5662                     remainingTime -= timeTaken;
5663                     if (remainingTime <= 0) {
5664                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5665                             "); deadline exceeded.");
5666                         return;
5667                     }
5668
5669                     if (DEBUG_ANR) {
5670                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5671                     }
5672                 }
5673             }
5674
5675             // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5676             if (extraPids != null) {
5677                 for (int pid : extraPids) {
5678                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5679
5680                     final long timeTaken;
5681                     if (useTombstonedForJavaTraces) {
5682                         timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5683                     } else {
5684                         timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5685                     }
5686
5687                     remainingTime -= timeTaken;
5688                     if (remainingTime <= 0) {
5689                         Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5690                                 "); deadline exceeded.");
5691                         return;
5692                     }
5693
5694                     if (DEBUG_ANR) {
5695                         Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5696                     }
5697                 }
5698             }
5699         } finally {
5700             if (observer != null) {
5701                 observer.stopWatching();
5702             }
5703         }
5704     }
5705
5706     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5707         if (true || IS_USER_BUILD) {
5708             return;
5709         }
5710         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5711         if (tracesPath == null || tracesPath.length() == 0) {
5712             return;
5713         }
5714
5715         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5716         StrictMode.allowThreadDiskWrites();
5717         try {
5718             final File tracesFile = new File(tracesPath);
5719             final File tracesDir = tracesFile.getParentFile();
5720             final File tracesTmp = new File(tracesDir, "__tmp__");
5721             try {
5722                 if (tracesFile.exists()) {
5723                     tracesTmp.delete();
5724                     tracesFile.renameTo(tracesTmp);
5725                 }
5726                 StringBuilder sb = new StringBuilder();
5727                 Time tobj = new Time();
5728                 tobj.set(System.currentTimeMillis());
5729                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5730                 sb.append(": ");
5731                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5732                 sb.append(" since ");
5733                 sb.append(msg);
5734                 FileOutputStream fos = new FileOutputStream(tracesFile);
5735                 fos.write(sb.toString().getBytes());
5736                 if (app == null) {
5737                     fos.write("\n*** No application process!".getBytes());
5738                 }
5739                 fos.close();
5740                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5741             } catch (IOException e) {
5742                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5743                 return;
5744             }
5745
5746             if (app != null) {
5747                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5748                 firstPids.add(app.pid);
5749                 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5750             }
5751
5752             File lastTracesFile = null;
5753             File curTracesFile = null;
5754             for (int i=9; i>=0; i--) {
5755                 String name = String.format(Locale.US, "slow%02d.txt", i);
5756                 curTracesFile = new File(tracesDir, name);
5757                 if (curTracesFile.exists()) {
5758                     if (lastTracesFile != null) {
5759                         curTracesFile.renameTo(lastTracesFile);
5760                     } else {
5761                         curTracesFile.delete();
5762                     }
5763                 }
5764                 lastTracesFile = curTracesFile;
5765             }
5766             tracesFile.renameTo(curTracesFile);
5767             if (tracesTmp.exists()) {
5768                 tracesTmp.renameTo(tracesFile);
5769             }
5770         } finally {
5771             StrictMode.setThreadPolicy(oldPolicy);
5772         }
5773     }
5774
5775     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5776         if (!mLaunchWarningShown) {
5777             mLaunchWarningShown = true;
5778             mUiHandler.post(new Runnable() {
5779                 @Override
5780                 public void run() {
5781                     synchronized (ActivityManagerService.this) {
5782                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5783                         d.show();
5784                         mUiHandler.postDelayed(new Runnable() {
5785                             @Override
5786                             public void run() {
5787                                 synchronized (ActivityManagerService.this) {
5788                                     d.dismiss();
5789                                     mLaunchWarningShown = false;
5790                                 }
5791                             }
5792                         }, 4000);
5793                     }
5794                 }
5795             });
5796         }
5797     }
5798
5799     @Override
5800     public boolean clearApplicationUserData(final String packageName,
5801             final IPackageDataObserver observer, int userId) {
5802         enforceNotIsolatedCaller("clearApplicationUserData");
5803         int uid = Binder.getCallingUid();
5804         int pid = Binder.getCallingPid();
5805         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5806                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5807
5808
5809         long callingId = Binder.clearCallingIdentity();
5810         try {
5811             IPackageManager pm = AppGlobals.getPackageManager();
5812             int pkgUid = -1;
5813             synchronized(this) {
5814                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5815                         userId, packageName)) {
5816                     throw new SecurityException(
5817                             "Cannot clear data for a protected package: " + packageName);
5818                 }
5819
5820                 try {
5821                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5822                 } catch (RemoteException e) {
5823                 }
5824                 if (pkgUid == -1) {
5825                     Slog.w(TAG, "Invalid packageName: " + packageName);
5826                     if (observer != null) {
5827                         try {
5828                             observer.onRemoveCompleted(packageName, false);
5829                         } catch (RemoteException e) {
5830                             Slog.i(TAG, "Observer no longer exists.");
5831                         }
5832                     }
5833                     return false;
5834                 }
5835                 if (uid == pkgUid || checkComponentPermission(
5836                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5837                         pid, uid, -1, true)
5838                         == PackageManager.PERMISSION_GRANTED) {
5839                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5840                 } else {
5841                     throw new SecurityException("PID " + pid + " does not have permission "
5842                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5843                                     + " of package " + packageName);
5844                 }
5845
5846                 // Remove all tasks match the cleared application package and user
5847                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5848                     final TaskRecord tr = mRecentTasks.get(i);
5849                     final String taskPackageName =
5850                             tr.getBaseIntent().getComponent().getPackageName();
5851                     if (tr.userId != userId) continue;
5852                     if (!taskPackageName.equals(packageName)) continue;
5853                     mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5854                 }
5855             }
5856
5857             final int pkgUidF = pkgUid;
5858             final int userIdF = userId;
5859             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5860                 @Override
5861                 public void onRemoveCompleted(String packageName, boolean succeeded)
5862                         throws RemoteException {
5863                     synchronized (ActivityManagerService.this) {
5864                         finishForceStopPackageLocked(packageName, pkgUidF);
5865                     }
5866
5867                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5868                             Uri.fromParts("package", packageName, null));
5869                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5870                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5871                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5872                     broadcastIntentInPackage("android", SYSTEM_UID, intent,
5873                             null, null, 0, null, null, null, null, false, false, userIdF);
5874
5875                     if (observer != null) {
5876                         observer.onRemoveCompleted(packageName, succeeded);
5877                     }
5878                 }
5879             };
5880
5881             try {
5882                 // Clear application user data
5883                 pm.clearApplicationUserData(packageName, localObserver, userId);
5884
5885                 synchronized(this) {
5886                     // Remove all permissions granted from/to this package
5887                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5888                 }
5889
5890                 // Reset notification settings.
5891                 INotificationManager inm = NotificationManager.getService();
5892                 inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5893             } catch (RemoteException e) {
5894             }
5895         } finally {
5896             Binder.restoreCallingIdentity(callingId);
5897         }
5898         return true;
5899     }
5900
5901     @Override
5902     public void killBackgroundProcesses(final String packageName, int userId) {
5903         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5904                 != PackageManager.PERMISSION_GRANTED &&
5905                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5906                         != PackageManager.PERMISSION_GRANTED) {
5907             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5908                     + Binder.getCallingPid()
5909                     + ", uid=" + Binder.getCallingUid()
5910                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5911             Slog.w(TAG, msg);
5912             throw new SecurityException(msg);
5913         }
5914
5915         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5916                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5917         long callingId = Binder.clearCallingIdentity();
5918         try {
5919             IPackageManager pm = AppGlobals.getPackageManager();
5920             synchronized(this) {
5921                 int appId = -1;
5922                 try {
5923                     appId = UserHandle.getAppId(
5924                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5925                 } catch (RemoteException e) {
5926                 }
5927                 if (appId == -1) {
5928                     Slog.w(TAG, "Invalid packageName: " + packageName);
5929                     return;
5930                 }
5931                 killPackageProcessesLocked(packageName, appId, userId,
5932                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5933             }
5934         } finally {
5935             Binder.restoreCallingIdentity(callingId);
5936         }
5937     }
5938
5939     @Override
5940     public void killAllBackgroundProcesses() {
5941         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5942                 != PackageManager.PERMISSION_GRANTED) {
5943             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5944                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5945                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5946             Slog.w(TAG, msg);
5947             throw new SecurityException(msg);
5948         }
5949
5950         final long callingId = Binder.clearCallingIdentity();
5951         try {
5952             synchronized (this) {
5953                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5954                 final int NP = mProcessNames.getMap().size();
5955                 for (int ip = 0; ip < NP; ip++) {
5956                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5957                     final int NA = apps.size();
5958                     for (int ia = 0; ia < NA; ia++) {
5959                         final ProcessRecord app = apps.valueAt(ia);
5960                         if (app.persistent) {
5961                             // We don't kill persistent processes.
5962                             continue;
5963                         }
5964                         if (app.removed) {
5965                             procs.add(app);
5966                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5967                             app.removed = true;
5968                             procs.add(app);
5969                         }
5970                     }
5971                 }
5972
5973                 final int N = procs.size();
5974                 for (int i = 0; i < N; i++) {
5975                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5976                 }
5977
5978                 mAllowLowerMemLevel = true;
5979
5980                 updateOomAdjLocked();
5981                 doLowMemReportIfNeededLocked(null);
5982             }
5983         } finally {
5984             Binder.restoreCallingIdentity(callingId);
5985         }
5986     }
5987
5988     /**
5989      * Kills all background processes, except those matching any of the
5990      * specified properties.
5991      *
5992      * @param minTargetSdk the target SDK version at or above which to preserve
5993      *                     processes, or {@code -1} to ignore the target SDK
5994      * @param maxProcState the process state at or below which to preserve
5995      *                     processes, or {@code -1} to ignore the process state
5996      */
5997     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5998         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5999                 != PackageManager.PERMISSION_GRANTED) {
6000             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6001                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6002                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6003             Slog.w(TAG, msg);
6004             throw new SecurityException(msg);
6005         }
6006
6007         final long callingId = Binder.clearCallingIdentity();
6008         try {
6009             synchronized (this) {
6010                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6011                 final int NP = mProcessNames.getMap().size();
6012                 for (int ip = 0; ip < NP; ip++) {
6013                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6014                     final int NA = apps.size();
6015                     for (int ia = 0; ia < NA; ia++) {
6016                         final ProcessRecord app = apps.valueAt(ia);
6017                         if (app.removed) {
6018                             procs.add(app);
6019                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6020                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6021                             app.removed = true;
6022                             procs.add(app);
6023                         }
6024                     }
6025                 }
6026
6027                 final int N = procs.size();
6028                 for (int i = 0; i < N; i++) {
6029                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
6030                 }
6031             }
6032         } finally {
6033             Binder.restoreCallingIdentity(callingId);
6034         }
6035     }
6036
6037     @Override
6038     public void forceStopPackage(final String packageName, int userId) {
6039         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6040                 != PackageManager.PERMISSION_GRANTED) {
6041             String msg = "Permission Denial: forceStopPackage() from pid="
6042                     + Binder.getCallingPid()
6043                     + ", uid=" + Binder.getCallingUid()
6044                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6045             Slog.w(TAG, msg);
6046             throw new SecurityException(msg);
6047         }
6048         final int callingPid = Binder.getCallingPid();
6049         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6050                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6051         long callingId = Binder.clearCallingIdentity();
6052         try {
6053             IPackageManager pm = AppGlobals.getPackageManager();
6054             synchronized(this) {
6055                 int[] users = userId == UserHandle.USER_ALL
6056                         ? mUserController.getUsers() : new int[] { userId };
6057                 for (int user : users) {
6058                     int pkgUid = -1;
6059                     try {
6060                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6061                                 user);
6062                     } catch (RemoteException e) {
6063                     }
6064                     if (pkgUid == -1) {
6065                         Slog.w(TAG, "Invalid packageName: " + packageName);
6066                         continue;
6067                     }
6068                     try {
6069                         pm.setPackageStoppedState(packageName, true, user);
6070                     } catch (RemoteException e) {
6071                     } catch (IllegalArgumentException e) {
6072                         Slog.w(TAG, "Failed trying to unstop package "
6073                                 + packageName + ": " + e);
6074                     }
6075                     if (mUserController.isUserRunningLocked(user, 0)) {
6076                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6077                         finishForceStopPackageLocked(packageName, pkgUid);
6078                     }
6079                 }
6080             }
6081         } finally {
6082             Binder.restoreCallingIdentity(callingId);
6083         }
6084     }
6085
6086     @Override
6087     public void addPackageDependency(String packageName) {
6088         synchronized (this) {
6089             int callingPid = Binder.getCallingPid();
6090             if (callingPid == myPid()) {
6091                 //  Yeah, um, no.
6092                 return;
6093             }
6094             ProcessRecord proc;
6095             synchronized (mPidsSelfLocked) {
6096                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6097             }
6098             if (proc != null) {
6099                 if (proc.pkgDeps == null) {
6100                     proc.pkgDeps = new ArraySet<String>(1);
6101                 }
6102                 proc.pkgDeps.add(packageName);
6103             }
6104         }
6105     }
6106
6107     /*
6108      * The pkg name and app id have to be specified.
6109      */
6110     @Override
6111     public void killApplication(String pkg, int appId, int userId, String reason) {
6112         if (pkg == null) {
6113             return;
6114         }
6115         // Make sure the uid is valid.
6116         if (appId < 0) {
6117             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6118             return;
6119         }
6120         int callerUid = Binder.getCallingUid();
6121         // Only the system server can kill an application
6122         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6123             // Post an aysnc message to kill the application
6124             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6125             msg.arg1 = appId;
6126             msg.arg2 = userId;
6127             Bundle bundle = new Bundle();
6128             bundle.putString("pkg", pkg);
6129             bundle.putString("reason", reason);
6130             msg.obj = bundle;
6131             mHandler.sendMessage(msg);
6132         } else {
6133             throw new SecurityException(callerUid + " cannot kill pkg: " +
6134                     pkg);
6135         }
6136     }
6137
6138     @Override
6139     public void closeSystemDialogs(String reason) {
6140         enforceNotIsolatedCaller("closeSystemDialogs");
6141
6142         final int pid = Binder.getCallingPid();
6143         final int uid = Binder.getCallingUid();
6144         final long origId = Binder.clearCallingIdentity();
6145         try {
6146             synchronized (this) {
6147                 // Only allow this from foreground processes, so that background
6148                 // applications can't abuse it to prevent system UI from being shown.
6149                 if (uid >= FIRST_APPLICATION_UID) {
6150                     ProcessRecord proc;
6151                     synchronized (mPidsSelfLocked) {
6152                         proc = mPidsSelfLocked.get(pid);
6153                     }
6154                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6155                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6156                                 + " from background process " + proc);
6157                         return;
6158                     }
6159                 }
6160                 closeSystemDialogsLocked(reason);
6161             }
6162         } finally {
6163             Binder.restoreCallingIdentity(origId);
6164         }
6165     }
6166
6167     void closeSystemDialogsLocked(String reason) {
6168         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6169         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6170                 | Intent.FLAG_RECEIVER_FOREGROUND);
6171         if (reason != null) {
6172             intent.putExtra("reason", reason);
6173         }
6174         mWindowManager.closeSystemDialogs(reason);
6175
6176         mStackSupervisor.closeSystemDialogsLocked();
6177
6178         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6179                 AppOpsManager.OP_NONE, null, false, false,
6180                 -1, SYSTEM_UID, UserHandle.USER_ALL);
6181     }
6182
6183     @Override
6184     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6185         enforceNotIsolatedCaller("getProcessMemoryInfo");
6186         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6187         for (int i=pids.length-1; i>=0; i--) {
6188             ProcessRecord proc;
6189             int oomAdj;
6190             synchronized (this) {
6191                 synchronized (mPidsSelfLocked) {
6192                     proc = mPidsSelfLocked.get(pids[i]);
6193                     oomAdj = proc != null ? proc.setAdj : 0;
6194                 }
6195             }
6196             infos[i] = new Debug.MemoryInfo();
6197             Debug.getMemoryInfo(pids[i], infos[i]);
6198             if (proc != null) {
6199                 synchronized (this) {
6200                     if (proc.thread != null && proc.setAdj == oomAdj) {
6201                         // Record this for posterity if the process has been stable.
6202                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6203                                 infos[i].getTotalUss(), false, proc.pkgList);
6204                     }
6205                 }
6206             }
6207         }
6208         return infos;
6209     }
6210
6211     @Override
6212     public long[] getProcessPss(int[] pids) {
6213         enforceNotIsolatedCaller("getProcessPss");
6214         long[] pss = new long[pids.length];
6215         for (int i=pids.length-1; i>=0; i--) {
6216             ProcessRecord proc;
6217             int oomAdj;
6218             synchronized (this) {
6219                 synchronized (mPidsSelfLocked) {
6220                     proc = mPidsSelfLocked.get(pids[i]);
6221                     oomAdj = proc != null ? proc.setAdj : 0;
6222                 }
6223             }
6224             long[] tmpUss = new long[1];
6225             pss[i] = Debug.getPss(pids[i], tmpUss, null);
6226             if (proc != null) {
6227                 synchronized (this) {
6228                     if (proc.thread != null && proc.setAdj == oomAdj) {
6229                         // Record this for posterity if the process has been stable.
6230                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6231                     }
6232                 }
6233             }
6234         }
6235         return pss;
6236     }
6237
6238     @Override
6239     public void killApplicationProcess(String processName, int uid) {
6240         if (processName == null) {
6241             return;
6242         }
6243
6244         int callerUid = Binder.getCallingUid();
6245         // Only the system server can kill an application
6246         if (callerUid == SYSTEM_UID) {
6247             synchronized (this) {
6248                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6249                 if (app != null && app.thread != null) {
6250                     try {
6251                         app.thread.scheduleSuicide();
6252                     } catch (RemoteException e) {
6253                         // If the other end already died, then our work here is done.
6254                     }
6255                 } else {
6256                     Slog.w(TAG, "Process/uid not found attempting kill of "
6257                             + processName + " / " + uid);
6258                 }
6259             }
6260         } else {
6261             throw new SecurityException(callerUid + " cannot kill app process: " +
6262                     processName);
6263         }
6264     }
6265
6266     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6267         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6268                 false, true, false, false, UserHandle.getUserId(uid), reason);
6269     }
6270
6271     private void finishForceStopPackageLocked(final String packageName, int uid) {
6272         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6273                 Uri.fromParts("package", packageName, null));
6274         if (!mProcessesReady) {
6275             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6276                     | Intent.FLAG_RECEIVER_FOREGROUND);
6277         }
6278         intent.putExtra(Intent.EXTRA_UID, uid);
6279         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6280         broadcastIntentLocked(null, null, intent,
6281                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6282                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6283     }
6284
6285
6286     private final boolean killPackageProcessesLocked(String packageName, int appId,
6287             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6288             boolean doit, boolean evenPersistent, String reason) {
6289         ArrayList<ProcessRecord> procs = new ArrayList<>();
6290
6291         // Remove all processes this package may have touched: all with the
6292         // same UID (except for the system or root user), and all whose name
6293         // matches the package name.
6294         final int NP = mProcessNames.getMap().size();
6295         for (int ip=0; ip<NP; ip++) {
6296             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6297             final int NA = apps.size();
6298             for (int ia=0; ia<NA; ia++) {
6299                 ProcessRecord app = apps.valueAt(ia);
6300                 if (app.persistent && !evenPersistent) {
6301                     // we don't kill persistent processes
6302                     continue;
6303                 }
6304                 if (app.removed) {
6305                     if (doit) {
6306                         procs.add(app);
6307                     }
6308                     continue;
6309                 }
6310
6311                 // Skip process if it doesn't meet our oom adj requirement.
6312                 if (app.setAdj < minOomAdj) {
6313                     continue;
6314                 }
6315
6316                 // If no package is specified, we call all processes under the
6317                 // give user id.
6318                 if (packageName == null) {
6319                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6320                         continue;
6321                     }
6322                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6323                         continue;
6324                     }
6325                 // Package has been specified, we want to hit all processes
6326                 // that match it.  We need to qualify this by the processes
6327                 // that are running under the specified app and user ID.
6328                 } else {
6329                     final boolean isDep = app.pkgDeps != null
6330                             && app.pkgDeps.contains(packageName);
6331                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6332                         continue;
6333                     }
6334                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6335                         continue;
6336                     }
6337                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6338                         continue;
6339                     }
6340                 }
6341
6342                 // Process has passed all conditions, kill it!
6343                 if (!doit) {
6344                     return true;
6345                 }
6346                 app.removed = true;
6347                 procs.add(app);
6348             }
6349         }
6350
6351         int N = procs.size();
6352         for (int i=0; i<N; i++) {
6353             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6354         }
6355         updateOomAdjLocked();
6356         return N > 0;
6357     }
6358
6359     private void cleanupDisabledPackageComponentsLocked(
6360             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6361
6362         Set<String> disabledClasses = null;
6363         boolean packageDisabled = false;
6364         IPackageManager pm = AppGlobals.getPackageManager();
6365
6366         if (changedClasses == null) {
6367             // Nothing changed...
6368             return;
6369         }
6370
6371         // Determine enable/disable state of the package and its components.
6372         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6373         for (int i = changedClasses.length - 1; i >= 0; i--) {
6374             final String changedClass = changedClasses[i];
6375
6376             if (changedClass.equals(packageName)) {
6377                 try {
6378                     // Entire package setting changed
6379                     enabled = pm.getApplicationEnabledSetting(packageName,
6380                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6381                 } catch (Exception e) {
6382                     // No such package/component; probably racing with uninstall.  In any
6383                     // event it means we have nothing further to do here.
6384                     return;
6385                 }
6386                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6387                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6388                 if (packageDisabled) {
6389                     // Entire package is disabled.
6390                     // No need to continue to check component states.
6391                     disabledClasses = null;
6392                     break;
6393                 }
6394             } else {
6395                 try {
6396                     enabled = pm.getComponentEnabledSetting(
6397                             new ComponentName(packageName, changedClass),
6398                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6399                 } catch (Exception e) {
6400                     // As above, probably racing with uninstall.
6401                     return;
6402                 }
6403                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6404                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6405                     if (disabledClasses == null) {
6406                         disabledClasses = new ArraySet<>(changedClasses.length);
6407                     }
6408                     disabledClasses.add(changedClass);
6409                 }
6410             }
6411         }
6412
6413         if (!packageDisabled && disabledClasses == null) {
6414             // Nothing to do here...
6415             return;
6416         }
6417
6418         // Clean-up disabled activities.
6419         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6420                 packageName, disabledClasses, true, false, userId) && mBooted) {
6421             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6422             mStackSupervisor.scheduleIdleLocked();
6423         }
6424
6425         // Clean-up disabled tasks
6426         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6427
6428         // Clean-up disabled services.
6429         mServices.bringDownDisabledPackageServicesLocked(
6430                 packageName, disabledClasses, userId, false, killProcess, true);
6431
6432         // Clean-up disabled providers.
6433         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6434         mProviderMap.collectPackageProvidersLocked(
6435                 packageName, disabledClasses, true, false, userId, providers);
6436         for (int i = providers.size() - 1; i >= 0; i--) {
6437             removeDyingProviderLocked(null, providers.get(i), true);
6438         }
6439
6440         // Clean-up disabled broadcast receivers.
6441         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6442             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6443                     packageName, disabledClasses, userId, true);
6444         }
6445
6446     }
6447
6448     final boolean clearBroadcastQueueForUserLocked(int userId) {
6449         boolean didSomething = false;
6450         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6451             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6452                     null, null, userId, true);
6453         }
6454         return didSomething;
6455     }
6456
6457     final boolean forceStopPackageLocked(String packageName, int appId,
6458             boolean callerWillRestart, boolean purgeCache, boolean doit,
6459             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6460         int i;
6461
6462         if (userId == UserHandle.USER_ALL && packageName == null) {
6463             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6464         }
6465
6466         if (appId < 0 && packageName != null) {
6467             try {
6468                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6469                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6470             } catch (RemoteException e) {
6471             }
6472         }
6473
6474         if (doit) {
6475             if (packageName != null) {
6476                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6477                         + " user=" + userId + ": " + reason);
6478             } else {
6479                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6480             }
6481
6482             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6483         }
6484
6485         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6486                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6487                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6488
6489         didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6490
6491         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6492                 packageName, null, doit, evenPersistent, userId)) {
6493             if (!doit) {
6494                 return true;
6495             }
6496             didSomething = true;
6497         }
6498
6499         if (mServices.bringDownDisabledPackageServicesLocked(
6500                 packageName, null, userId, evenPersistent, true, doit)) {
6501             if (!doit) {
6502                 return true;
6503             }
6504             didSomething = true;
6505         }
6506
6507         if (packageName == null) {
6508             // Remove all sticky broadcasts from this user.
6509             mStickyBroadcasts.remove(userId);
6510         }
6511
6512         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6513         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6514                 userId, providers)) {
6515             if (!doit) {
6516                 return true;
6517             }
6518             didSomething = true;
6519         }
6520         for (i = providers.size() - 1; i >= 0; i--) {
6521             removeDyingProviderLocked(null, providers.get(i), true);
6522         }
6523
6524         // Remove transient permissions granted from/to this package/user
6525         removeUriPermissionsForPackageLocked(packageName, userId, false);
6526
6527         if (doit) {
6528             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6529                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6530                         packageName, null, userId, doit);
6531             }
6532         }
6533
6534         if (packageName == null || uninstalling) {
6535             // Remove pending intents.  For now we only do this when force
6536             // stopping users, because we have some problems when doing this
6537             // for packages -- app widgets are not currently cleaned up for
6538             // such packages, so they can be left with bad pending intents.
6539             if (mIntentSenderRecords.size() > 0) {
6540                 Iterator<WeakReference<PendingIntentRecord>> it
6541                         = mIntentSenderRecords.values().iterator();
6542                 while (it.hasNext()) {
6543                     WeakReference<PendingIntentRecord> wpir = it.next();
6544                     if (wpir == null) {
6545                         it.remove();
6546                         continue;
6547                     }
6548                     PendingIntentRecord pir = wpir.get();
6549                     if (pir == null) {
6550                         it.remove();
6551                         continue;
6552                     }
6553                     if (packageName == null) {
6554                         // Stopping user, remove all objects for the user.
6555                         if (pir.key.userId != userId) {
6556                             // Not the same user, skip it.
6557                             continue;
6558                         }
6559                     } else {
6560                         if (UserHandle.getAppId(pir.uid) != appId) {
6561                             // Different app id, skip it.
6562                             continue;
6563                         }
6564                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6565                             // Different user, skip it.
6566                             continue;
6567                         }
6568                         if (!pir.key.packageName.equals(packageName)) {
6569                             // Different package, skip it.
6570                             continue;
6571                         }
6572                     }
6573                     if (!doit) {
6574                         return true;
6575                     }
6576                     didSomething = true;
6577                     it.remove();
6578                     makeIntentSenderCanceledLocked(pir);
6579                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6580                         pir.key.activity.pendingResults.remove(pir.ref);
6581                     }
6582                 }
6583             }
6584         }
6585
6586         if (doit) {
6587             if (purgeCache && packageName != null) {
6588                 AttributeCache ac = AttributeCache.instance();
6589                 if (ac != null) {
6590                     ac.removePackage(packageName);
6591                 }
6592             }
6593             if (mBooted) {
6594                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6595                 mStackSupervisor.scheduleIdleLocked();
6596             }
6597         }
6598
6599         return didSomething;
6600     }
6601
6602     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6603         return removeProcessNameLocked(name, uid, null);
6604     }
6605
6606     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6607             final ProcessRecord expecting) {
6608         ProcessRecord old = mProcessNames.get(name, uid);
6609         // Only actually remove when the currently recorded value matches the
6610         // record that we expected; if it doesn't match then we raced with a
6611         // newly created process and we don't want to destroy the new one.
6612         if ((expecting == null) || (old == expecting)) {
6613             mProcessNames.remove(name, uid);
6614         }
6615         if (old != null && old.uidRecord != null) {
6616             old.uidRecord.numProcs--;
6617             if (old.uidRecord.numProcs == 0) {
6618                 // No more processes using this uid, tell clients it is gone.
6619                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6620                         "No more processes in " + old.uidRecord);
6621                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6622                 EventLogTags.writeAmUidStopped(uid);
6623                 mActiveUids.remove(uid);
6624                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6625             }
6626             old.uidRecord = null;
6627         }
6628         mIsolatedProcesses.remove(uid);
6629         return old;
6630     }
6631
6632     private final void addProcessNameLocked(ProcessRecord proc) {
6633         // We shouldn't already have a process under this name, but just in case we
6634         // need to clean up whatever may be there now.
6635         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6636         if (old == proc && proc.persistent) {
6637             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6638             Slog.w(TAG, "Re-adding persistent process " + proc);
6639         } else if (old != null) {
6640             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6641         }
6642         UidRecord uidRec = mActiveUids.get(proc.uid);
6643         if (uidRec == null) {
6644             uidRec = new UidRecord(proc.uid);
6645             // This is the first appearance of the uid, report it now!
6646             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6647                     "Creating new process uid: " + uidRec);
6648             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6649                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6650                 uidRec.setWhitelist = uidRec.curWhitelist = true;
6651             }
6652             uidRec.updateHasInternetPermission();
6653             mActiveUids.put(proc.uid, uidRec);
6654             EventLogTags.writeAmUidRunning(uidRec.uid);
6655             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6656             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6657         }
6658         proc.uidRecord = uidRec;
6659
6660         // Reset render thread tid if it was already set, so new process can set it again.
6661         proc.renderThreadTid = 0;
6662         uidRec.numProcs++;
6663         mProcessNames.put(proc.processName, proc.uid, proc);
6664         if (proc.isolated) {
6665             mIsolatedProcesses.put(proc.uid, proc);
6666         }
6667     }
6668
6669     boolean removeProcessLocked(ProcessRecord app,
6670             boolean callerWillRestart, boolean allowRestart, String reason) {
6671         final String name = app.processName;
6672         final int uid = app.uid;
6673         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6674             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6675
6676         ProcessRecord old = mProcessNames.get(name, uid);
6677         if (old != app) {
6678             // This process is no longer active, so nothing to do.
6679             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6680             return false;
6681         }
6682         removeProcessNameLocked(name, uid);
6683         if (mHeavyWeightProcess == app) {
6684             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6685                     mHeavyWeightProcess.userId, 0));
6686             mHeavyWeightProcess = null;
6687         }
6688         boolean needRestart = false;
6689         if (app.pid > 0 && app.pid != MY_PID) {
6690             int pid = app.pid;
6691             synchronized (mPidsSelfLocked) {
6692                 mPidsSelfLocked.remove(pid);
6693                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6694             }
6695             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6696             if (app.isolated) {
6697                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6698                 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6699             }
6700             boolean willRestart = false;
6701             if (app.persistent && !app.isolated) {
6702                 if (!callerWillRestart) {
6703                     willRestart = true;
6704                 } else {
6705                     needRestart = true;
6706                 }
6707             }
6708             app.kill(reason, true);
6709             handleAppDiedLocked(app, willRestart, allowRestart);
6710             if (willRestart) {
6711                 removeLruProcessLocked(app);
6712                 addAppLocked(app.info, null, false, null /* ABI override */);
6713             }
6714         } else {
6715             mRemovedProcesses.add(app);
6716         }
6717
6718         return needRestart;
6719     }
6720
6721     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6722         cleanupAppInLaunchingProvidersLocked(app, true);
6723         removeProcessLocked(app, false, true, "timeout publishing content providers");
6724     }
6725
6726     private final void processStartTimedOutLocked(ProcessRecord app) {
6727         final int pid = app.pid;
6728         boolean gone = false;
6729         synchronized (mPidsSelfLocked) {
6730             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6731             if (knownApp != null && knownApp.thread == null) {
6732                 mPidsSelfLocked.remove(pid);
6733                 gone = true;
6734             }
6735         }
6736
6737         if (gone) {
6738             Slog.w(TAG, "Process " + app + " failed to attach");
6739             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6740                     pid, app.uid, app.processName);
6741             removeProcessNameLocked(app.processName, app.uid);
6742             if (mHeavyWeightProcess == app) {
6743                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6744                         mHeavyWeightProcess.userId, 0));
6745                 mHeavyWeightProcess = null;
6746             }
6747             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6748             if (app.isolated) {
6749                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6750             }
6751             // Take care of any launching providers waiting for this process.
6752             cleanupAppInLaunchingProvidersLocked(app, true);
6753             // Take care of any services that are waiting for the process.
6754             mServices.processStartTimedOutLocked(app);
6755             app.kill("start timeout", true);
6756             removeLruProcessLocked(app);
6757             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6758                 Slog.w(TAG, "Unattached app died before backup, skipping");
6759                 mHandler.post(new Runnable() {
6760                 @Override
6761                     public void run(){
6762                         try {
6763                             IBackupManager bm = IBackupManager.Stub.asInterface(
6764                                     ServiceManager.getService(Context.BACKUP_SERVICE));
6765                             bm.agentDisconnected(app.info.packageName);
6766                         } catch (RemoteException e) {
6767                             // Can't happen; the backup manager is local
6768                         }
6769                     }
6770                 });
6771             }
6772             if (isPendingBroadcastProcessLocked(pid)) {
6773                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6774                 skipPendingBroadcastLocked(pid);
6775             }
6776         } else {
6777             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6778         }
6779     }
6780
6781     private final boolean attachApplicationLocked(IApplicationThread thread,
6782             int pid) {
6783
6784         // Find the application record that is being attached...  either via
6785         // the pid if we are running in multiple processes, or just pull the
6786         // next app record if we are emulating process with anonymous threads.
6787         ProcessRecord app;
6788         long startTime = SystemClock.uptimeMillis();
6789         if (pid != MY_PID && pid >= 0) {
6790             synchronized (mPidsSelfLocked) {
6791                 app = mPidsSelfLocked.get(pid);
6792             }
6793         } else {
6794             app = null;
6795         }
6796
6797         if (app == null) {
6798             Slog.w(TAG, "No pending application record for pid " + pid
6799                     + " (IApplicationThread " + thread + "); dropping process");
6800             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6801             if (pid > 0 && pid != MY_PID) {
6802                 killProcessQuiet(pid);
6803                 //TODO: killProcessGroup(app.info.uid, pid);
6804             } else {
6805                 try {
6806                     thread.scheduleExit();
6807                 } catch (Exception e) {
6808                     // Ignore exceptions.
6809                 }
6810             }
6811             return false;
6812         }
6813
6814         // If this application record is still attached to a previous
6815         // process, clean it up now.
6816         if (app.thread != null) {
6817             handleAppDiedLocked(app, true, true);
6818         }
6819
6820         // Tell the process all about itself.
6821
6822         if (DEBUG_ALL) Slog.v(
6823                 TAG, "Binding process pid " + pid + " to record " + app);
6824
6825         final String processName = app.processName;
6826         try {
6827             AppDeathRecipient adr = new AppDeathRecipient(
6828                     app, pid, thread);
6829             thread.asBinder().linkToDeath(adr, 0);
6830             app.deathRecipient = adr;
6831         } catch (RemoteException e) {
6832             app.resetPackageList(mProcessStats);
6833             startProcessLocked(app, "link fail", processName);
6834             return false;
6835         }
6836
6837         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6838
6839         app.makeActive(thread, mProcessStats);
6840         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6841         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6842         app.forcingToImportant = null;
6843         updateProcessForegroundLocked(app, false, false);
6844         app.hasShownUi = false;
6845         app.debugging = false;
6846         app.cached = false;
6847         app.killedByAm = false;
6848         app.killed = false;
6849
6850
6851         // We carefully use the same state that PackageManager uses for
6852         // filtering, since we use this flag to decide if we need to install
6853         // providers when user is unlocked later
6854         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6855
6856         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6857
6858         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6859         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6860
6861         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6862             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6863             msg.obj = app;
6864             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6865         }
6866
6867         checkTime(startTime, "attachApplicationLocked: before bindApplication");
6868
6869         if (!normalMode) {
6870             Slog.i(TAG, "Launching preboot mode app: " + app);
6871         }
6872
6873         if (DEBUG_ALL) Slog.v(
6874             TAG, "New app record " + app
6875             + " thread=" + thread.asBinder() + " pid=" + pid);
6876         try {
6877             int testMode = ApplicationThreadConstants.DEBUG_OFF;
6878             if (mDebugApp != null && mDebugApp.equals(processName)) {
6879                 testMode = mWaitForDebugger
6880                     ? ApplicationThreadConstants.DEBUG_WAIT
6881                     : ApplicationThreadConstants.DEBUG_ON;
6882                 app.debugging = true;
6883                 if (mDebugTransient) {
6884                     mDebugApp = mOrigDebugApp;
6885                     mWaitForDebugger = mOrigWaitForDebugger;
6886                 }
6887             }
6888             String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6889             ParcelFileDescriptor profileFd = null;
6890             int samplingInterval = 0;
6891             boolean profileAutoStop = false;
6892             boolean profileStreamingOutput = false;
6893             if (mProfileApp != null && mProfileApp.equals(processName)) {
6894                 mProfileProc = app;
6895                 profileFile = mProfileFile;
6896                 profileFd = mProfileFd;
6897                 samplingInterval = mSamplingInterval;
6898                 profileAutoStop = mAutoStopProfiler;
6899                 profileStreamingOutput = mStreamingOutput;
6900             }
6901             boolean enableTrackAllocation = false;
6902             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6903                 enableTrackAllocation = true;
6904                 mTrackAllocationApp = null;
6905             }
6906
6907             // If the app is being launched for restore or full backup, set it up specially
6908             boolean isRestrictedBackupMode = false;
6909             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6910                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6911                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6912                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6913                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6914             }
6915
6916             if (app.instr != null) {
6917                 notifyPackageUse(app.instr.mClass.getPackageName(),
6918                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6919             }
6920             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6921                     + processName + " with config " + getGlobalConfiguration());
6922             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6923             app.compat = compatibilityInfoForPackageLocked(appInfo);
6924             if (profileFd != null) {
6925                 profileFd = profileFd.dup();
6926             }
6927             ProfilerInfo profilerInfo = profileFile == null ? null
6928                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6929                                        profileStreamingOutput);
6930
6931             // We deprecated Build.SERIAL and it is not accessible to
6932             // apps that target the v2 security sandbox. Since access to
6933             // the serial is now behind a permission we push down the value.
6934             String buildSerial = Build.UNKNOWN;
6935             if (appInfo.targetSandboxVersion != 2) {
6936                 buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6937                         ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6938                         .getSerial();
6939             }
6940
6941             // Check if this is a secondary process that should be incorporated into some
6942             // currently active instrumentation.  (Note we do this AFTER all of the profiling
6943             // stuff above because profiling can currently happen only in the primary
6944             // instrumentation process.)
6945             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6946                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6947                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6948                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6949                         if (aInstr.mTargetProcesses.length == 0) {
6950                             // This is the wildcard mode, where every process brought up for
6951                             // the target instrumentation should be included.
6952                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6953                                 app.instr = aInstr;
6954                                 aInstr.mRunningProcesses.add(app);
6955                             }
6956                         } else {
6957                             for (String proc : aInstr.mTargetProcesses) {
6958                                 if (proc.equals(app.processName)) {
6959                                     app.instr = aInstr;
6960                                     aInstr.mRunningProcesses.add(app);
6961                                     break;
6962                                 }
6963                             }
6964                         }
6965                     }
6966                 }
6967             }
6968
6969             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6970             mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
6971             if (app.instr != null) {
6972                 thread.bindApplication(processName, appInfo, providers,
6973                         app.instr.mClass,
6974                         profilerInfo, app.instr.mArguments,
6975                         app.instr.mWatcher,
6976                         app.instr.mUiAutomationConnection, testMode,
6977                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
6978                         isRestrictedBackupMode || !normalMode, app.persistent,
6979                         new Configuration(getGlobalConfiguration()), app.compat,
6980                         getCommonServicesLocked(app.isolated),
6981                         mCoreSettingsObserver.getCoreSettingsLocked(),
6982                         buildSerial);
6983             } else {
6984                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6985                         null, null, null, testMode,
6986                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
6987                         isRestrictedBackupMode || !normalMode, app.persistent,
6988                         new Configuration(getGlobalConfiguration()), app.compat,
6989                         getCommonServicesLocked(app.isolated),
6990                         mCoreSettingsObserver.getCoreSettingsLocked(),
6991                         buildSerial);
6992             }
6993
6994             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6995             updateLruProcessLocked(app, false, null);
6996             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6997             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6998         } catch (Exception e) {
6999             // todo: Yikes!  What should we do?  For now we will try to
7000             // start another process, but that could easily get us in
7001             // an infinite loop of restarting processes...
7002             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7003
7004             app.resetPackageList(mProcessStats);
7005             app.unlinkDeathRecipient();
7006             startProcessLocked(app, "bind fail", processName);
7007             return false;
7008         }
7009
7010         // Remove this record from the list of starting applications.
7011         mPersistentStartingProcesses.remove(app);
7012         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7013                 "Attach application locked removing on hold: " + app);
7014         mProcessesOnHold.remove(app);
7015
7016         boolean badApp = false;
7017         boolean didSomething = false;
7018
7019         // See if the top visible activity is waiting to run in this process...
7020         if (normalMode) {
7021             try {
7022                 if (mStackSupervisor.attachApplicationLocked(app)) {
7023                     didSomething = true;
7024                 }
7025             } catch (Exception e) {
7026                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7027                 badApp = true;
7028             }
7029         }
7030
7031         // Find any services that should be running in this process...
7032         if (!badApp) {
7033             try {
7034                 didSomething |= mServices.attachApplicationLocked(app, processName);
7035                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7036             } catch (Exception e) {
7037                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7038                 badApp = true;
7039             }
7040         }
7041
7042         // Check if a next-broadcast receiver is in this process...
7043         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7044             try {
7045                 didSomething |= sendPendingBroadcastsLocked(app);
7046                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7047             } catch (Exception e) {
7048                 // If the app died trying to launch the receiver we declare it 'bad'
7049                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7050                 badApp = true;
7051             }
7052         }
7053
7054         // Check whether the next backup agent is in this process...
7055         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7056             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7057                     "New app is backup target, launching agent for " + app);
7058             notifyPackageUse(mBackupTarget.appInfo.packageName,
7059                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7060             try {
7061                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7062                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7063                         mBackupTarget.backupMode);
7064             } catch (Exception e) {
7065                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7066                 badApp = true;
7067             }
7068         }
7069
7070         if (badApp) {
7071             app.kill("error during init", true);
7072             handleAppDiedLocked(app, false, true);
7073             return false;
7074         }
7075
7076         if (!didSomething) {
7077             updateOomAdjLocked();
7078             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7079         }
7080
7081         return true;
7082     }
7083
7084     @Override
7085     public final void attachApplication(IApplicationThread thread) {
7086         synchronized (this) {
7087             int callingPid = Binder.getCallingPid();
7088             final long origId = Binder.clearCallingIdentity();
7089             attachApplicationLocked(thread, callingPid);
7090             Binder.restoreCallingIdentity(origId);
7091         }
7092     }
7093
7094     @Override
7095     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7096         final long origId = Binder.clearCallingIdentity();
7097         synchronized (this) {
7098             ActivityStack stack = ActivityRecord.getStackLocked(token);
7099             if (stack != null) {
7100                 ActivityRecord r =
7101                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7102                                 false /* processPausingActivities */, config);
7103                 if (stopProfiling) {
7104                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
7105                         try {
7106                             mProfileFd.close();
7107                         } catch (IOException e) {
7108                         }
7109                         clearProfilerLocked();
7110                     }
7111                 }
7112             }
7113         }
7114         Binder.restoreCallingIdentity(origId);
7115     }
7116
7117     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7118         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7119                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7120     }
7121
7122     void enableScreenAfterBoot() {
7123         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7124                 SystemClock.uptimeMillis());
7125         mWindowManager.enableScreenAfterBoot();
7126
7127         synchronized (this) {
7128             updateEventDispatchingLocked();
7129         }
7130     }
7131
7132     @Override
7133     public void showBootMessage(final CharSequence msg, final boolean always) {
7134         if (Binder.getCallingUid() != myUid()) {
7135             throw new SecurityException();
7136         }
7137         mWindowManager.showBootMessage(msg, always);
7138     }
7139
7140     @Override
7141     public void keyguardGoingAway(int flags) {
7142         enforceNotIsolatedCaller("keyguardGoingAway");
7143         final long token = Binder.clearCallingIdentity();
7144         try {
7145             synchronized (this) {
7146                 mKeyguardController.keyguardGoingAway(flags);
7147             }
7148         } finally {
7149             Binder.restoreCallingIdentity(token);
7150         }
7151     }
7152
7153     /**
7154      * @return whther the keyguard is currently locked.
7155      */
7156     boolean isKeyguardLocked() {
7157         return mKeyguardController.isKeyguardLocked();
7158     }
7159
7160     final void finishBooting() {
7161         synchronized (this) {
7162             if (!mBootAnimationComplete) {
7163                 mCallFinishBooting = true;
7164                 return;
7165             }
7166             mCallFinishBooting = false;
7167         }
7168
7169         ArraySet<String> completedIsas = new ArraySet<String>();
7170         for (String abi : Build.SUPPORTED_ABIS) {
7171             zygoteProcess.establishZygoteConnectionForAbi(abi);
7172             final String instructionSet = VMRuntime.getInstructionSet(abi);
7173             if (!completedIsas.contains(instructionSet)) {
7174                 try {
7175                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7176                 } catch (InstallerException e) {
7177                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7178                             e.getMessage() +")");
7179                 }
7180                 completedIsas.add(instructionSet);
7181             }
7182         }
7183
7184         IntentFilter pkgFilter = new IntentFilter();
7185         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7186         pkgFilter.addDataScheme("package");
7187         mContext.registerReceiver(new BroadcastReceiver() {
7188             @Override
7189             public void onReceive(Context context, Intent intent) {
7190                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7191                 if (pkgs != null) {
7192                     for (String pkg : pkgs) {
7193                         synchronized (ActivityManagerService.this) {
7194                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7195                                     0, "query restart")) {
7196                                 setResultCode(Activity.RESULT_OK);
7197                                 return;
7198                             }
7199                         }
7200                     }
7201                 }
7202             }
7203         }, pkgFilter);
7204
7205         IntentFilter dumpheapFilter = new IntentFilter();
7206         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7207         mContext.registerReceiver(new BroadcastReceiver() {
7208             @Override
7209             public void onReceive(Context context, Intent intent) {
7210                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7211                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7212                 } else {
7213                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7214                 }
7215             }
7216         }, dumpheapFilter);
7217
7218         // Let system services know.
7219         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7220
7221         synchronized (this) {
7222             // Ensure that any processes we had put on hold are now started
7223             // up.
7224             final int NP = mProcessesOnHold.size();
7225             if (NP > 0) {
7226                 ArrayList<ProcessRecord> procs =
7227                     new ArrayList<ProcessRecord>(mProcessesOnHold);
7228                 for (int ip=0; ip<NP; ip++) {
7229                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7230                             + procs.get(ip));
7231                     startProcessLocked(procs.get(ip), "on-hold", null);
7232                 }
7233             }
7234
7235             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7236                 // Start looking for apps that are abusing wake locks.
7237                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7238                 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
7239                 // Tell anyone interested that we are done booting!
7240                 SystemProperties.set("sys.boot_completed", "1");
7241
7242                 // And trigger dev.bootcomplete if we are not showing encryption progress
7243                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7244                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7245                     SystemProperties.set("dev.bootcomplete", "1");
7246                 }
7247                 mUserController.sendBootCompletedLocked(
7248                         new IIntentReceiver.Stub() {
7249                             @Override
7250                             public void performReceive(Intent intent, int resultCode,
7251                                     String data, Bundle extras, boolean ordered,
7252                                     boolean sticky, int sendingUser) {
7253                                 synchronized (ActivityManagerService.this) {
7254                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7255                                             true, false);
7256                                 }
7257                             }
7258                         });
7259                 scheduleStartProfilesLocked();
7260             }
7261         }
7262     }
7263
7264     @Override
7265     public void bootAnimationComplete() {
7266         final boolean callFinishBooting;
7267         synchronized (this) {
7268             callFinishBooting = mCallFinishBooting;
7269             mBootAnimationComplete = true;
7270         }
7271         if (callFinishBooting) {
7272             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7273             finishBooting();
7274             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7275         }
7276     }
7277
7278     final void ensureBootCompleted() {
7279         boolean booting;
7280         boolean enableScreen;
7281         synchronized (this) {
7282             booting = mBooting;
7283             mBooting = false;
7284             enableScreen = !mBooted;
7285             mBooted = true;
7286         }
7287
7288         if (booting) {
7289             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7290             finishBooting();
7291             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7292         }
7293
7294         if (enableScreen) {
7295             enableScreenAfterBoot();
7296         }
7297     }
7298
7299     @Override
7300     public final void activityResumed(IBinder token) {
7301         final long origId = Binder.clearCallingIdentity();
7302         synchronized(this) {
7303             ActivityRecord.activityResumedLocked(token);
7304             mWindowManager.notifyAppResumedFinished(token);
7305         }
7306         Binder.restoreCallingIdentity(origId);
7307     }
7308
7309     @Override
7310     public final void activityPaused(IBinder token) {
7311         final long origId = Binder.clearCallingIdentity();
7312         synchronized(this) {
7313             ActivityStack stack = ActivityRecord.getStackLocked(token);
7314             if (stack != null) {
7315                 stack.activityPausedLocked(token, false);
7316             }
7317         }
7318         Binder.restoreCallingIdentity(origId);
7319     }
7320
7321     @Override
7322     public final void activityStopped(IBinder token, Bundle icicle,
7323             PersistableBundle persistentState, CharSequence description) {
7324         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7325
7326         // Refuse possible leaked file descriptors
7327         if (icicle != null && icicle.hasFileDescriptors()) {
7328             throw new IllegalArgumentException("File descriptors passed in Bundle");
7329         }
7330
7331         final long origId = Binder.clearCallingIdentity();
7332
7333         synchronized (this) {
7334             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7335             if (r != null) {
7336                 r.activityStoppedLocked(icicle, persistentState, description);
7337             }
7338         }
7339
7340         trimApplications();
7341
7342         Binder.restoreCallingIdentity(origId);
7343     }
7344
7345     @Override
7346     public final void activityDestroyed(IBinder token) {
7347         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7348         synchronized (this) {
7349             ActivityStack stack = ActivityRecord.getStackLocked(token);
7350             if (stack != null) {
7351                 stack.activityDestroyedLocked(token, "activityDestroyed");
7352             }
7353         }
7354     }
7355
7356     @Override
7357     public final void activityRelaunched(IBinder token) {
7358         final long origId = Binder.clearCallingIdentity();
7359         synchronized (this) {
7360             mStackSupervisor.activityRelaunchedLocked(token);
7361         }
7362         Binder.restoreCallingIdentity(origId);
7363     }
7364
7365     @Override
7366     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7367             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7368         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7369                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7370         synchronized (this) {
7371             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7372             if (record == null) {
7373                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7374                         + "found for: " + token);
7375             }
7376             record.setSizeConfigurations(horizontalSizeConfiguration,
7377                     verticalSizeConfigurations, smallestSizeConfigurations);
7378         }
7379     }
7380
7381     @Override
7382     public final void backgroundResourcesReleased(IBinder token) {
7383         final long origId = Binder.clearCallingIdentity();
7384         try {
7385             synchronized (this) {
7386                 ActivityStack stack = ActivityRecord.getStackLocked(token);
7387                 if (stack != null) {
7388                     stack.backgroundResourcesReleased();
7389                 }
7390             }
7391         } finally {
7392             Binder.restoreCallingIdentity(origId);
7393         }
7394     }
7395
7396     @Override
7397     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7398         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7399     }
7400
7401     @Override
7402     public final void notifyEnterAnimationComplete(IBinder token) {
7403         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7404     }
7405
7406     @Override
7407     public String getCallingPackage(IBinder token) {
7408         synchronized (this) {
7409             ActivityRecord r = getCallingRecordLocked(token);
7410             return r != null ? r.info.packageName : null;
7411         }
7412     }
7413
7414     @Override
7415     public ComponentName getCallingActivity(IBinder token) {
7416         synchronized (this) {
7417             ActivityRecord r = getCallingRecordLocked(token);
7418             return r != null ? r.intent.getComponent() : null;
7419         }
7420     }
7421
7422     private ActivityRecord getCallingRecordLocked(IBinder token) {
7423         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7424         if (r == null) {
7425             return null;
7426         }
7427         return r.resultTo;
7428     }
7429
7430     @Override
7431     public ComponentName getActivityClassForToken(IBinder token) {
7432         synchronized(this) {
7433             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7434             if (r == null) {
7435                 return null;
7436             }
7437             return r.intent.getComponent();
7438         }
7439     }
7440
7441     @Override
7442     public String getPackageForToken(IBinder token) {
7443         synchronized(this) {
7444             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7445             if (r == null) {
7446                 return null;
7447             }
7448             return r.packageName;
7449         }
7450     }
7451
7452     @Override
7453     public boolean isRootVoiceInteraction(IBinder token) {
7454         synchronized(this) {
7455             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7456             if (r == null) {
7457                 return false;
7458             }
7459             return r.rootVoiceInteraction;
7460         }
7461     }
7462
7463     @Override
7464     public IIntentSender getIntentSender(int type,
7465             String packageName, IBinder token, String resultWho,
7466             int requestCode, Intent[] intents, String[] resolvedTypes,
7467             int flags, Bundle bOptions, int userId) {
7468         enforceNotIsolatedCaller("getIntentSender");
7469         // Refuse possible leaked file descriptors
7470         if (intents != null) {
7471             if (intents.length < 1) {
7472                 throw new IllegalArgumentException("Intents array length must be >= 1");
7473             }
7474             for (int i=0; i<intents.length; i++) {
7475                 Intent intent = intents[i];
7476                 if (intent != null) {
7477                     if (intent.hasFileDescriptors()) {
7478                         throw new IllegalArgumentException("File descriptors passed in Intent");
7479                     }
7480                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7481                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7482                         throw new IllegalArgumentException(
7483                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7484                     }
7485                     intents[i] = new Intent(intent);
7486                 }
7487             }
7488             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7489                 throw new IllegalArgumentException(
7490                         "Intent array length does not match resolvedTypes length");
7491             }
7492         }
7493         if (bOptions != null) {
7494             if (bOptions.hasFileDescriptors()) {
7495                 throw new IllegalArgumentException("File descriptors passed in options");
7496             }
7497         }
7498
7499         synchronized(this) {
7500             int callingUid = Binder.getCallingUid();
7501             int origUserId = userId;
7502             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7503                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7504                     ALLOW_NON_FULL, "getIntentSender", null);
7505             if (origUserId == UserHandle.USER_CURRENT) {
7506                 // We don't want to evaluate this until the pending intent is
7507                 // actually executed.  However, we do want to always do the
7508                 // security checking for it above.
7509                 userId = UserHandle.USER_CURRENT;
7510             }
7511             try {
7512                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7513                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7514                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7515                     if (!UserHandle.isSameApp(callingUid, uid)) {
7516                         String msg = "Permission Denial: getIntentSender() from pid="
7517                             + Binder.getCallingPid()
7518                             + ", uid=" + Binder.getCallingUid()
7519                             + ", (need uid=" + uid + ")"
7520                             + " is not allowed to send as package " + packageName;
7521                         Slog.w(TAG, msg);
7522                         throw new SecurityException(msg);
7523                     }
7524                 }
7525
7526                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7527                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7528
7529             } catch (RemoteException e) {
7530                 throw new SecurityException(e);
7531             }
7532         }
7533     }
7534
7535     IIntentSender getIntentSenderLocked(int type, String packageName,
7536             int callingUid, int userId, IBinder token, String resultWho,
7537             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7538             Bundle bOptions) {
7539         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7540         ActivityRecord activity = null;
7541         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7542             activity = ActivityRecord.isInStackLocked(token);
7543             if (activity == null) {
7544                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7545                 return null;
7546             }
7547             if (activity.finishing) {
7548                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7549                 return null;
7550             }
7551         }
7552
7553         // We're going to be splicing together extras before sending, so we're
7554         // okay poking into any contained extras.
7555         if (intents != null) {
7556             for (int i = 0; i < intents.length; i++) {
7557                 intents[i].setDefusable(true);
7558             }
7559         }
7560         Bundle.setDefusable(bOptions, true);
7561
7562         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7563         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7564         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7565         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7566                 |PendingIntent.FLAG_UPDATE_CURRENT);
7567
7568         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7569                 type, packageName, activity, resultWho,
7570                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7571         WeakReference<PendingIntentRecord> ref;
7572         ref = mIntentSenderRecords.get(key);
7573         PendingIntentRecord rec = ref != null ? ref.get() : null;
7574         if (rec != null) {
7575             if (!cancelCurrent) {
7576                 if (updateCurrent) {
7577                     if (rec.key.requestIntent != null) {
7578                         rec.key.requestIntent.replaceExtras(intents != null ?
7579                                 intents[intents.length - 1] : null);
7580                     }
7581                     if (intents != null) {
7582                         intents[intents.length-1] = rec.key.requestIntent;
7583                         rec.key.allIntents = intents;
7584                         rec.key.allResolvedTypes = resolvedTypes;
7585                     } else {
7586                         rec.key.allIntents = null;
7587                         rec.key.allResolvedTypes = null;
7588                     }
7589                 }
7590                 return rec;
7591             }
7592             makeIntentSenderCanceledLocked(rec);
7593             mIntentSenderRecords.remove(key);
7594         }
7595         if (noCreate) {
7596             return rec;
7597         }
7598         rec = new PendingIntentRecord(this, key, callingUid);
7599         mIntentSenderRecords.put(key, rec.ref);
7600         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7601             if (activity.pendingResults == null) {
7602                 activity.pendingResults
7603                         = new HashSet<WeakReference<PendingIntentRecord>>();
7604             }
7605             activity.pendingResults.add(rec.ref);
7606         }
7607         return rec;
7608     }
7609
7610     @Override
7611     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7612             Intent intent, String resolvedType,
7613             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7614         if (target instanceof PendingIntentRecord) {
7615             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7616                     whitelistToken, finishedReceiver, requiredPermission, options);
7617         } else {
7618             if (intent == null) {
7619                 // Weird case: someone has given us their own custom IIntentSender, and now
7620                 // they have someone else trying to send to it but of course this isn't
7621                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7622                 // supplying an Intent... but we never want to dispatch a null Intent to
7623                 // a receiver, so um...  let's make something up.
7624                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7625                 intent = new Intent(Intent.ACTION_MAIN);
7626             }
7627             try {
7628                 target.send(code, intent, resolvedType, whitelistToken, null,
7629                         requiredPermission, options);
7630             } catch (RemoteException e) {
7631             }
7632             // Platform code can rely on getting a result back when the send is done, but if
7633             // this intent sender is from outside of the system we can't rely on it doing that.
7634             // So instead we don't give it the result receiver, and instead just directly
7635             // report the finish immediately.
7636             if (finishedReceiver != null) {
7637                 try {
7638                     finishedReceiver.performReceive(intent, 0,
7639                             null, null, false, false, UserHandle.getCallingUserId());
7640                 } catch (RemoteException e) {
7641                 }
7642             }
7643             return 0;
7644         }
7645     }
7646
7647     @Override
7648     public void cancelIntentSender(IIntentSender sender) {
7649         if (!(sender instanceof PendingIntentRecord)) {
7650             return;
7651         }
7652         synchronized(this) {
7653             PendingIntentRecord rec = (PendingIntentRecord)sender;
7654             try {
7655                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7656                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7657                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7658                     String msg = "Permission Denial: cancelIntentSender() from pid="
7659                         + Binder.getCallingPid()
7660                         + ", uid=" + Binder.getCallingUid()
7661                         + " is not allowed to cancel package "
7662                         + rec.key.packageName;
7663                     Slog.w(TAG, msg);
7664                     throw new SecurityException(msg);
7665                 }
7666             } catch (RemoteException e) {
7667                 throw new SecurityException(e);
7668             }
7669             cancelIntentSenderLocked(rec, true);
7670         }
7671     }
7672
7673     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7674         makeIntentSenderCanceledLocked(rec);
7675         mIntentSenderRecords.remove(rec.key);
7676         if (cleanActivity && rec.key.activity != null) {
7677             rec.key.activity.pendingResults.remove(rec.ref);
7678         }
7679     }
7680
7681     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7682         rec.canceled = true;
7683         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7684         if (callbacks != null) {
7685             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7686         }
7687     }
7688
7689     @Override
7690     public String getPackageForIntentSender(IIntentSender pendingResult) {
7691         if (!(pendingResult instanceof PendingIntentRecord)) {
7692             return null;
7693         }
7694         try {
7695             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7696             return res.key.packageName;
7697         } catch (ClassCastException e) {
7698         }
7699         return null;
7700     }
7701
7702     @Override
7703     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7704         if (!(sender instanceof PendingIntentRecord)) {
7705             return;
7706         }
7707         synchronized(this) {
7708             ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7709         }
7710     }
7711
7712     @Override
7713     public void unregisterIntentSenderCancelListener(IIntentSender sender,
7714             IResultReceiver receiver) {
7715         if (!(sender instanceof PendingIntentRecord)) {
7716             return;
7717         }
7718         synchronized(this) {
7719             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7720         }
7721     }
7722
7723     @Override
7724     public int getUidForIntentSender(IIntentSender sender) {
7725         if (sender instanceof PendingIntentRecord) {
7726             try {
7727                 PendingIntentRecord res = (PendingIntentRecord)sender;
7728                 return res.uid;
7729             } catch (ClassCastException e) {
7730             }
7731         }
7732         return -1;
7733     }
7734
7735     @Override
7736     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7737         if (!(pendingResult instanceof PendingIntentRecord)) {
7738             return false;
7739         }
7740         try {
7741             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7742             if (res.key.allIntents == null) {
7743                 return false;
7744             }
7745             for (int i=0; i<res.key.allIntents.length; i++) {
7746                 Intent intent = res.key.allIntents[i];
7747                 if (intent.getPackage() != null && intent.getComponent() != null) {
7748                     return false;
7749                 }
7750             }
7751             return true;
7752         } catch (ClassCastException e) {
7753         }
7754         return false;
7755     }
7756
7757     @Override
7758     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7759         if (!(pendingResult instanceof PendingIntentRecord)) {
7760             return false;
7761         }
7762         try {
7763             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7764             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7765                 return true;
7766             }
7767             return false;
7768         } catch (ClassCastException e) {
7769         }
7770         return false;
7771     }
7772
7773     @Override
7774     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7775         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7776                 "getIntentForIntentSender()");
7777         if (!(pendingResult instanceof PendingIntentRecord)) {
7778             return null;
7779         }
7780         try {
7781             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7782             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7783         } catch (ClassCastException e) {
7784         }
7785         return null;
7786     }
7787
7788     @Override
7789     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7790         if (!(pendingResult instanceof PendingIntentRecord)) {
7791             return null;
7792         }
7793         try {
7794             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7795             synchronized (this) {
7796                 return getTagForIntentSenderLocked(res, prefix);
7797             }
7798         } catch (ClassCastException e) {
7799         }
7800         return null;
7801     }
7802
7803     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7804         final Intent intent = res.key.requestIntent;
7805         if (intent != null) {
7806             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7807                     || res.lastTagPrefix.equals(prefix))) {
7808                 return res.lastTag;
7809             }
7810             res.lastTagPrefix = prefix;
7811             final StringBuilder sb = new StringBuilder(128);
7812             if (prefix != null) {
7813                 sb.append(prefix);
7814             }
7815             if (intent.getAction() != null) {
7816                 sb.append(intent.getAction());
7817             } else if (intent.getComponent() != null) {
7818                 intent.getComponent().appendShortString(sb);
7819             } else {
7820                 sb.append("?");
7821             }
7822             return res.lastTag = sb.toString();
7823         }
7824         return null;
7825     }
7826
7827     @Override
7828     public void setProcessLimit(int max) {
7829         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7830                 "setProcessLimit()");
7831         synchronized (this) {
7832             mConstants.setOverrideMaxCachedProcesses(max);
7833         }
7834         trimApplications();
7835     }
7836
7837     @Override
7838     public int getProcessLimit() {
7839         synchronized (this) {
7840             return mConstants.getOverrideMaxCachedProcesses();
7841         }
7842     }
7843
7844     void importanceTokenDied(ImportanceToken token) {
7845         synchronized (ActivityManagerService.this) {
7846             synchronized (mPidsSelfLocked) {
7847                 ImportanceToken cur
7848                     = mImportantProcesses.get(token.pid);
7849                 if (cur != token) {
7850                     return;
7851                 }
7852                 mImportantProcesses.remove(token.pid);
7853                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7854                 if (pr == null) {
7855                     return;
7856                 }
7857                 pr.forcingToImportant = null;
7858                 updateProcessForegroundLocked(pr, false, false);
7859             }
7860             updateOomAdjLocked();
7861         }
7862     }
7863
7864     @Override
7865     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7866         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7867                 "setProcessImportant()");
7868         synchronized(this) {
7869             boolean changed = false;
7870
7871             synchronized (mPidsSelfLocked) {
7872                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7873                 if (pr == null && isForeground) {
7874                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7875                     return;
7876                 }
7877                 ImportanceToken oldToken = mImportantProcesses.get(pid);
7878                 if (oldToken != null) {
7879                     oldToken.token.unlinkToDeath(oldToken, 0);
7880                     mImportantProcesses.remove(pid);
7881                     if (pr != null) {
7882                         pr.forcingToImportant = null;
7883                     }
7884                     changed = true;
7885                 }
7886                 if (isForeground && token != null) {
7887                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7888                         @Override
7889                         public void binderDied() {
7890                             importanceTokenDied(this);
7891                         }
7892                     };
7893                     try {
7894                         token.linkToDeath(newToken, 0);
7895                         mImportantProcesses.put(pid, newToken);
7896                         pr.forcingToImportant = newToken;
7897                         changed = true;
7898                     } catch (RemoteException e) {
7899                         // If the process died while doing this, we will later
7900                         // do the cleanup with the process death link.
7901                     }
7902                 }
7903             }
7904
7905             if (changed) {
7906                 updateOomAdjLocked();
7907             }
7908         }
7909     }
7910
7911     @Override
7912     public boolean isAppForeground(int uid) throws RemoteException {
7913         synchronized (this) {
7914             UidRecord uidRec = mActiveUids.get(uid);
7915             if (uidRec == null || uidRec.idle) {
7916                 return false;
7917             }
7918             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7919         }
7920     }
7921
7922     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7923     // be guarded by permission checking.
7924     int getUidState(int uid) {
7925         synchronized (this) {
7926             return getUidStateLocked(uid);
7927         }
7928     }
7929
7930     int getUidStateLocked(int uid) {
7931         UidRecord uidRec = mActiveUids.get(uid);
7932         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7933     }
7934
7935     @Override
7936     public boolean isInMultiWindowMode(IBinder token) {
7937         final long origId = Binder.clearCallingIdentity();
7938         try {
7939             synchronized(this) {
7940                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7941                 if (r == null) {
7942                     return false;
7943                 }
7944                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7945                 return !r.getTask().mFullscreen;
7946             }
7947         } finally {
7948             Binder.restoreCallingIdentity(origId);
7949         }
7950     }
7951
7952     @Override
7953     public boolean isInPictureInPictureMode(IBinder token) {
7954         final long origId = Binder.clearCallingIdentity();
7955         try {
7956             synchronized(this) {
7957                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
7958             }
7959         } finally {
7960             Binder.restoreCallingIdentity(origId);
7961         }
7962     }
7963
7964     private boolean isInPictureInPictureMode(ActivityRecord r) {
7965         if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
7966                 r.getStack().isInStackLocked(r) == null) {
7967             return false;
7968         }
7969
7970         // If we are animating to fullscreen then we have already dispatched the PIP mode
7971         // changed, so we should reflect that check here as well.
7972         final PinnedActivityStack stack = r.getStack();
7973         final PinnedStackWindowController windowController = stack.getWindowContainerController();
7974         return !windowController.isAnimatingBoundsToFullscreen();
7975     }
7976
7977     @Override
7978     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
7979         final long origId = Binder.clearCallingIdentity();
7980         try {
7981             synchronized(this) {
7982                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7983                         "enterPictureInPictureMode", token, params);
7984
7985                 // If the activity is already in picture in picture mode, then just return early
7986                 if (isInPictureInPictureMode(r)) {
7987                     return true;
7988                 }
7989
7990                 // Activity supports picture-in-picture, now check that we can enter PiP at this
7991                 // point, if it is
7992                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7993                         false /* noThrow */, false /* beforeStopping */)) {
7994                     return false;
7995                 }
7996
7997                 final Runnable enterPipRunnable = () -> {
7998                     // Only update the saved args from the args that are set
7999                     r.pictureInPictureArgs.copyOnlySet(params);
8000                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8001                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8002                     // Adjust the source bounds by the insets for the transition down
8003                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8004                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8005                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8006                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8007                     stack.setPictureInPictureAspectRatio(aspectRatio);
8008                     stack.setPictureInPictureActions(actions);
8009
8010                     MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8011                             r.supportsPictureInPictureWhilePausing);
8012                     logPictureInPictureArgs(params);
8013                 };
8014
8015                 if (isKeyguardLocked()) {
8016                     // If the keyguard is showing or occluded, then try and dismiss it before
8017                     // entering picture-in-picture (this will prompt the user to authenticate if the
8018                     // device is currently locked).
8019                     try {
8020                         dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8021                             @Override
8022                             public void onDismissError() throws RemoteException {
8023                                 // Do nothing
8024                             }
8025
8026                             @Override
8027                             public void onDismissSucceeded() throws RemoteException {
8028                                 mHandler.post(enterPipRunnable);
8029                             }
8030
8031                             @Override
8032                             public void onDismissCancelled() throws RemoteException {
8033                                 // Do nothing
8034                             }
8035                         });
8036                     } catch (RemoteException e) {
8037                         // Local call
8038                     }
8039                 } else {
8040                     // Enter picture in picture immediately otherwise
8041                     enterPipRunnable.run();
8042                 }
8043                 return true;
8044             }
8045         } finally {
8046             Binder.restoreCallingIdentity(origId);
8047         }
8048     }
8049
8050     @Override
8051     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8052         final long origId = Binder.clearCallingIdentity();
8053         try {
8054             synchronized(this) {
8055                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8056                         "setPictureInPictureParams", token, params);
8057
8058                 // Only update the saved args from the args that are set
8059                 r.pictureInPictureArgs.copyOnlySet(params);
8060                 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8061                     // If the activity is already in picture-in-picture, update the pinned stack now
8062                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
8063                     // be used the next time the activity enters PiP
8064                     final PinnedActivityStack stack = r.getStack();
8065                     if (!stack.isAnimatingBoundsToFullscreen()) {
8066                         stack.setPictureInPictureAspectRatio(
8067                                 r.pictureInPictureArgs.getAspectRatio());
8068                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8069                     }
8070                 }
8071                 logPictureInPictureArgs(params);
8072             }
8073         } finally {
8074             Binder.restoreCallingIdentity(origId);
8075         }
8076     }
8077
8078     @Override
8079     public int getMaxNumPictureInPictureActions(IBinder token) {
8080         // Currently, this is a static constant, but later, we may change this to be dependent on
8081         // the context of the activity
8082         return 3;
8083     }
8084
8085     private void logPictureInPictureArgs(PictureInPictureParams params) {
8086         if (params.hasSetActions()) {
8087             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8088                     params.getActions().size());
8089         }
8090         if (params.hasSetAspectRatio()) {
8091             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8092             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8093             MetricsLogger.action(lm);
8094         }
8095     }
8096
8097     /**
8098      * Checks the state of the system and the activity associated with the given {@param token} to
8099      * verify that picture-in-picture is supported for that activity.
8100      *
8101      * @return the activity record for the given {@param token} if all the checks pass.
8102      */
8103     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8104             IBinder token, PictureInPictureParams params) {
8105         if (!mSupportsPictureInPicture) {
8106             throw new IllegalStateException(caller
8107                     + ": Device doesn't support picture-in-picture mode.");
8108         }
8109
8110         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8111         if (r == null) {
8112             throw new IllegalStateException(caller
8113                     + ": Can't find activity for token=" + token);
8114         }
8115
8116         if (!r.supportsPictureInPicture()) {
8117             throw new IllegalStateException(caller
8118                     + ": Current activity does not support picture-in-picture.");
8119         }
8120
8121         if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8122             throw new IllegalStateException(caller
8123                     + ": Activities on the home, assistant, or recents stack not supported");
8124         }
8125
8126         if (params.hasSetAspectRatio()
8127                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8128                         params.getAspectRatio())) {
8129             final float minAspectRatio = mContext.getResources().getFloat(
8130                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8131             final float maxAspectRatio = mContext.getResources().getFloat(
8132                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8133             throw new IllegalArgumentException(String.format(caller
8134                     + ": Aspect ratio is too extreme (must be between %f and %f).",
8135                             minAspectRatio, maxAspectRatio));
8136         }
8137
8138         // Truncate the number of actions if necessary
8139         params.truncateActions(getMaxNumPictureInPictureActions(token));
8140
8141         return r;
8142     }
8143
8144     // =========================================================
8145     // PROCESS INFO
8146     // =========================================================
8147
8148     static class ProcessInfoService extends IProcessInfoService.Stub {
8149         final ActivityManagerService mActivityManagerService;
8150         ProcessInfoService(ActivityManagerService activityManagerService) {
8151             mActivityManagerService = activityManagerService;
8152         }
8153
8154         @Override
8155         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8156             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8157                     /*in*/ pids, /*out*/ states, null);
8158         }
8159
8160         @Override
8161         public void getProcessStatesAndOomScoresFromPids(
8162                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8163             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8164                     /*in*/ pids, /*out*/ states, /*out*/ scores);
8165         }
8166     }
8167
8168     /**
8169      * For each PID in the given input array, write the current process state
8170      * for that process into the states array, or -1 to indicate that no
8171      * process with the given PID exists. If scores array is provided, write
8172      * the oom score for the process into the scores array, with INVALID_ADJ
8173      * indicating the PID doesn't exist.
8174      */
8175     public void getProcessStatesAndOomScoresForPIDs(
8176             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8177         if (scores != null) {
8178             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8179                     "getProcessStatesAndOomScoresForPIDs()");
8180         }
8181
8182         if (pids == null) {
8183             throw new NullPointerException("pids");
8184         } else if (states == null) {
8185             throw new NullPointerException("states");
8186         } else if (pids.length != states.length) {
8187             throw new IllegalArgumentException("pids and states arrays have different lengths!");
8188         } else if (scores != null && pids.length != scores.length) {
8189             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8190         }
8191
8192         synchronized (mPidsSelfLocked) {
8193             for (int i = 0; i < pids.length; i++) {
8194                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8195                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8196                         pr.curProcState;
8197                 if (scores != null) {
8198                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8199                 }
8200             }
8201         }
8202     }
8203
8204     // =========================================================
8205     // PERMISSIONS
8206     // =========================================================
8207
8208     static class PermissionController extends IPermissionController.Stub {
8209         ActivityManagerService mActivityManagerService;
8210         PermissionController(ActivityManagerService activityManagerService) {
8211             mActivityManagerService = activityManagerService;
8212         }
8213
8214         @Override
8215         public boolean checkPermission(String permission, int pid, int uid) {
8216             return mActivityManagerService.checkPermission(permission, pid,
8217                     uid) == PackageManager.PERMISSION_GRANTED;
8218         }
8219
8220         @Override
8221         public String[] getPackagesForUid(int uid) {
8222             return mActivityManagerService.mContext.getPackageManager()
8223                     .getPackagesForUid(uid);
8224         }
8225
8226         @Override
8227         public boolean isRuntimePermission(String permission) {
8228             try {
8229                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8230                         .getPermissionInfo(permission, 0);
8231                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8232                         == PermissionInfo.PROTECTION_DANGEROUS;
8233             } catch (NameNotFoundException nnfe) {
8234                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8235             }
8236             return false;
8237         }
8238     }
8239
8240     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8241         @Override
8242         public int checkComponentPermission(String permission, int pid, int uid,
8243                 int owningUid, boolean exported) {
8244             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8245                     owningUid, exported);
8246         }
8247
8248         @Override
8249         public Object getAMSLock() {
8250             return ActivityManagerService.this;
8251         }
8252     }
8253
8254     /**
8255      * This can be called with or without the global lock held.
8256      */
8257     int checkComponentPermission(String permission, int pid, int uid,
8258             int owningUid, boolean exported) {
8259         if (pid == MY_PID) {
8260             return PackageManager.PERMISSION_GRANTED;
8261         }
8262         return ActivityManager.checkComponentPermission(permission, uid,
8263                 owningUid, exported);
8264     }
8265
8266     /**
8267      * As the only public entry point for permissions checking, this method
8268      * can enforce the semantic that requesting a check on a null global
8269      * permission is automatically denied.  (Internally a null permission
8270      * string is used when calling {@link #checkComponentPermission} in cases
8271      * when only uid-based security is needed.)
8272      *
8273      * This can be called with or without the global lock held.
8274      */
8275     @Override
8276     public int checkPermission(String permission, int pid, int uid) {
8277         if (permission == null) {
8278             return PackageManager.PERMISSION_DENIED;
8279         }
8280         return checkComponentPermission(permission, pid, uid, -1, true);
8281     }
8282
8283     @Override
8284     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8285         if (permission == null) {
8286             return PackageManager.PERMISSION_DENIED;
8287         }
8288
8289         // We might be performing an operation on behalf of an indirect binder
8290         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8291         // client identity accordingly before proceeding.
8292         Identity tlsIdentity = sCallerIdentity.get();
8293         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8294             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8295                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8296             uid = tlsIdentity.uid;
8297             pid = tlsIdentity.pid;
8298         }
8299
8300         return checkComponentPermission(permission, pid, uid, -1, true);
8301     }
8302
8303     /**
8304      * Binder IPC calls go through the public entry point.
8305      * This can be called with or without the global lock held.
8306      */
8307     int checkCallingPermission(String permission) {
8308         return checkPermission(permission,
8309                 Binder.getCallingPid(),
8310                 UserHandle.getAppId(Binder.getCallingUid()));
8311     }
8312
8313     /**
8314      * This can be called with or without the global lock held.
8315      */
8316     void enforceCallingPermission(String permission, String func) {
8317         if (checkCallingPermission(permission)
8318                 == PackageManager.PERMISSION_GRANTED) {
8319             return;
8320         }
8321
8322         String msg = "Permission Denial: " + func + " from pid="
8323                 + Binder.getCallingPid()
8324                 + ", uid=" + Binder.getCallingUid()
8325                 + " requires " + permission;
8326         Slog.w(TAG, msg);
8327         throw new SecurityException(msg);
8328     }
8329
8330     /**
8331      * Determine if UID is holding permissions required to access {@link Uri} in
8332      * the given {@link ProviderInfo}. Final permission checking is always done
8333      * in {@link ContentProvider}.
8334      */
8335     private final boolean checkHoldingPermissionsLocked(
8336             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8337         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8338                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8339         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8340             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8341                     != PERMISSION_GRANTED) {
8342                 return false;
8343             }
8344         }
8345         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8346     }
8347
8348     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8349             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8350         if (pi.applicationInfo.uid == uid) {
8351             return true;
8352         } else if (!pi.exported) {
8353             return false;
8354         }
8355
8356         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8357         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8358         try {
8359             // check if target holds top-level <provider> permissions
8360             if (!readMet && pi.readPermission != null && considerUidPermissions
8361                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8362                 readMet = true;
8363             }
8364             if (!writeMet && pi.writePermission != null && considerUidPermissions
8365                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8366                 writeMet = true;
8367             }
8368
8369             // track if unprotected read/write is allowed; any denied
8370             // <path-permission> below removes this ability
8371             boolean allowDefaultRead = pi.readPermission == null;
8372             boolean allowDefaultWrite = pi.writePermission == null;
8373
8374             // check if target holds any <path-permission> that match uri
8375             final PathPermission[] pps = pi.pathPermissions;
8376             if (pps != null) {
8377                 final String path = grantUri.uri.getPath();
8378                 int i = pps.length;
8379                 while (i > 0 && (!readMet || !writeMet)) {
8380                     i--;
8381                     PathPermission pp = pps[i];
8382                     if (pp.match(path)) {
8383                         if (!readMet) {
8384                             final String pprperm = pp.getReadPermission();
8385                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8386                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
8387                                     + ": match=" + pp.match(path)
8388                                     + " check=" + pm.checkUidPermission(pprperm, uid));
8389                             if (pprperm != null) {
8390                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8391                                         == PERMISSION_GRANTED) {
8392                                     readMet = true;
8393                                 } else {
8394                                     allowDefaultRead = false;
8395                                 }
8396                             }
8397                         }
8398                         if (!writeMet) {
8399                             final String ppwperm = pp.getWritePermission();
8400                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8401                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
8402                                     + ": match=" + pp.match(path)
8403                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
8404                             if (ppwperm != null) {
8405                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8406                                         == PERMISSION_GRANTED) {
8407                                     writeMet = true;
8408                                 } else {
8409                                     allowDefaultWrite = false;
8410                                 }
8411                             }
8412                         }
8413                     }
8414                 }
8415             }
8416
8417             // grant unprotected <provider> read/write, if not blocked by
8418             // <path-permission> above
8419             if (allowDefaultRead) readMet = true;
8420             if (allowDefaultWrite) writeMet = true;
8421
8422         } catch (RemoteException e) {
8423             return false;
8424         }
8425
8426         return readMet && writeMet;
8427     }
8428
8429     public boolean isAppStartModeDisabled(int uid, String packageName) {
8430         synchronized (this) {
8431             return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8432                     == ActivityManager.APP_START_MODE_DISABLED;
8433         }
8434     }
8435
8436     // Unified app-op and target sdk check
8437     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8438         // Apps that target O+ are always subject to background check
8439         if (packageTargetSdk >= Build.VERSION_CODES.O) {
8440             if (DEBUG_BACKGROUND_CHECK) {
8441                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8442             }
8443             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8444         }
8445         // ...and legacy apps get an AppOp check
8446         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8447                 uid, packageName);
8448         if (DEBUG_BACKGROUND_CHECK) {
8449             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8450         }
8451         switch (appop) {
8452             case AppOpsManager.MODE_ALLOWED:
8453                 return ActivityManager.APP_START_MODE_NORMAL;
8454             case AppOpsManager.MODE_IGNORED:
8455                 return ActivityManager.APP_START_MODE_DELAYED;
8456             default:
8457                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8458         }
8459     }
8460
8461     // Service launch is available to apps with run-in-background exemptions but
8462     // some other background operations are not.  If we're doing a check
8463     // of service-launch policy, allow those callers to proceed unrestricted.
8464     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8465         // Persistent app?
8466         if (mPackageManagerInt.isPackagePersistent(packageName)) {
8467             if (DEBUG_BACKGROUND_CHECK) {
8468                 Slog.i(TAG, "App " + uid + "/" + packageName
8469                         + " is persistent; not restricted in background");
8470             }
8471             return ActivityManager.APP_START_MODE_NORMAL;
8472         }
8473
8474         // Non-persistent but background whitelisted?
8475         if (uidOnBackgroundWhitelist(uid)) {
8476             if (DEBUG_BACKGROUND_CHECK) {
8477                 Slog.i(TAG, "App " + uid + "/" + packageName
8478                         + " on background whitelist; not restricted in background");
8479             }
8480             return ActivityManager.APP_START_MODE_NORMAL;
8481         }
8482
8483         // Is this app on the battery whitelist?
8484         if (isOnDeviceIdleWhitelistLocked(uid)) {
8485             if (DEBUG_BACKGROUND_CHECK) {
8486                 Slog.i(TAG, "App " + uid + "/" + packageName
8487                         + " on idle whitelist; not restricted in background");
8488             }
8489             return ActivityManager.APP_START_MODE_NORMAL;
8490         }
8491
8492         // None of the service-policy criteria apply, so we apply the common criteria
8493         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8494     }
8495
8496     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8497             int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8498         UidRecord uidRec = mActiveUids.get(uid);
8499         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8500                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8501                 + (uidRec != null ? uidRec.idle : false));
8502         if (uidRec == null || alwaysRestrict || uidRec.idle) {
8503             boolean ephemeral;
8504             if (uidRec == null) {
8505                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8506                         UserHandle.getUserId(uid), packageName);
8507             } else {
8508                 ephemeral = uidRec.ephemeral;
8509             }
8510
8511             if (ephemeral) {
8512                 // We are hard-core about ephemeral apps not running in the background.
8513                 return ActivityManager.APP_START_MODE_DISABLED;
8514             } else {
8515                 if (disabledOnly) {
8516                     // The caller is only interested in whether app starts are completely
8517                     // disabled for the given package (that is, it is an instant app).  So
8518                     // we don't need to go further, which is all just seeing if we should
8519                     // apply a "delayed" mode for a regular app.
8520                     return ActivityManager.APP_START_MODE_NORMAL;
8521                 }
8522                 final int startMode = (alwaysRestrict)
8523                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8524                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
8525                                 packageTargetSdk);
8526                 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8527                         + " pkg=" + packageName + " startMode=" + startMode
8528                         + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8529                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8530                     // This is an old app that has been forced into a "compatible as possible"
8531                     // mode of background check.  To increase compatibility, we will allow other
8532                     // foreground apps to cause its services to start.
8533                     if (callingPid >= 0) {
8534                         ProcessRecord proc;
8535                         synchronized (mPidsSelfLocked) {
8536                             proc = mPidsSelfLocked.get(callingPid);
8537                         }
8538                         if (proc != null &&
8539                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8540                             // Whoever is instigating this is in the foreground, so we will allow it
8541                             // to go through.
8542                             return ActivityManager.APP_START_MODE_NORMAL;
8543                         }
8544                     }
8545                 }
8546                 return startMode;
8547             }
8548         }
8549         return ActivityManager.APP_START_MODE_NORMAL;
8550     }
8551
8552     boolean isOnDeviceIdleWhitelistLocked(int uid) {
8553         final int appId = UserHandle.getAppId(uid);
8554         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8555                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8556                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8557     }
8558
8559     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8560         ProviderInfo pi = null;
8561         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8562         if (cpr != null) {
8563             pi = cpr.info;
8564         } else {
8565             try {
8566                 pi = AppGlobals.getPackageManager().resolveContentProvider(
8567                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8568                         userHandle);
8569             } catch (RemoteException ex) {
8570             }
8571         }
8572         return pi;
8573     }
8574
8575     void grantEphemeralAccessLocked(int userId, Intent intent,
8576             int targetAppId, int ephemeralAppId) {
8577         getPackageManagerInternalLocked().
8578                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8579     }
8580
8581     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8582         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8583         if (targetUris != null) {
8584             return targetUris.get(grantUri);
8585         }
8586         return null;
8587     }
8588
8589     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8590             String targetPkg, int targetUid, GrantUri grantUri) {
8591         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8592         if (targetUris == null) {
8593             targetUris = Maps.newArrayMap();
8594             mGrantedUriPermissions.put(targetUid, targetUris);
8595         }
8596
8597         UriPermission perm = targetUris.get(grantUri);
8598         if (perm == null) {
8599             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8600             targetUris.put(grantUri, perm);
8601         }
8602
8603         return perm;
8604     }
8605
8606     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8607             final int modeFlags) {
8608         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8609         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8610                 : UriPermission.STRENGTH_OWNED;
8611
8612         // Root gets to do everything.
8613         if (uid == 0) {
8614             return true;
8615         }
8616
8617         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8618         if (perms == null) return false;
8619
8620         // First look for exact match
8621         final UriPermission exactPerm = perms.get(grantUri);
8622         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8623             return true;
8624         }
8625
8626         // No exact match, look for prefixes
8627         final int N = perms.size();
8628         for (int i = 0; i < N; i++) {
8629             final UriPermission perm = perms.valueAt(i);
8630             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8631                     && perm.getStrength(modeFlags) >= minStrength) {
8632                 return true;
8633             }
8634         }
8635
8636         return false;
8637     }
8638
8639     /**
8640      * @param uri This uri must NOT contain an embedded userId.
8641      * @param userId The userId in which the uri is to be resolved.
8642      */
8643     @Override
8644     public int checkUriPermission(Uri uri, int pid, int uid,
8645             final int modeFlags, int userId, IBinder callerToken) {
8646         enforceNotIsolatedCaller("checkUriPermission");
8647
8648         // Another redirected-binder-call permissions check as in
8649         // {@link checkPermissionWithToken}.
8650         Identity tlsIdentity = sCallerIdentity.get();
8651         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8652             uid = tlsIdentity.uid;
8653             pid = tlsIdentity.pid;
8654         }
8655
8656         // Our own process gets to do everything.
8657         if (pid == MY_PID) {
8658             return PackageManager.PERMISSION_GRANTED;
8659         }
8660         synchronized (this) {
8661             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8662                     ? PackageManager.PERMISSION_GRANTED
8663                     : PackageManager.PERMISSION_DENIED;
8664         }
8665     }
8666
8667     /**
8668      * Check if the targetPkg can be granted permission to access uri by
8669      * the callingUid using the given modeFlags.  Throws a security exception
8670      * if callingUid is not allowed to do this.  Returns the uid of the target
8671      * if the URI permission grant should be performed; returns -1 if it is not
8672      * needed (for example targetPkg already has permission to access the URI).
8673      * If you already know the uid of the target, you can supply it in
8674      * lastTargetUid else set that to -1.
8675      */
8676     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8677             final int modeFlags, int lastTargetUid) {
8678         if (!Intent.isAccessUriMode(modeFlags)) {
8679             return -1;
8680         }
8681
8682         if (targetPkg != null) {
8683             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8684                     "Checking grant " + targetPkg + " permission to " + grantUri);
8685         }
8686
8687         final IPackageManager pm = AppGlobals.getPackageManager();
8688
8689         // If this is not a content: uri, we can't do anything with it.
8690         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8691             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8692                     "Can't grant URI permission for non-content URI: " + grantUri);
8693             return -1;
8694         }
8695
8696         final String authority = grantUri.uri.getAuthority();
8697         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8698                 MATCH_DEBUG_TRIAGED_MISSING);
8699         if (pi == null) {
8700             Slog.w(TAG, "No content provider found for permission check: " +
8701                     grantUri.uri.toSafeString());
8702             return -1;
8703         }
8704
8705         int targetUid = lastTargetUid;
8706         if (targetUid < 0 && targetPkg != null) {
8707             try {
8708                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8709                         UserHandle.getUserId(callingUid));
8710                 if (targetUid < 0) {
8711                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8712                             "Can't grant URI permission no uid for: " + targetPkg);
8713                     return -1;
8714                 }
8715             } catch (RemoteException ex) {
8716                 return -1;
8717             }
8718         }
8719
8720         // If we're extending a persistable grant, then we always need to create
8721         // the grant data structure so that take/release APIs work
8722         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8723             return targetUid;
8724         }
8725
8726         if (targetUid >= 0) {
8727             // First...  does the target actually need this permission?
8728             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8729                 // No need to grant the target this permission.
8730                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8731                         "Target " + targetPkg + " already has full permission to " + grantUri);
8732                 return -1;
8733             }
8734         } else {
8735             // First...  there is no target package, so can anyone access it?
8736             boolean allowed = pi.exported;
8737             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8738                 if (pi.readPermission != null) {
8739                     allowed = false;
8740                 }
8741             }
8742             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8743                 if (pi.writePermission != null) {
8744                     allowed = false;
8745                 }
8746             }
8747             if (allowed) {
8748                 return -1;
8749             }
8750         }
8751
8752         /* There is a special cross user grant if:
8753          * - The target is on another user.
8754          * - Apps on the current user can access the uri without any uid permissions.
8755          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8756          * grant uri permissions.
8757          */
8758         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8759                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8760                 modeFlags, false /*without considering the uid permissions*/);
8761
8762         // Second...  is the provider allowing granting of URI permissions?
8763         if (!specialCrossUserGrant) {
8764             if (!pi.grantUriPermissions) {
8765                 throw new SecurityException("Provider " + pi.packageName
8766                         + "/" + pi.name
8767                         + " does not allow granting of Uri permissions (uri "
8768                         + grantUri + ")");
8769             }
8770             if (pi.uriPermissionPatterns != null) {
8771                 final int N = pi.uriPermissionPatterns.length;
8772                 boolean allowed = false;
8773                 for (int i=0; i<N; i++) {
8774                     if (pi.uriPermissionPatterns[i] != null
8775                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8776                         allowed = true;
8777                         break;
8778                     }
8779                 }
8780                 if (!allowed) {
8781                     throw new SecurityException("Provider " + pi.packageName
8782                             + "/" + pi.name
8783                             + " does not allow granting of permission to path of Uri "
8784                             + grantUri);
8785                 }
8786             }
8787         }
8788
8789         // Third...  does the caller itself have permission to access
8790         // this uri?
8791         final int callingAppId = UserHandle.getAppId(callingUid);
8792         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8793             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8794                 // Exempted authority for cropping user photos in Settings app
8795             } else {
8796                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8797                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8798                 return -1;
8799             }
8800         }
8801         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8802             // Require they hold a strong enough Uri permission
8803             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8804                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8805                     throw new SecurityException(
8806                             "UID " + callingUid + " does not have permission to " + grantUri
8807                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8808                                     + "or related APIs");
8809                 } else {
8810                     throw new SecurityException(
8811                             "UID " + callingUid + " does not have permission to " + grantUri);
8812                 }
8813             }
8814         }
8815         return targetUid;
8816     }
8817
8818     /**
8819      * @param uri This uri must NOT contain an embedded userId.
8820      * @param userId The userId in which the uri is to be resolved.
8821      */
8822     @Override
8823     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8824             final int modeFlags, int userId) {
8825         enforceNotIsolatedCaller("checkGrantUriPermission");
8826         synchronized(this) {
8827             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8828                     new GrantUri(userId, uri, false), modeFlags, -1);
8829         }
8830     }
8831
8832     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8833             final int modeFlags, UriPermissionOwner owner) {
8834         if (!Intent.isAccessUriMode(modeFlags)) {
8835             return;
8836         }
8837
8838         // So here we are: the caller has the assumed permission
8839         // to the uri, and the target doesn't.  Let's now give this to
8840         // the target.
8841
8842         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8843                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8844
8845         final String authority = grantUri.uri.getAuthority();
8846         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8847                 MATCH_DEBUG_TRIAGED_MISSING);
8848         if (pi == null) {
8849             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8850             return;
8851         }
8852
8853         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8854             grantUri.prefix = true;
8855         }
8856         final UriPermission perm = findOrCreateUriPermissionLocked(
8857                 pi.packageName, targetPkg, targetUid, grantUri);
8858         perm.grantModes(modeFlags, owner);
8859     }
8860
8861     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8862             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8863         if (targetPkg == null) {
8864             throw new NullPointerException("targetPkg");
8865         }
8866         int targetUid;
8867         final IPackageManager pm = AppGlobals.getPackageManager();
8868         try {
8869             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8870         } catch (RemoteException ex) {
8871             return;
8872         }
8873
8874         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8875                 targetUid);
8876         if (targetUid < 0) {
8877             return;
8878         }
8879
8880         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8881                 owner);
8882     }
8883
8884     static class NeededUriGrants extends ArrayList<GrantUri> {
8885         final String targetPkg;
8886         final int targetUid;
8887         final int flags;
8888
8889         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8890             this.targetPkg = targetPkg;
8891             this.targetUid = targetUid;
8892             this.flags = flags;
8893         }
8894     }
8895
8896     /**
8897      * Like checkGrantUriPermissionLocked, but takes an Intent.
8898      */
8899     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8900             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8901         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8902                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8903                 + " clip=" + (intent != null ? intent.getClipData() : null)
8904                 + " from " + intent + "; flags=0x"
8905                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8906
8907         if (targetPkg == null) {
8908             throw new NullPointerException("targetPkg");
8909         }
8910
8911         if (intent == null) {
8912             return null;
8913         }
8914         Uri data = intent.getData();
8915         ClipData clip = intent.getClipData();
8916         if (data == null && clip == null) {
8917             return null;
8918         }
8919         // Default userId for uris in the intent (if they don't specify it themselves)
8920         int contentUserHint = intent.getContentUserHint();
8921         if (contentUserHint == UserHandle.USER_CURRENT) {
8922             contentUserHint = UserHandle.getUserId(callingUid);
8923         }
8924         final IPackageManager pm = AppGlobals.getPackageManager();
8925         int targetUid;
8926         if (needed != null) {
8927             targetUid = needed.targetUid;
8928         } else {
8929             try {
8930                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8931                         targetUserId);
8932             } catch (RemoteException ex) {
8933                 return null;
8934             }
8935             if (targetUid < 0) {
8936                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8937                         "Can't grant URI permission no uid for: " + targetPkg
8938                         + " on user " + targetUserId);
8939                 return null;
8940             }
8941         }
8942         if (data != null) {
8943             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8944             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8945                     targetUid);
8946             if (targetUid > 0) {
8947                 if (needed == null) {
8948                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8949                 }
8950                 needed.add(grantUri);
8951             }
8952         }
8953         if (clip != null) {
8954             for (int i=0; i<clip.getItemCount(); i++) {
8955                 Uri uri = clip.getItemAt(i).getUri();
8956                 if (uri != null) {
8957                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8958                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8959                             targetUid);
8960                     if (targetUid > 0) {
8961                         if (needed == null) {
8962                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8963                         }
8964                         needed.add(grantUri);
8965                     }
8966                 } else {
8967                     Intent clipIntent = clip.getItemAt(i).getIntent();
8968                     if (clipIntent != null) {
8969                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8970                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8971                         if (newNeeded != null) {
8972                             needed = newNeeded;
8973                         }
8974                     }
8975                 }
8976             }
8977         }
8978
8979         return needed;
8980     }
8981
8982     /**
8983      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8984      */
8985     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8986             UriPermissionOwner owner) {
8987         if (needed != null) {
8988             for (int i=0; i<needed.size(); i++) {
8989                 GrantUri grantUri = needed.get(i);
8990                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8991                         grantUri, needed.flags, owner);
8992             }
8993         }
8994     }
8995
8996     void grantUriPermissionFromIntentLocked(int callingUid,
8997             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8998         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8999                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9000         if (needed == null) {
9001             return;
9002         }
9003
9004         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9005     }
9006
9007     /**
9008      * @param uri This uri must NOT contain an embedded userId.
9009      * @param userId The userId in which the uri is to be resolved.
9010      */
9011     @Override
9012     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9013             final int modeFlags, int userId) {
9014         enforceNotIsolatedCaller("grantUriPermission");
9015         GrantUri grantUri = new GrantUri(userId, uri, false);
9016         synchronized(this) {
9017             final ProcessRecord r = getRecordForAppLocked(caller);
9018             if (r == null) {
9019                 throw new SecurityException("Unable to find app for caller "
9020                         + caller
9021                         + " when granting permission to uri " + grantUri);
9022             }
9023             if (targetPkg == null) {
9024                 throw new IllegalArgumentException("null target");
9025             }
9026             if (grantUri == null) {
9027                 throw new IllegalArgumentException("null uri");
9028             }
9029
9030             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9031                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9032                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9033                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9034
9035             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9036                     UserHandle.getUserId(r.uid));
9037         }
9038     }
9039
9040     void removeUriPermissionIfNeededLocked(UriPermission perm) {
9041         if (perm.modeFlags == 0) {
9042             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9043                     perm.targetUid);
9044             if (perms != null) {
9045                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9046                         "Removing " + perm.targetUid + " permission to " + perm.uri);
9047
9048                 perms.remove(perm.uri);
9049                 if (perms.isEmpty()) {
9050                     mGrantedUriPermissions.remove(perm.targetUid);
9051                 }
9052             }
9053         }
9054     }
9055
9056     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9057             final int modeFlags) {
9058         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9059                 "Revoking all granted permissions to " + grantUri);
9060
9061         final IPackageManager pm = AppGlobals.getPackageManager();
9062         final String authority = grantUri.uri.getAuthority();
9063         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9064                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9065         if (pi == null) {
9066             Slog.w(TAG, "No content provider found for permission revoke: "
9067                     + grantUri.toSafeString());
9068             return;
9069         }
9070
9071         // Does the caller have this permission on the URI?
9072         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9073             // If they don't have direct access to the URI, then revoke any
9074             // ownerless URI permissions that have been granted to them.
9075             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9076             if (perms != null) {
9077                 boolean persistChanged = false;
9078                 for (int i = perms.size()-1; i >= 0; i--) {
9079                     final UriPermission perm = perms.valueAt(i);
9080                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9081                         continue;
9082                     }
9083                     if (perm.uri.sourceUserId == grantUri.sourceUserId
9084                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9085                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9086                                 "Revoking non-owned " + perm.targetUid
9087                                 + " permission to " + perm.uri);
9088                         persistChanged |= perm.revokeModes(
9089                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9090                         if (perm.modeFlags == 0) {
9091                             perms.removeAt(i);
9092                         }
9093                     }
9094                 }
9095                 if (perms.isEmpty()) {
9096                     mGrantedUriPermissions.remove(callingUid);
9097                 }
9098                 if (persistChanged) {
9099                     schedulePersistUriGrants();
9100                 }
9101             }
9102             return;
9103         }
9104
9105         boolean persistChanged = false;
9106
9107         // Go through all of the permissions and remove any that match.
9108         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9109             final int targetUid = mGrantedUriPermissions.keyAt(i);
9110             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9111
9112             for (int j = perms.size()-1; j >= 0; j--) {
9113                 final UriPermission perm = perms.valueAt(j);
9114                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9115                     continue;
9116                 }
9117                 if (perm.uri.sourceUserId == grantUri.sourceUserId
9118                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9119                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9120                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9121                     persistChanged |= perm.revokeModes(
9122                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9123                             targetPackage == null);
9124                     if (perm.modeFlags == 0) {
9125                         perms.removeAt(j);
9126                     }
9127                 }
9128             }
9129
9130             if (perms.isEmpty()) {
9131                 mGrantedUriPermissions.removeAt(i);
9132             }
9133         }
9134
9135         if (persistChanged) {
9136             schedulePersistUriGrants();
9137         }
9138     }
9139
9140     /**
9141      * @param uri This uri must NOT contain an embedded userId.
9142      * @param userId The userId in which the uri is to be resolved.
9143      */
9144     @Override
9145     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9146             final int modeFlags, int userId) {
9147         enforceNotIsolatedCaller("revokeUriPermission");
9148         synchronized(this) {
9149             final ProcessRecord r = getRecordForAppLocked(caller);
9150             if (r == null) {
9151                 throw new SecurityException("Unable to find app for caller "
9152                         + caller
9153                         + " when revoking permission to uri " + uri);
9154             }
9155             if (uri == null) {
9156                 Slog.w(TAG, "revokeUriPermission: null uri");
9157                 return;
9158             }
9159
9160             if (!Intent.isAccessUriMode(modeFlags)) {
9161                 return;
9162             }
9163
9164             final String authority = uri.getAuthority();
9165             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9166                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9167             if (pi == null) {
9168                 Slog.w(TAG, "No content provider found for permission revoke: "
9169                         + uri.toSafeString());
9170                 return;
9171             }
9172
9173             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9174                     modeFlags);
9175         }
9176     }
9177
9178     /**
9179      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9180      * given package.
9181      *
9182      * @param packageName Package name to match, or {@code null} to apply to all
9183      *            packages.
9184      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9185      *            to all users.
9186      * @param persistable If persistable grants should be removed.
9187      */
9188     private void removeUriPermissionsForPackageLocked(
9189             String packageName, int userHandle, boolean persistable) {
9190         if (userHandle == UserHandle.USER_ALL && packageName == null) {
9191             throw new IllegalArgumentException("Must narrow by either package or user");
9192         }
9193
9194         boolean persistChanged = false;
9195
9196         int N = mGrantedUriPermissions.size();
9197         for (int i = 0; i < N; i++) {
9198             final int targetUid = mGrantedUriPermissions.keyAt(i);
9199             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9200
9201             // Only inspect grants matching user
9202             if (userHandle == UserHandle.USER_ALL
9203                     || userHandle == UserHandle.getUserId(targetUid)) {
9204                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9205                     final UriPermission perm = it.next();
9206
9207                     // Only inspect grants matching package
9208                     if (packageName == null || perm.sourcePkg.equals(packageName)
9209                             || perm.targetPkg.equals(packageName)) {
9210                         // Hacky solution as part of fixing a security bug; ignore
9211                         // grants associated with DownloadManager so we don't have
9212                         // to immediately launch it to regrant the permissions
9213                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9214                                 && !persistable) continue;
9215
9216                         persistChanged |= perm.revokeModes(persistable
9217                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9218
9219                         // Only remove when no modes remain; any persisted grants
9220                         // will keep this alive.
9221                         if (perm.modeFlags == 0) {
9222                             it.remove();
9223                         }
9224                     }
9225                 }
9226
9227                 if (perms.isEmpty()) {
9228                     mGrantedUriPermissions.remove(targetUid);
9229                     N--;
9230                     i--;
9231                 }
9232             }
9233         }
9234
9235         if (persistChanged) {
9236             schedulePersistUriGrants();
9237         }
9238     }
9239
9240     @Override
9241     public IBinder newUriPermissionOwner(String name) {
9242         enforceNotIsolatedCaller("newUriPermissionOwner");
9243         synchronized(this) {
9244             UriPermissionOwner owner = new UriPermissionOwner(this, name);
9245             return owner.getExternalTokenLocked();
9246         }
9247     }
9248
9249     @Override
9250     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9251         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9252         synchronized(this) {
9253             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9254             if (r == null) {
9255                 throw new IllegalArgumentException("Activity does not exist; token="
9256                         + activityToken);
9257             }
9258             return r.getUriPermissionsLocked().getExternalTokenLocked();
9259         }
9260     }
9261     /**
9262      * @param uri This uri must NOT contain an embedded userId.
9263      * @param sourceUserId The userId in which the uri is to be resolved.
9264      * @param targetUserId The userId of the app that receives the grant.
9265      */
9266     @Override
9267     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9268             final int modeFlags, int sourceUserId, int targetUserId) {
9269         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9270                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9271                 "grantUriPermissionFromOwner", null);
9272         synchronized(this) {
9273             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9274             if (owner == null) {
9275                 throw new IllegalArgumentException("Unknown owner: " + token);
9276             }
9277             if (fromUid != Binder.getCallingUid()) {
9278                 if (Binder.getCallingUid() != myUid()) {
9279                     // Only system code can grant URI permissions on behalf
9280                     // of other users.
9281                     throw new SecurityException("nice try");
9282                 }
9283             }
9284             if (targetPkg == null) {
9285                 throw new IllegalArgumentException("null target");
9286             }
9287             if (uri == null) {
9288                 throw new IllegalArgumentException("null uri");
9289             }
9290
9291             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9292                     modeFlags, owner, targetUserId);
9293         }
9294     }
9295
9296     /**
9297      * @param uri This uri must NOT contain an embedded userId.
9298      * @param userId The userId in which the uri is to be resolved.
9299      */
9300     @Override
9301     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9302         synchronized(this) {
9303             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9304             if (owner == null) {
9305                 throw new IllegalArgumentException("Unknown owner: " + token);
9306             }
9307
9308             if (uri == null) {
9309                 owner.removeUriPermissionsLocked(mode);
9310             } else {
9311                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9312                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9313             }
9314         }
9315     }
9316
9317     private void schedulePersistUriGrants() {
9318         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9319             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9320                     10 * DateUtils.SECOND_IN_MILLIS);
9321         }
9322     }
9323
9324     private void writeGrantedUriPermissions() {
9325         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9326
9327         // Snapshot permissions so we can persist without lock
9328         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9329         synchronized (this) {
9330             final int size = mGrantedUriPermissions.size();
9331             for (int i = 0; i < size; i++) {
9332                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9333                 for (UriPermission perm : perms.values()) {
9334                     if (perm.persistedModeFlags != 0) {
9335                         persist.add(perm.snapshot());
9336                     }
9337                 }
9338             }
9339         }
9340
9341         FileOutputStream fos = null;
9342         try {
9343             fos = mGrantFile.startWrite();
9344
9345             XmlSerializer out = new FastXmlSerializer();
9346             out.setOutput(fos, StandardCharsets.UTF_8.name());
9347             out.startDocument(null, true);
9348             out.startTag(null, TAG_URI_GRANTS);
9349             for (UriPermission.Snapshot perm : persist) {
9350                 out.startTag(null, TAG_URI_GRANT);
9351                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9352                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9353                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9354                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9355                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9356                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9357                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9358                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9359                 out.endTag(null, TAG_URI_GRANT);
9360             }
9361             out.endTag(null, TAG_URI_GRANTS);
9362             out.endDocument();
9363
9364             mGrantFile.finishWrite(fos);
9365         } catch (IOException e) {
9366             if (fos != null) {
9367                 mGrantFile.failWrite(fos);
9368             }
9369         }
9370     }
9371
9372     private void readGrantedUriPermissionsLocked() {
9373         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9374
9375         final long now = System.currentTimeMillis();
9376
9377         FileInputStream fis = null;
9378         try {
9379             fis = mGrantFile.openRead();
9380             final XmlPullParser in = Xml.newPullParser();
9381             in.setInput(fis, StandardCharsets.UTF_8.name());
9382
9383             int type;
9384             while ((type = in.next()) != END_DOCUMENT) {
9385                 final String tag = in.getName();
9386                 if (type == START_TAG) {
9387                     if (TAG_URI_GRANT.equals(tag)) {
9388                         final int sourceUserId;
9389                         final int targetUserId;
9390                         final int userHandle = readIntAttribute(in,
9391                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9392                         if (userHandle != UserHandle.USER_NULL) {
9393                             // For backwards compatibility.
9394                             sourceUserId = userHandle;
9395                             targetUserId = userHandle;
9396                         } else {
9397                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9398                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9399                         }
9400                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9401                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9402                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9403                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9404                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9405                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9406
9407                         // Sanity check that provider still belongs to source package
9408                         // Both direct boot aware and unaware packages are fine as we
9409                         // will do filtering at query time to avoid multiple parsing.
9410                         final ProviderInfo pi = getProviderInfoLocked(
9411                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9412                                         | MATCH_DIRECT_BOOT_UNAWARE);
9413                         if (pi != null && sourcePkg.equals(pi.packageName)) {
9414                             int targetUid = -1;
9415                             try {
9416                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
9417                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9418                             } catch (RemoteException e) {
9419                             }
9420                             if (targetUid != -1) {
9421                                 final UriPermission perm = findOrCreateUriPermissionLocked(
9422                                         sourcePkg, targetPkg, targetUid,
9423                                         new GrantUri(sourceUserId, uri, prefix));
9424                                 perm.initPersistedModes(modeFlags, createdTime);
9425                             }
9426                         } else {
9427                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9428                                     + " but instead found " + pi);
9429                         }
9430                     }
9431                 }
9432             }
9433         } catch (FileNotFoundException e) {
9434             // Missing grants is okay
9435         } catch (IOException e) {
9436             Slog.wtf(TAG, "Failed reading Uri grants", e);
9437         } catch (XmlPullParserException e) {
9438             Slog.wtf(TAG, "Failed reading Uri grants", e);
9439         } finally {
9440             IoUtils.closeQuietly(fis);
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 takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9450         enforceNotIsolatedCaller("takePersistableUriPermission");
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             GrantUri grantUri = new GrantUri(userId, uri, false);
9459
9460             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9461                     new GrantUri(userId, uri, false));
9462             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9463                     new GrantUri(userId, uri, true));
9464
9465             final boolean exactValid = (exactPerm != null)
9466                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9467             final boolean prefixValid = (prefixPerm != null)
9468                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9469
9470             if (!(exactValid || prefixValid)) {
9471                 throw new SecurityException("No persistable permission grants found for UID "
9472                         + callingUid + " and Uri " + grantUri.toSafeString());
9473             }
9474
9475             if (exactValid) {
9476                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9477             }
9478             if (prefixValid) {
9479                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9480             }
9481
9482             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9483
9484             if (persistChanged) {
9485                 schedulePersistUriGrants();
9486             }
9487         }
9488     }
9489
9490     /**
9491      * @param uri This uri must NOT contain an embedded userId.
9492      * @param userId The userId in which the uri is to be resolved.
9493      */
9494     @Override
9495     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9496         enforceNotIsolatedCaller("releasePersistableUriPermission");
9497
9498         Preconditions.checkFlagsArgument(modeFlags,
9499                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9500
9501         synchronized (this) {
9502             final int callingUid = Binder.getCallingUid();
9503             boolean persistChanged = false;
9504
9505             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9506                     new GrantUri(userId, uri, false));
9507             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9508                     new GrantUri(userId, uri, true));
9509             if (exactPerm == null && prefixPerm == null) {
9510                 throw new SecurityException("No permission grants found for UID " + callingUid
9511                         + " and Uri " + uri.toSafeString());
9512             }
9513
9514             if (exactPerm != null) {
9515                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9516                 removeUriPermissionIfNeededLocked(exactPerm);
9517             }
9518             if (prefixPerm != null) {
9519                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9520                 removeUriPermissionIfNeededLocked(prefixPerm);
9521             }
9522
9523             if (persistChanged) {
9524                 schedulePersistUriGrants();
9525             }
9526         }
9527     }
9528
9529     /**
9530      * Prune any older {@link UriPermission} for the given UID until outstanding
9531      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9532      *
9533      * @return if any mutations occured that require persisting.
9534      */
9535     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9536         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9537         if (perms == null) return false;
9538         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9539
9540         final ArrayList<UriPermission> persisted = Lists.newArrayList();
9541         for (UriPermission perm : perms.values()) {
9542             if (perm.persistedModeFlags != 0) {
9543                 persisted.add(perm);
9544             }
9545         }
9546
9547         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9548         if (trimCount <= 0) return false;
9549
9550         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9551         for (int i = 0; i < trimCount; i++) {
9552             final UriPermission perm = persisted.get(i);
9553
9554             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9555                     "Trimming grant created at " + perm.persistedCreateTime);
9556
9557             perm.releasePersistableModes(~0);
9558             removeUriPermissionIfNeededLocked(perm);
9559         }
9560
9561         return true;
9562     }
9563
9564     @Override
9565     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9566             String packageName, boolean incoming) {
9567         enforceNotIsolatedCaller("getPersistedUriPermissions");
9568         Preconditions.checkNotNull(packageName, "packageName");
9569
9570         final int callingUid = Binder.getCallingUid();
9571         final int callingUserId = UserHandle.getUserId(callingUid);
9572         final IPackageManager pm = AppGlobals.getPackageManager();
9573         try {
9574             final int packageUid = pm.getPackageUid(packageName,
9575                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9576             if (packageUid != callingUid) {
9577                 throw new SecurityException(
9578                         "Package " + packageName + " does not belong to calling UID " + callingUid);
9579             }
9580         } catch (RemoteException e) {
9581             throw new SecurityException("Failed to verify package name ownership");
9582         }
9583
9584         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9585         synchronized (this) {
9586             if (incoming) {
9587                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9588                         callingUid);
9589                 if (perms == null) {
9590                     Slog.w(TAG, "No permission grants found for " + packageName);
9591                 } else {
9592                     for (UriPermission perm : perms.values()) {
9593                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9594                             result.add(perm.buildPersistedPublicApiObject());
9595                         }
9596                     }
9597                 }
9598             } else {
9599                 final int size = mGrantedUriPermissions.size();
9600                 for (int i = 0; i < size; i++) {
9601                     final ArrayMap<GrantUri, UriPermission> perms =
9602                             mGrantedUriPermissions.valueAt(i);
9603                     for (UriPermission perm : perms.values()) {
9604                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9605                             result.add(perm.buildPersistedPublicApiObject());
9606                         }
9607                     }
9608                 }
9609             }
9610         }
9611         return new ParceledListSlice<android.content.UriPermission>(result);
9612     }
9613
9614     @Override
9615     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9616             String packageName, int userId) {
9617         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9618                 "getGrantedUriPermissions");
9619
9620         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9621         synchronized (this) {
9622             final int size = mGrantedUriPermissions.size();
9623             for (int i = 0; i < size; i++) {
9624                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9625                 for (UriPermission perm : perms.values()) {
9626                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9627                             && perm.persistedModeFlags != 0) {
9628                         result.add(perm.buildPersistedPublicApiObject());
9629                     }
9630                 }
9631             }
9632         }
9633         return new ParceledListSlice<android.content.UriPermission>(result);
9634     }
9635
9636     @Override
9637     public void clearGrantedUriPermissions(String packageName, int userId) {
9638         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9639                 "clearGrantedUriPermissions");
9640         removeUriPermissionsForPackageLocked(packageName, userId, true);
9641     }
9642
9643     @Override
9644     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9645         synchronized (this) {
9646             ProcessRecord app =
9647                 who != null ? getRecordForAppLocked(who) : null;
9648             if (app == null) return;
9649
9650             Message msg = Message.obtain();
9651             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9652             msg.obj = app;
9653             msg.arg1 = waiting ? 1 : 0;
9654             mUiHandler.sendMessage(msg);
9655         }
9656     }
9657
9658     @Override
9659     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9660         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9661         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9662         outInfo.availMem = getFreeMemory();
9663         outInfo.totalMem = getTotalMemory();
9664         outInfo.threshold = homeAppMem;
9665         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9666         outInfo.hiddenAppThreshold = cachedAppMem;
9667         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9668                 ProcessList.SERVICE_ADJ);
9669         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9670                 ProcessList.VISIBLE_APP_ADJ);
9671         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9672                 ProcessList.FOREGROUND_APP_ADJ);
9673     }
9674
9675     // =========================================================
9676     // TASK MANAGEMENT
9677     // =========================================================
9678
9679     @Override
9680     public List<IBinder> getAppTasks(String callingPackage) {
9681         int callingUid = Binder.getCallingUid();
9682         long ident = Binder.clearCallingIdentity();
9683
9684         synchronized(this) {
9685             ArrayList<IBinder> list = new ArrayList<IBinder>();
9686             try {
9687                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9688
9689                 final int N = mRecentTasks.size();
9690                 for (int i = 0; i < N; i++) {
9691                     TaskRecord tr = mRecentTasks.get(i);
9692                     // Skip tasks that do not match the caller.  We don't need to verify
9693                     // callingPackage, because we are also limiting to callingUid and know
9694                     // that will limit to the correct security sandbox.
9695                     if (tr.effectiveUid != callingUid) {
9696                         continue;
9697                     }
9698                     Intent intent = tr.getBaseIntent();
9699                     if (intent == null ||
9700                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9701                         continue;
9702                     }
9703                     ActivityManager.RecentTaskInfo taskInfo =
9704                             createRecentTaskInfoFromTaskRecord(tr);
9705                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9706                     list.add(taskImpl.asBinder());
9707                 }
9708             } finally {
9709                 Binder.restoreCallingIdentity(ident);
9710             }
9711             return list;
9712         }
9713     }
9714
9715     @Override
9716     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9717         final int callingUid = Binder.getCallingUid();
9718         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9719
9720         synchronized(this) {
9721             if (DEBUG_ALL) Slog.v(
9722                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9723
9724             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9725                     callingUid);
9726
9727             // TODO: Improve with MRU list from all ActivityStacks.
9728             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9729         }
9730
9731         return list;
9732     }
9733
9734     /**
9735      * Creates a new RecentTaskInfo from a TaskRecord.
9736      */
9737     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9738         // Update the task description to reflect any changes in the task stack
9739         tr.updateTaskDescription();
9740
9741         // Compose the recent task info
9742         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9743         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9744         rti.persistentId = tr.taskId;
9745         rti.baseIntent = new Intent(tr.getBaseIntent());
9746         rti.origActivity = tr.origActivity;
9747         rti.realActivity = tr.realActivity;
9748         rti.description = tr.lastDescription;
9749         rti.stackId = tr.getStackId();
9750         rti.userId = tr.userId;
9751         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9752         rti.firstActiveTime = tr.firstActiveTime;
9753         rti.lastActiveTime = tr.lastActiveTime;
9754         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9755         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9756         rti.numActivities = 0;
9757         if (tr.mBounds != null) {
9758             rti.bounds = new Rect(tr.mBounds);
9759         }
9760         rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9761         rti.resizeMode = tr.mResizeMode;
9762
9763         ActivityRecord base = null;
9764         ActivityRecord top = null;
9765         ActivityRecord tmp;
9766
9767         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9768             tmp = tr.mActivities.get(i);
9769             if (tmp.finishing) {
9770                 continue;
9771             }
9772             base = tmp;
9773             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9774                 top = base;
9775             }
9776             rti.numActivities++;
9777         }
9778
9779         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9780         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9781
9782         return rti;
9783     }
9784
9785     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9786         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9787                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9788         if (!allowed) {
9789             if (checkPermission(android.Manifest.permission.GET_TASKS,
9790                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9791                 // Temporary compatibility: some existing apps on the system image may
9792                 // still be requesting the old permission and not switched to the new
9793                 // one; if so, we'll still allow them full access.  This means we need
9794                 // to see if they are holding the old permission and are a system app.
9795                 try {
9796                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9797                         allowed = true;
9798                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9799                                 + " is using old GET_TASKS but privileged; allowing");
9800                     }
9801                 } catch (RemoteException e) {
9802                 }
9803             }
9804         }
9805         if (!allowed) {
9806             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9807                     + " does not hold REAL_GET_TASKS; limiting output");
9808         }
9809         return allowed;
9810     }
9811
9812     @Override
9813     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9814             int userId) {
9815         final int callingUid = Binder.getCallingUid();
9816         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9817                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9818
9819         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9820         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9821         synchronized (this) {
9822             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9823                     callingUid);
9824             final boolean detailed = checkCallingPermission(
9825                     android.Manifest.permission.GET_DETAILED_TASKS)
9826                     == PackageManager.PERMISSION_GRANTED;
9827
9828             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9829                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9830                 return ParceledListSlice.emptyList();
9831             }
9832             mRecentTasks.loadUserRecentsLocked(userId);
9833
9834             final int recentsCount = mRecentTasks.size();
9835             ArrayList<ActivityManager.RecentTaskInfo> res =
9836                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9837
9838             final Set<Integer> includedUsers;
9839             if (includeProfiles) {
9840                 includedUsers = mUserController.getProfileIds(userId);
9841             } else {
9842                 includedUsers = new HashSet<>();
9843             }
9844             includedUsers.add(Integer.valueOf(userId));
9845
9846             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9847                 TaskRecord tr = mRecentTasks.get(i);
9848                 // Only add calling user or related users recent tasks
9849                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9850                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9851                     continue;
9852                 }
9853
9854                 if (tr.realActivitySuspended) {
9855                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9856                     continue;
9857                 }
9858
9859                 // Return the entry if desired by the caller.  We always return
9860                 // the first entry, because callers always expect this to be the
9861                 // foreground app.  We may filter others if the caller has
9862                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9863                 // we should exclude the entry.
9864
9865                 if (i == 0
9866                         || withExcluded
9867                         || (tr.intent == null)
9868                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9869                                 == 0)) {
9870                     if (!allowed) {
9871                         // If the caller doesn't have the GET_TASKS permission, then only
9872                         // allow them to see a small subset of tasks -- their own and home.
9873                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9874                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9875                             continue;
9876                         }
9877                     }
9878                     final ActivityStack stack = tr.getStack();
9879                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9880                         if (stack != null && stack.isHomeOrRecentsStack()) {
9881                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9882                                     "Skipping, home or recents stack task: " + tr);
9883                             continue;
9884                         }
9885                     }
9886                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9887                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9888                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9889                                     "Skipping, top task in docked stack: " + tr);
9890                             continue;
9891                         }
9892                     }
9893                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9894                         if (stack != null && stack.isPinnedStack()) {
9895                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9896                                     "Skipping, pinned stack task: " + tr);
9897                             continue;
9898                         }
9899                     }
9900                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9901                         // Don't include auto remove tasks that are finished or finishing.
9902                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9903                                 "Skipping, auto-remove without activity: " + tr);
9904                         continue;
9905                     }
9906                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9907                             && !tr.isAvailable) {
9908                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9909                                 "Skipping, unavail real act: " + tr);
9910                         continue;
9911                     }
9912
9913                     if (!tr.mUserSetupComplete) {
9914                         // Don't include task launched while user is not done setting-up.
9915                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9916                                 "Skipping, user setup not complete: " + tr);
9917                         continue;
9918                     }
9919
9920                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9921                     if (!detailed) {
9922                         rti.baseIntent.replaceExtras((Bundle)null);
9923                     }
9924
9925                     res.add(rti);
9926                     maxNum--;
9927                 }
9928             }
9929             return new ParceledListSlice<>(res);
9930         }
9931     }
9932
9933     @Override
9934     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9935         synchronized (this) {
9936             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9937                     "getTaskThumbnail()");
9938             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9939                     id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9940             if (tr != null) {
9941                 return tr.getTaskThumbnailLocked();
9942             }
9943         }
9944         return null;
9945     }
9946
9947     @Override
9948     public ActivityManager.TaskDescription getTaskDescription(int id) {
9949         synchronized (this) {
9950             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9951                     "getTaskDescription()");
9952             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9953                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9954             if (tr != null) {
9955                 return tr.lastTaskDescription;
9956             }
9957         }
9958         return null;
9959     }
9960
9961     @Override
9962     public int addAppTask(IBinder activityToken, Intent intent,
9963             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9964         final int callingUid = Binder.getCallingUid();
9965         final long callingIdent = Binder.clearCallingIdentity();
9966
9967         try {
9968             synchronized (this) {
9969                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9970                 if (r == null) {
9971                     throw new IllegalArgumentException("Activity does not exist; token="
9972                             + activityToken);
9973                 }
9974                 ComponentName comp = intent.getComponent();
9975                 if (comp == null) {
9976                     throw new IllegalArgumentException("Intent " + intent
9977                             + " must specify explicit component");
9978                 }
9979                 if (thumbnail.getWidth() != mThumbnailWidth
9980                         || thumbnail.getHeight() != mThumbnailHeight) {
9981                     throw new IllegalArgumentException("Bad thumbnail size: got "
9982                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9983                             + mThumbnailWidth + "x" + mThumbnailHeight);
9984                 }
9985                 if (intent.getSelector() != null) {
9986                     intent.setSelector(null);
9987                 }
9988                 if (intent.getSourceBounds() != null) {
9989                     intent.setSourceBounds(null);
9990                 }
9991                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9992                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9993                         // The caller has added this as an auto-remove task...  that makes no
9994                         // sense, so turn off auto-remove.
9995                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9996                     }
9997                 }
9998                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9999                     mLastAddedTaskActivity = null;
10000                 }
10001                 ActivityInfo ainfo = mLastAddedTaskActivity;
10002                 if (ainfo == null) {
10003                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10004                             comp, 0, UserHandle.getUserId(callingUid));
10005                     if (ainfo.applicationInfo.uid != callingUid) {
10006                         throw new SecurityException(
10007                                 "Can't add task for another application: target uid="
10008                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10009                     }
10010                 }
10011
10012                 TaskRecord task = new TaskRecord(this,
10013                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10014                         ainfo, intent, description, new TaskThumbnailInfo());
10015
10016                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10017                 if (trimIdx >= 0) {
10018                     // If this would have caused a trim, then we'll abort because that
10019                     // means it would be added at the end of the list but then just removed.
10020                     return INVALID_TASK_ID;
10021                 }
10022
10023                 final int N = mRecentTasks.size();
10024                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10025                     final TaskRecord tr = mRecentTasks.remove(N - 1);
10026                     tr.removedFromRecents();
10027                 }
10028
10029                 task.inRecents = true;
10030                 mRecentTasks.add(task);
10031                 r.getStack().addTask(task, false, "addAppTask");
10032
10033                 task.setLastThumbnailLocked(thumbnail);
10034                 task.freeLastThumbnail();
10035                 return task.taskId;
10036             }
10037         } finally {
10038             Binder.restoreCallingIdentity(callingIdent);
10039         }
10040     }
10041
10042     @Override
10043     public Point getAppTaskThumbnailSize() {
10044         synchronized (this) {
10045             return new Point(mThumbnailWidth,  mThumbnailHeight);
10046         }
10047     }
10048
10049     @Override
10050     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10051         synchronized (this) {
10052             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10053             if (r != null) {
10054                 r.setTaskDescription(td);
10055                 final TaskRecord task = r.getTask();
10056                 task.updateTaskDescription();
10057                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10058             }
10059         }
10060     }
10061
10062     @Override
10063     public void setTaskResizeable(int taskId, int resizeableMode) {
10064         synchronized (this) {
10065             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10066                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10067             if (task == null) {
10068                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10069                 return;
10070             }
10071             task.setResizeMode(resizeableMode);
10072         }
10073     }
10074
10075     @Override
10076     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10077         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10078         long ident = Binder.clearCallingIdentity();
10079         try {
10080             synchronized (this) {
10081                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10082                 if (task == null) {
10083                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10084                     return;
10085                 }
10086                 // Place the task in the right stack if it isn't there already based on
10087                 // the requested bounds.
10088                 // The stack transition logic is:
10089                 // - a null bounds on a freeform task moves that task to fullscreen
10090                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10091                 //   that task to freeform
10092                 // - otherwise the task is not moved
10093                 int stackId = task.getStackId();
10094                 if (!StackId.isTaskResizeAllowed(stackId)) {
10095                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10096                 }
10097                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10098                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10099                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10100                     stackId = FREEFORM_WORKSPACE_STACK_ID;
10101                 }
10102
10103                 // Reparent the task to the right stack if necessary
10104                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10105                 if (stackId != task.getStackId()) {
10106                     // Defer resume until the task is resized below
10107                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10108                             DEFER_RESUME, "resizeTask");
10109                     preserveWindow = false;
10110                 }
10111
10112                 // After reparenting (which only resizes the task to the stack bounds), resize the
10113                 // task to the actual bounds provided
10114                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10115             }
10116         } finally {
10117             Binder.restoreCallingIdentity(ident);
10118         }
10119     }
10120
10121     @Override
10122     public Rect getTaskBounds(int taskId) {
10123         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10124         long ident = Binder.clearCallingIdentity();
10125         Rect rect = new Rect();
10126         try {
10127             synchronized (this) {
10128                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10129                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10130                 if (task == null) {
10131                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10132                     return rect;
10133                 }
10134                 if (task.getStack() != null) {
10135                     // Return the bounds from window manager since it will be adjusted for various
10136                     // things like the presense of a docked stack for tasks that aren't resizeable.
10137                     task.getWindowContainerBounds(rect);
10138                 } else {
10139                     // Task isn't in window manager yet since it isn't associated with a stack.
10140                     // Return the persist value from activity manager
10141                     if (task.mBounds != null) {
10142                         rect.set(task.mBounds);
10143                     } else if (task.mLastNonFullscreenBounds != null) {
10144                         rect.set(task.mLastNonFullscreenBounds);
10145                     }
10146                 }
10147             }
10148         } finally {
10149             Binder.restoreCallingIdentity(ident);
10150         }
10151         return rect;
10152     }
10153
10154     @Override
10155     public void cancelTaskWindowTransition(int taskId) {
10156         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10157         final long ident = Binder.clearCallingIdentity();
10158         try {
10159             synchronized (this) {
10160                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10161                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10162                 if (task == null) {
10163                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10164                     return;
10165                 }
10166                 task.cancelWindowTransition();
10167             }
10168         } finally {
10169             Binder.restoreCallingIdentity(ident);
10170         }
10171     }
10172
10173     @Override
10174     public void cancelTaskThumbnailTransition(int taskId) {
10175         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10176         final long ident = Binder.clearCallingIdentity();
10177         try {
10178             synchronized (this) {
10179                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10180                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10181                 if (task == null) {
10182                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10183                     return;
10184                 }
10185                 task.cancelThumbnailTransition();
10186             }
10187         } finally {
10188             Binder.restoreCallingIdentity(ident);
10189         }
10190     }
10191
10192     @Override
10193     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10194         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10195         final long ident = Binder.clearCallingIdentity();
10196         try {
10197             final TaskRecord task;
10198             synchronized (this) {
10199                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10200                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10201                 if (task == null) {
10202                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10203                     return null;
10204                 }
10205             }
10206             // Don't call this while holding the lock as this operation might hit the disk.
10207             return task.getSnapshot(reducedResolution);
10208         } finally {
10209             Binder.restoreCallingIdentity(ident);
10210         }
10211     }
10212
10213     @Override
10214     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10215         if (userId != UserHandle.getCallingUserId()) {
10216             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10217                     "getTaskDescriptionIcon");
10218         }
10219         final File passedIconFile = new File(filePath);
10220         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10221                 passedIconFile.getName());
10222         if (!legitIconFile.getPath().equals(filePath)
10223                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10224             throw new IllegalArgumentException("Bad file path: " + filePath
10225                     + " passed for userId " + userId);
10226         }
10227         return mRecentTasks.getTaskDescriptionIcon(filePath);
10228     }
10229
10230     @Override
10231     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10232             throws RemoteException {
10233         final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10234         if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10235                 activityOptions.getCustomInPlaceResId() == 0) {
10236             throw new IllegalArgumentException("Expected in-place ActivityOption " +
10237                     "with valid animation");
10238         }
10239         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10240         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10241                 activityOptions.getCustomInPlaceResId());
10242         mWindowManager.executeAppTransition();
10243     }
10244
10245     private void removeTasksByPackageNameLocked(String packageName, int userId) {
10246         // Remove all tasks with activities in the specified package from the list of recent tasks
10247         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10248             TaskRecord tr = mRecentTasks.get(i);
10249             if (tr.userId != userId) continue;
10250
10251             ComponentName cn = tr.intent.getComponent();
10252             if (cn != null && cn.getPackageName().equals(packageName)) {
10253                 // If the package name matches, remove the task.
10254                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10255             }
10256         }
10257     }
10258
10259     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10260             int userId) {
10261
10262         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10263             TaskRecord tr = mRecentTasks.get(i);
10264             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10265                 continue;
10266             }
10267
10268             ComponentName cn = tr.intent.getComponent();
10269             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10270                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10271             if (sameComponent) {
10272                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10273             }
10274         }
10275     }
10276
10277     @Override
10278     public void removeStack(int stackId) {
10279         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10280         if (StackId.isHomeOrRecentsStack(stackId)) {
10281             throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10282         }
10283
10284         synchronized (this) {
10285             final long ident = Binder.clearCallingIdentity();
10286             try {
10287                 mStackSupervisor.removeStackLocked(stackId);
10288             } finally {
10289                 Binder.restoreCallingIdentity(ident);
10290             }
10291         }
10292     }
10293
10294     @Override
10295     public void moveStackToDisplay(int stackId, int displayId) {
10296         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
10297
10298         synchronized (this) {
10299             final long ident = Binder.clearCallingIdentity();
10300             try {
10301                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10302                         + " to displayId=" + displayId);
10303                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10304             } finally {
10305                 Binder.restoreCallingIdentity(ident);
10306             }
10307         }
10308     }
10309
10310     @Override
10311     public boolean removeTask(int taskId) {
10312         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10313         synchronized (this) {
10314             final long ident = Binder.clearCallingIdentity();
10315             try {
10316                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10317             } finally {
10318                 Binder.restoreCallingIdentity(ident);
10319             }
10320         }
10321     }
10322
10323     /**
10324      * TODO: Add mController hook
10325      */
10326     @Override
10327     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10328         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10329
10330         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10331         synchronized(this) {
10332             moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10333         }
10334     }
10335
10336     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10337         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10338
10339         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10340                 Binder.getCallingUid(), -1, -1, "Task to front")) {
10341             ActivityOptions.abort(options);
10342             return;
10343         }
10344         final long origId = Binder.clearCallingIdentity();
10345         try {
10346             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10347             if (task == null) {
10348                 Slog.d(TAG, "Could not find task for id: "+ taskId);
10349                 return;
10350             }
10351             if (mStackSupervisor.isLockTaskModeViolation(task)) {
10352                 mStackSupervisor.showLockTaskToast();
10353                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10354                 return;
10355             }
10356             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10357             if (prev != null) {
10358                 task.setTaskToReturnTo(prev);
10359             }
10360             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10361                     false /* forceNonResizable */);
10362
10363             final ActivityRecord topActivity = task.getTopActivity();
10364             if (topActivity != null) {
10365
10366                 // We are reshowing a task, use a starting window to hide the initial draw delay
10367                 // so the transition can start earlier.
10368                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10369                         true /* taskSwitch */, fromRecents);
10370             }
10371         } finally {
10372             Binder.restoreCallingIdentity(origId);
10373         }
10374         ActivityOptions.abort(options);
10375     }
10376
10377     /**
10378      * Attempts to move a task backwards in z-order (the order of activities within the task is
10379      * unchanged).
10380      *
10381      * There are several possible results of this call:
10382      * - if the task is locked, then we will show the lock toast
10383      * - if there is a task behind the provided task, then that task is made visible and resumed as
10384      *   this task is moved to the back
10385      * - otherwise, if there are no other tasks in the stack:
10386      *     - if this task is in the pinned stack, then we remove the stack completely, which will
10387      *       have the effect of moving the task to the top or bottom of the fullscreen stack
10388      *       (depending on whether it is visible)
10389      *     - otherwise, we simply return home and hide this task
10390      *
10391      * @param token A reference to the activity we wish to move
10392      * @param nonRoot If false then this only works if the activity is the root
10393      *                of a task; if true it will work for any activity in a task.
10394      * @return Returns true if the move completed, false if not.
10395      */
10396     @Override
10397     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10398         enforceNotIsolatedCaller("moveActivityTaskToBack");
10399         synchronized(this) {
10400             final long origId = Binder.clearCallingIdentity();
10401             try {
10402                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10403                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10404                 if (task != null) {
10405                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10406                 }
10407             } finally {
10408                 Binder.restoreCallingIdentity(origId);
10409             }
10410         }
10411         return false;
10412     }
10413
10414     @Override
10415     public void moveTaskBackwards(int task) {
10416         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10417                 "moveTaskBackwards()");
10418
10419         synchronized(this) {
10420             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10421                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
10422                 return;
10423             }
10424             final long origId = Binder.clearCallingIdentity();
10425             moveTaskBackwardsLocked(task);
10426             Binder.restoreCallingIdentity(origId);
10427         }
10428     }
10429
10430     private final void moveTaskBackwardsLocked(int task) {
10431         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10432     }
10433
10434     @Override
10435     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10436             IActivityContainerCallback callback) throws RemoteException {
10437         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10438         synchronized (this) {
10439             if (parentActivityToken == null) {
10440                 throw new IllegalArgumentException("parent token must not be null");
10441             }
10442             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10443             if (r == null) {
10444                 return null;
10445             }
10446             if (callback == null) {
10447                 throw new IllegalArgumentException("callback must not be null");
10448             }
10449             return mStackSupervisor.createVirtualActivityContainer(r, callback);
10450         }
10451     }
10452
10453     @Override
10454     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10455         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10456         synchronized (this) {
10457             final int stackId = mStackSupervisor.getNextStackId();
10458             final ActivityStack stack =
10459                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10460             if (stack == null) {
10461                 return null;
10462             }
10463             return stack.mActivityContainer;
10464         }
10465     }
10466
10467     @Override
10468     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10469         synchronized (this) {
10470             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10471             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10472                 return stack.mActivityContainer.getDisplayId();
10473             }
10474             return DEFAULT_DISPLAY;
10475         }
10476     }
10477
10478     @Override
10479     public int getActivityStackId(IBinder token) throws RemoteException {
10480         synchronized (this) {
10481             ActivityStack stack = ActivityRecord.getStackLocked(token);
10482             if (stack == null) {
10483                 return INVALID_STACK_ID;
10484             }
10485             return stack.mStackId;
10486         }
10487     }
10488
10489     @Override
10490     public void exitFreeformMode(IBinder token) throws RemoteException {
10491         synchronized (this) {
10492             long ident = Binder.clearCallingIdentity();
10493             try {
10494                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10495                 if (r == null) {
10496                     throw new IllegalArgumentException(
10497                             "exitFreeformMode: No activity record matching token=" + token);
10498                 }
10499
10500                 final ActivityStack stack = r.getStack();
10501                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10502                     throw new IllegalStateException(
10503                             "exitFreeformMode: You can only go fullscreen from freeform.");
10504                 }
10505
10506                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10507                 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10508                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10509             } finally {
10510                 Binder.restoreCallingIdentity(ident);
10511             }
10512         }
10513     }
10514
10515     @Override
10516     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10517         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10518         if (StackId.isHomeOrRecentsStack(stackId)) {
10519             throw new IllegalArgumentException(
10520                     "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10521         }
10522         synchronized (this) {
10523             long ident = Binder.clearCallingIdentity();
10524             try {
10525                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10526                 if (task == null) {
10527                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10528                     return;
10529                 }
10530
10531                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10532                         + " to stackId=" + stackId + " toTop=" + toTop);
10533                 if (stackId == DOCKED_STACK_ID) {
10534                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10535                             null /* initialBounds */);
10536                 }
10537                 task.reparent(stackId, toTop,
10538                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10539             } finally {
10540                 Binder.restoreCallingIdentity(ident);
10541             }
10542         }
10543     }
10544
10545     @Override
10546     public void swapDockedAndFullscreenStack() throws RemoteException {
10547         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10548         synchronized (this) {
10549             long ident = Binder.clearCallingIdentity();
10550             try {
10551                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10552                         FULLSCREEN_WORKSPACE_STACK_ID);
10553                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10554                         : null;
10555                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10556                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10557                         : null;
10558                 if (topTask == null || tasks == null || tasks.size() == 0) {
10559                     Slog.w(TAG,
10560                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
10561                     return;
10562                 }
10563
10564                 // TODO: App transition
10565                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10566
10567                 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10568                 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10569                         DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10570                 final int size = tasks.size();
10571                 for (int i = 0; i < size; i++) {
10572                     final int id = tasks.get(i).taskId;
10573                     if (id == topTask.taskId) {
10574                         continue;
10575                     }
10576
10577                     // Defer the resume until after all the tasks have been moved
10578                     tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10579                             REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10580                             "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10581                 }
10582
10583                 // Because we deferred the resume to avoid conflicts with stack switches while
10584                 // resuming, we need to do it after all the tasks are moved.
10585                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10586                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10587
10588                 mWindowManager.executeAppTransition();
10589             } finally {
10590                 Binder.restoreCallingIdentity(ident);
10591             }
10592         }
10593     }
10594
10595     /**
10596      * Moves the input task to the docked stack.
10597      *
10598      * @param taskId Id of task to move.
10599      * @param createMode The mode the docked stack should be created in if it doesn't exist
10600      *                   already. See
10601      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10602      *                   and
10603      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10604      * @param toTop If the task and stack should be moved to the top.
10605      * @param animate Whether we should play an animation for the moving the task
10606      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10607      *                      docked stack. Pass {@code null} to use default bounds.
10608      */
10609     @Override
10610     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10611             Rect initialBounds) {
10612         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10613         synchronized (this) {
10614             long ident = Binder.clearCallingIdentity();
10615             try {
10616                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10617                 if (task == null) {
10618                     Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10619                     return false;
10620                 }
10621
10622                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10623                         + " to createMode=" + createMode + " toTop=" + toTop);
10624                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10625
10626                 // Defer resuming until we move the home stack to the front below
10627                 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10628                         REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10629                         "moveTaskToDockedStack");
10630                 if (moved) {
10631                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10632                 }
10633                 return moved;
10634             } finally {
10635                 Binder.restoreCallingIdentity(ident);
10636             }
10637         }
10638     }
10639
10640     /**
10641      * Moves the top activity in the input stackId to the pinned stack.
10642      *
10643      * @param stackId Id of stack to move the top activity to pinned stack.
10644      * @param bounds Bounds to use for pinned stack.
10645      *
10646      * @return True if the top activity of the input stack was successfully moved to the pinned
10647      *          stack.
10648      */
10649     @Override
10650     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10651         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10652         synchronized (this) {
10653             if (!mSupportsPictureInPicture) {
10654                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10655                         + "Device doesn't support picture-in-picture mode");
10656             }
10657
10658             long ident = Binder.clearCallingIdentity();
10659             try {
10660                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10661             } finally {
10662                 Binder.restoreCallingIdentity(ident);
10663             }
10664         }
10665     }
10666
10667     @Override
10668     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10669             boolean preserveWindows, boolean animate, int animationDuration) {
10670         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10671         long ident = Binder.clearCallingIdentity();
10672         try {
10673             synchronized (this) {
10674                 if (animate) {
10675                     if (stackId == PINNED_STACK_ID) {
10676                         final PinnedActivityStack pinnedStack =
10677                                 mStackSupervisor.getStack(PINNED_STACK_ID);
10678                         if (pinnedStack != null) {
10679                             pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10680                                     destBounds, animationDuration, false /* fromFullscreen */);
10681                         }
10682                     } else {
10683                         throw new IllegalArgumentException("Stack: " + stackId
10684                                 + " doesn't support animated resize.");
10685                     }
10686                 } else {
10687                     mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10688                             null /* tempTaskInsetBounds */, preserveWindows,
10689                             allowResizeInDockedMode, !DEFER_RESUME);
10690                 }
10691             }
10692         } finally {
10693             Binder.restoreCallingIdentity(ident);
10694         }
10695     }
10696
10697     @Override
10698     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10699             Rect tempDockedTaskInsetBounds,
10700             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10701         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10702                 "resizeDockedStack()");
10703         long ident = Binder.clearCallingIdentity();
10704         try {
10705             synchronized (this) {
10706                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10707                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10708                         PRESERVE_WINDOWS);
10709             }
10710         } finally {
10711             Binder.restoreCallingIdentity(ident);
10712         }
10713     }
10714
10715     @Override
10716     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10717         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10718                 "resizePinnedStack()");
10719         final long ident = Binder.clearCallingIdentity();
10720         try {
10721             synchronized (this) {
10722                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10723             }
10724         } finally {
10725             Binder.restoreCallingIdentity(ident);
10726         }
10727     }
10728
10729     /**
10730      * Try to place task to provided position. The final position might be different depending on
10731      * current user and stacks state. The task will be moved to target stack if it's currently in
10732      * different stack.
10733      */
10734     @Override
10735     public void positionTaskInStack(int taskId, int stackId, int position) {
10736         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10737         if (StackId.isHomeOrRecentsStack(stackId)) {
10738             throw new IllegalArgumentException(
10739                     "positionTaskInStack: Attempt to change the position of task "
10740                     + taskId + " in/to home/recents stack");
10741         }
10742         synchronized (this) {
10743             long ident = Binder.clearCallingIdentity();
10744             try {
10745                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10746                         + taskId + " in stackId=" + stackId + " at position=" + position);
10747                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10748                 if (task == null) {
10749                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
10750                             + taskId);
10751                 }
10752
10753                 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10754                         !ON_TOP);
10755
10756                 // TODO: Have the callers of this API call a separate reparent method if that is
10757                 // what they intended to do vs. having this method also do reparenting.
10758                 if (task.getStack() == stack) {
10759                     // Change position in current stack.
10760                     stack.positionChildAt(task, position);
10761                 } else {
10762                     // Reparent to new stack.
10763                     task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10764                             !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10765                 }
10766             } finally {
10767                 Binder.restoreCallingIdentity(ident);
10768             }
10769         }
10770     }
10771
10772     @Override
10773     public List<StackInfo> getAllStackInfos() {
10774         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10775         long ident = Binder.clearCallingIdentity();
10776         try {
10777             synchronized (this) {
10778                 return mStackSupervisor.getAllStackInfosLocked();
10779             }
10780         } finally {
10781             Binder.restoreCallingIdentity(ident);
10782         }
10783     }
10784
10785     @Override
10786     public StackInfo getStackInfo(int stackId) {
10787         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10788         long ident = Binder.clearCallingIdentity();
10789         try {
10790             synchronized (this) {
10791                 return mStackSupervisor.getStackInfoLocked(stackId);
10792             }
10793         } finally {
10794             Binder.restoreCallingIdentity(ident);
10795         }
10796     }
10797
10798     @Override
10799     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10800         synchronized(this) {
10801             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10802         }
10803     }
10804
10805     @Override
10806     public void updateDeviceOwner(String packageName) {
10807         final int callingUid = Binder.getCallingUid();
10808         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10809             throw new SecurityException("updateDeviceOwner called from non-system process");
10810         }
10811         synchronized (this) {
10812             mDeviceOwnerName = packageName;
10813         }
10814     }
10815
10816     @Override
10817     public void updateLockTaskPackages(int userId, String[] packages) {
10818         final int callingUid = Binder.getCallingUid();
10819         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10820             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10821                     "updateLockTaskPackages()");
10822         }
10823         synchronized (this) {
10824             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10825                     Arrays.toString(packages));
10826             mLockTaskPackages.put(userId, packages);
10827             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10828         }
10829     }
10830
10831
10832     void startLockTaskModeLocked(TaskRecord task) {
10833         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10834         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10835             return;
10836         }
10837
10838         // When a task is locked, dismiss the pinned stack if it exists
10839         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10840                 PINNED_STACK_ID);
10841         if (pinnedStack != null) {
10842             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10843         }
10844
10845         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10846         // is initiated by system after the pinning request was shown and locked mode is initiated
10847         // by an authorized app directly
10848         final int callingUid = Binder.getCallingUid();
10849         boolean isSystemInitiated = callingUid == SYSTEM_UID;
10850         long ident = Binder.clearCallingIdentity();
10851         try {
10852             if (!isSystemInitiated) {
10853                 task.mLockTaskUid = callingUid;
10854                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10855                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10856                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10857                     StatusBarManagerInternal statusBarManager =
10858                             LocalServices.getService(StatusBarManagerInternal.class);
10859                     if (statusBarManager != null) {
10860                         statusBarManager.showScreenPinningRequest(task.taskId);
10861                     }
10862                     return;
10863                 }
10864
10865                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10866                 if (stack == null || task != stack.topTask()) {
10867                     throw new IllegalArgumentException("Invalid task, not in foreground");
10868                 }
10869             }
10870             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10871                     "Locking fully");
10872             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10873                     ActivityManager.LOCK_TASK_MODE_PINNED :
10874                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10875                     "startLockTask", true);
10876         } finally {
10877             Binder.restoreCallingIdentity(ident);
10878         }
10879     }
10880
10881     @Override
10882     public void startLockTaskModeById(int taskId) {
10883         synchronized (this) {
10884             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10885             if (task != null) {
10886                 startLockTaskModeLocked(task);
10887             }
10888         }
10889     }
10890
10891     @Override
10892     public void startLockTaskModeByToken(IBinder token) {
10893         synchronized (this) {
10894             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10895             if (r == null) {
10896                 return;
10897             }
10898             final TaskRecord task = r.getTask();
10899             if (task != null) {
10900                 startLockTaskModeLocked(task);
10901             }
10902         }
10903     }
10904
10905     @Override
10906     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10907         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10908         // This makes inner call to look as if it was initiated by system.
10909         long ident = Binder.clearCallingIdentity();
10910         try {
10911             synchronized (this) {
10912                 startLockTaskModeById(taskId);
10913             }
10914         } finally {
10915             Binder.restoreCallingIdentity(ident);
10916         }
10917     }
10918
10919     @Override
10920     public void stopLockTaskMode() {
10921         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10922         if (lockTask == null) {
10923             // Our work here is done.
10924             return;
10925         }
10926
10927         final int callingUid = Binder.getCallingUid();
10928         final int lockTaskUid = lockTask.mLockTaskUid;
10929         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10930         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10931             // Done.
10932             return;
10933         } else {
10934             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10935             // It is possible lockTaskMode was started by the system process because
10936             // android:lockTaskMode is set to a locking value in the application manifest
10937             // instead of the app calling startLockTaskMode. In this case
10938             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10939             // {@link TaskRecord.effectiveUid} instead. Also caller with
10940             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10941             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10942                     && callingUid != lockTaskUid
10943                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10944                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10945                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10946             }
10947         }
10948         long ident = Binder.clearCallingIdentity();
10949         try {
10950             Log.d(TAG, "stopLockTaskMode");
10951             // Stop lock task
10952             synchronized (this) {
10953                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10954                         "stopLockTask", true);
10955             }
10956             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10957             if (tm != null) {
10958                 tm.showInCallScreen(false);
10959             }
10960         } finally {
10961             Binder.restoreCallingIdentity(ident);
10962         }
10963     }
10964
10965     /**
10966      * This API should be called by SystemUI only when user perform certain action to dismiss
10967      * lock task mode. We should only dismiss pinned lock task mode in this case.
10968      */
10969     @Override
10970     public void stopSystemLockTaskMode() throws RemoteException {
10971         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10972             stopLockTaskMode();
10973         } else {
10974             mStackSupervisor.showLockTaskToast();
10975         }
10976     }
10977
10978     @Override
10979     public boolean isInLockTaskMode() {
10980         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10981     }
10982
10983     @Override
10984     public int getLockTaskModeState() {
10985         synchronized (this) {
10986             return mStackSupervisor.getLockTaskModeState();
10987         }
10988     }
10989
10990     @Override
10991     public void showLockTaskEscapeMessage(IBinder token) {
10992         synchronized (this) {
10993             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10994             if (r == null) {
10995                 return;
10996             }
10997             mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
10998         }
10999     }
11000
11001     @Override
11002     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11003             throws RemoteException {
11004         synchronized (this) {
11005             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11006             if (r == null) {
11007                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11008                         + token);
11009                 return;
11010             }
11011             final long origId = Binder.clearCallingIdentity();
11012             try {
11013                 r.setDisablePreviewScreenshots(disable);
11014             } finally {
11015                 Binder.restoreCallingIdentity(origId);
11016             }
11017         }
11018     }
11019
11020     // =========================================================
11021     // CONTENT PROVIDERS
11022     // =========================================================
11023
11024     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11025         List<ProviderInfo> providers = null;
11026         try {
11027             providers = AppGlobals.getPackageManager()
11028                     .queryContentProviders(app.processName, app.uid,
11029                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11030                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11031                     .getList();
11032         } catch (RemoteException ex) {
11033         }
11034         if (DEBUG_MU) Slog.v(TAG_MU,
11035                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11036         int userId = app.userId;
11037         if (providers != null) {
11038             int N = providers.size();
11039             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11040             for (int i=0; i<N; i++) {
11041                 // TODO: keep logic in sync with installEncryptionUnawareProviders
11042                 ProviderInfo cpi =
11043                     (ProviderInfo)providers.get(i);
11044                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11045                         cpi.name, cpi.flags);
11046                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11047                     // This is a singleton provider, but a user besides the
11048                     // default user is asking to initialize a process it runs
11049                     // in...  well, no, it doesn't actually run in this process,
11050                     // it runs in the process of the default user.  Get rid of it.
11051                     providers.remove(i);
11052                     N--;
11053                     i--;
11054                     continue;
11055                 }
11056
11057                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11058                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11059                 if (cpr == null) {
11060                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11061                     mProviderMap.putProviderByClass(comp, cpr);
11062                 }
11063                 if (DEBUG_MU) Slog.v(TAG_MU,
11064                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11065                 app.pubProviders.put(cpi.name, cpr);
11066                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11067                     // Don't add this if it is a platform component that is marked
11068                     // to run in multiple processes, because this is actually
11069                     // part of the framework so doesn't make sense to track as a
11070                     // separate apk in the process.
11071                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11072                             mProcessStats);
11073                 }
11074                 notifyPackageUse(cpi.applicationInfo.packageName,
11075                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11076             }
11077         }
11078         return providers;
11079     }
11080
11081     /**
11082      * Check if the calling UID has a possible chance at accessing the provider
11083      * at the given authority and user.
11084      */
11085     public String checkContentProviderAccess(String authority, int userId) {
11086         if (userId == UserHandle.USER_ALL) {
11087             mContext.enforceCallingOrSelfPermission(
11088                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11089             userId = UserHandle.getCallingUserId();
11090         }
11091
11092         ProviderInfo cpi = null;
11093         try {
11094             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11095                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11096                             | PackageManager.MATCH_DISABLED_COMPONENTS
11097                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
11098                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11099                     userId);
11100         } catch (RemoteException ignored) {
11101         }
11102         if (cpi == null) {
11103             return "Failed to find provider " + authority + " for user " + userId
11104                     + "; expected to find a valid ContentProvider for this authority";
11105         }
11106
11107         ProcessRecord r = null;
11108         synchronized (mPidsSelfLocked) {
11109             r = mPidsSelfLocked.get(Binder.getCallingPid());
11110         }
11111         if (r == null) {
11112             return "Failed to find PID " + Binder.getCallingPid();
11113         }
11114
11115         synchronized (this) {
11116             return checkContentProviderPermissionLocked(cpi, r, userId, true);
11117         }
11118     }
11119
11120     /**
11121      * Check if {@link ProcessRecord} has a possible chance at accessing the
11122      * given {@link ProviderInfo}. Final permission checking is always done
11123      * in {@link ContentProvider}.
11124      */
11125     private final String checkContentProviderPermissionLocked(
11126             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11127         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11128         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11129         boolean checkedGrants = false;
11130         if (checkUser) {
11131             // Looking for cross-user grants before enforcing the typical cross-users permissions
11132             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11133             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11134                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11135                     return null;
11136                 }
11137                 checkedGrants = true;
11138             }
11139             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11140                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11141             if (userId != tmpTargetUserId) {
11142                 // When we actually went to determine the final targer user ID, this ended
11143                 // up different than our initial check for the authority.  This is because
11144                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11145                 // SELF.  So we need to re-check the grants again.
11146                 checkedGrants = false;
11147             }
11148         }
11149         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11150                 cpi.applicationInfo.uid, cpi.exported)
11151                 == PackageManager.PERMISSION_GRANTED) {
11152             return null;
11153         }
11154         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11155                 cpi.applicationInfo.uid, cpi.exported)
11156                 == PackageManager.PERMISSION_GRANTED) {
11157             return null;
11158         }
11159
11160         PathPermission[] pps = cpi.pathPermissions;
11161         if (pps != null) {
11162             int i = pps.length;
11163             while (i > 0) {
11164                 i--;
11165                 PathPermission pp = pps[i];
11166                 String pprperm = pp.getReadPermission();
11167                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11168                         cpi.applicationInfo.uid, cpi.exported)
11169                         == PackageManager.PERMISSION_GRANTED) {
11170                     return null;
11171                 }
11172                 String ppwperm = pp.getWritePermission();
11173                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11174                         cpi.applicationInfo.uid, cpi.exported)
11175                         == PackageManager.PERMISSION_GRANTED) {
11176                     return null;
11177                 }
11178             }
11179         }
11180         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11181             return null;
11182         }
11183
11184         final String suffix;
11185         if (!cpi.exported) {
11186             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11187         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11188             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11189         } else {
11190             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11191         }
11192         final String msg = "Permission Denial: opening provider " + cpi.name
11193                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11194                 + ", uid=" + callingUid + ")" + suffix;
11195         Slog.w(TAG, msg);
11196         return msg;
11197     }
11198
11199     /**
11200      * Returns if the ContentProvider has granted a uri to callingUid
11201      */
11202     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11203         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11204         if (perms != null) {
11205             for (int i=perms.size()-1; i>=0; i--) {
11206                 GrantUri grantUri = perms.keyAt(i);
11207                 if (grantUri.sourceUserId == userId || !checkUser) {
11208                     if (matchesProvider(grantUri.uri, cpi)) {
11209                         return true;
11210                     }
11211                 }
11212             }
11213         }
11214         return false;
11215     }
11216
11217     /**
11218      * Returns true if the uri authority is one of the authorities specified in the provider.
11219      */
11220     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11221         String uriAuth = uri.getAuthority();
11222         String cpiAuth = cpi.authority;
11223         if (cpiAuth.indexOf(';') == -1) {
11224             return cpiAuth.equals(uriAuth);
11225         }
11226         String[] cpiAuths = cpiAuth.split(";");
11227         int length = cpiAuths.length;
11228         for (int i = 0; i < length; i++) {
11229             if (cpiAuths[i].equals(uriAuth)) return true;
11230         }
11231         return false;
11232     }
11233
11234     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11235             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11236         if (r != null) {
11237             for (int i=0; i<r.conProviders.size(); i++) {
11238                 ContentProviderConnection conn = r.conProviders.get(i);
11239                 if (conn.provider == cpr) {
11240                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11241                             "Adding provider requested by "
11242                             + r.processName + " from process "
11243                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11244                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11245                     if (stable) {
11246                         conn.stableCount++;
11247                         conn.numStableIncs++;
11248                     } else {
11249                         conn.unstableCount++;
11250                         conn.numUnstableIncs++;
11251                     }
11252                     return conn;
11253                 }
11254             }
11255             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11256             if (stable) {
11257                 conn.stableCount = 1;
11258                 conn.numStableIncs = 1;
11259             } else {
11260                 conn.unstableCount = 1;
11261                 conn.numUnstableIncs = 1;
11262             }
11263             cpr.connections.add(conn);
11264             r.conProviders.add(conn);
11265             startAssociationLocked(r.uid, r.processName, r.curProcState,
11266                     cpr.uid, cpr.name, cpr.info.processName);
11267             return conn;
11268         }
11269         cpr.addExternalProcessHandleLocked(externalProcessToken);
11270         return null;
11271     }
11272
11273     boolean decProviderCountLocked(ContentProviderConnection conn,
11274             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11275         if (conn != null) {
11276             cpr = conn.provider;
11277             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11278                     "Removing provider requested by "
11279                     + conn.client.processName + " from process "
11280                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11281                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11282             if (stable) {
11283                 conn.stableCount--;
11284             } else {
11285                 conn.unstableCount--;
11286             }
11287             if (conn.stableCount == 0 && conn.unstableCount == 0) {
11288                 cpr.connections.remove(conn);
11289                 conn.client.conProviders.remove(conn);
11290                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11291                     // The client is more important than last activity -- note the time this
11292                     // is happening, so we keep the old provider process around a bit as last
11293                     // activity to avoid thrashing it.
11294                     if (cpr.proc != null) {
11295                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11296                     }
11297                 }
11298                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11299                 return true;
11300             }
11301             return false;
11302         }
11303         cpr.removeExternalProcessHandleLocked(externalProcessToken);
11304         return false;
11305     }
11306
11307     private void checkTime(long startTime, String where) {
11308         long now = SystemClock.uptimeMillis();
11309         if ((now-startTime) > 50) {
11310             // If we are taking more than 50ms, log about it.
11311             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11312         }
11313     }
11314
11315     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11316             PROC_SPACE_TERM,
11317             PROC_SPACE_TERM|PROC_PARENS,
11318             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11319     };
11320
11321     private final long[] mProcessStateStatsLongs = new long[1];
11322
11323     boolean isProcessAliveLocked(ProcessRecord proc) {
11324         if (proc.procStatFile == null) {
11325             proc.procStatFile = "/proc/" + proc.pid + "/stat";
11326         }
11327         mProcessStateStatsLongs[0] = 0;
11328         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11329                 mProcessStateStatsLongs, null)) {
11330             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11331             return false;
11332         }
11333         final long state = mProcessStateStatsLongs[0];
11334         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11335                 + (char)state);
11336         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11337     }
11338
11339     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11340             String name, IBinder token, boolean stable, int userId) {
11341         ContentProviderRecord cpr;
11342         ContentProviderConnection conn = null;
11343         ProviderInfo cpi = null;
11344
11345         synchronized(this) {
11346             long startTime = SystemClock.uptimeMillis();
11347
11348             ProcessRecord r = null;
11349             if (caller != null) {
11350                 r = getRecordForAppLocked(caller);
11351                 if (r == null) {
11352                     throw new SecurityException(
11353                             "Unable to find app for caller " + caller
11354                           + " (pid=" + Binder.getCallingPid()
11355                           + ") when getting content provider " + name);
11356                 }
11357             }
11358
11359             boolean checkCrossUser = true;
11360
11361             checkTime(startTime, "getContentProviderImpl: getProviderByName");
11362
11363             // First check if this content provider has been published...
11364             cpr = mProviderMap.getProviderByName(name, userId);
11365             // If that didn't work, check if it exists for user 0 and then
11366             // verify that it's a singleton provider before using it.
11367             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11368                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11369                 if (cpr != null) {
11370                     cpi = cpr.info;
11371                     if (isSingleton(cpi.processName, cpi.applicationInfo,
11372                             cpi.name, cpi.flags)
11373                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11374                         userId = UserHandle.USER_SYSTEM;
11375                         checkCrossUser = false;
11376                     } else {
11377                         cpr = null;
11378                         cpi = null;
11379                     }
11380                 }
11381             }
11382
11383             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11384             if (providerRunning) {
11385                 cpi = cpr.info;
11386                 String msg;
11387                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11388                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11389                         != null) {
11390                     throw new SecurityException(msg);
11391                 }
11392                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11393
11394                 if (r != null && cpr.canRunHere(r)) {
11395                     // This provider has been published or is in the process
11396                     // of being published...  but it is also allowed to run
11397                     // in the caller's process, so don't make a connection
11398                     // and just let the caller instantiate its own instance.
11399                     ContentProviderHolder holder = cpr.newHolder(null);
11400                     // don't give caller the provider object, it needs
11401                     // to make its own.
11402                     holder.provider = null;
11403                     return holder;
11404                 }
11405                 // Don't expose providers between normal apps and instant apps
11406                 try {
11407                     if (AppGlobals.getPackageManager()
11408                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11409                         return null;
11410                     }
11411                 } catch (RemoteException e) {
11412                 }
11413
11414                 final long origId = Binder.clearCallingIdentity();
11415
11416                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11417
11418                 // In this case the provider instance already exists, so we can
11419                 // return it right away.
11420                 conn = incProviderCountLocked(r, cpr, token, stable);
11421                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11422                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11423                         // If this is a perceptible app accessing the provider,
11424                         // make sure to count it as being accessed and thus
11425                         // back up on the LRU list.  This is good because
11426                         // content providers are often expensive to start.
11427                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11428                         updateLruProcessLocked(cpr.proc, false, null);
11429                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11430                     }
11431                 }
11432
11433                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11434                 final int verifiedAdj = cpr.proc.verifiedAdj;
11435                 boolean success = updateOomAdjLocked(cpr.proc, true);
11436                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11437                 // if the process has been successfully adjusted.  So to reduce races with
11438                 // it, we will check whether the process still exists.  Note that this doesn't
11439                 // completely get rid of races with LMK killing the process, but should make
11440                 // them much smaller.
11441                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11442                     success = false;
11443                 }
11444                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11445                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11446                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11447                 // NOTE: there is still a race here where a signal could be
11448                 // pending on the process even though we managed to update its
11449                 // adj level.  Not sure what to do about this, but at least
11450                 // the race is now smaller.
11451                 if (!success) {
11452                     // Uh oh...  it looks like the provider's process
11453                     // has been killed on us.  We need to wait for a new
11454                     // process to be started, and make sure its death
11455                     // doesn't kill our process.
11456                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11457                             + " is crashing; detaching " + r);
11458                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11459                     checkTime(startTime, "getContentProviderImpl: before appDied");
11460                     appDiedLocked(cpr.proc);
11461                     checkTime(startTime, "getContentProviderImpl: after appDied");
11462                     if (!lastRef) {
11463                         // This wasn't the last ref our process had on
11464                         // the provider...  we have now been killed, bail.
11465                         return null;
11466                     }
11467                     providerRunning = false;
11468                     conn = null;
11469                 } else {
11470                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
11471                 }
11472
11473                 Binder.restoreCallingIdentity(origId);
11474             }
11475
11476             if (!providerRunning) {
11477                 try {
11478                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11479                     cpi = AppGlobals.getPackageManager().
11480                         resolveContentProvider(name,
11481                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11482                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11483                 } catch (RemoteException ex) {
11484                 }
11485                 if (cpi == null) {
11486                     return null;
11487                 }
11488                 // If the provider is a singleton AND
11489                 // (it's a call within the same user || the provider is a
11490                 // privileged app)
11491                 // Then allow connecting to the singleton provider
11492                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11493                         cpi.name, cpi.flags)
11494                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11495                 if (singleton) {
11496                     userId = UserHandle.USER_SYSTEM;
11497                 }
11498                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11499                 checkTime(startTime, "getContentProviderImpl: got app info for user");
11500
11501                 String msg;
11502                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11503                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11504                         != null) {
11505                     throw new SecurityException(msg);
11506                 }
11507                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11508
11509                 if (!mProcessesReady
11510                         && !cpi.processName.equals("system")) {
11511                     // If this content provider does not run in the system
11512                     // process, and the system is not yet ready to run other
11513                     // processes, then fail fast instead of hanging.
11514                     throw new IllegalArgumentException(
11515                             "Attempt to launch content provider before system ready");
11516                 }
11517
11518                 // Make sure that the user who owns this provider is running.  If not,
11519                 // we don't want to allow it to run.
11520                 if (!mUserController.isUserRunningLocked(userId, 0)) {
11521                     Slog.w(TAG, "Unable to launch app "
11522                             + cpi.applicationInfo.packageName + "/"
11523                             + cpi.applicationInfo.uid + " for provider "
11524                             + name + ": user " + userId + " is stopped");
11525                     return null;
11526                 }
11527
11528                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11529                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11530                 cpr = mProviderMap.getProviderByClass(comp, userId);
11531                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11532                 final boolean firstClass = cpr == null;
11533                 if (firstClass) {
11534                     final long ident = Binder.clearCallingIdentity();
11535
11536                     // If permissions need a review before any of the app components can run,
11537                     // we return no provider and launch a review activity if the calling app
11538                     // is in the foreground.
11539                     if (mPermissionReviewRequired) {
11540                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11541                             return null;
11542                         }
11543                     }
11544
11545                     try {
11546                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11547                         ApplicationInfo ai =
11548                             AppGlobals.getPackageManager().
11549                                 getApplicationInfo(
11550                                         cpi.applicationInfo.packageName,
11551                                         STOCK_PM_FLAGS, userId);
11552                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11553                         if (ai == null) {
11554                             Slog.w(TAG, "No package info for content provider "
11555                                     + cpi.name);
11556                             return null;
11557                         }
11558                         ai = getAppInfoForUser(ai, userId);
11559                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11560                     } catch (RemoteException ex) {
11561                         // pm is in same process, this will never happen.
11562                     } finally {
11563                         Binder.restoreCallingIdentity(ident);
11564                     }
11565                 }
11566
11567                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11568
11569                 if (r != null && cpr.canRunHere(r)) {
11570                     // If this is a multiprocess provider, then just return its
11571                     // info and allow the caller to instantiate it.  Only do
11572                     // this if the provider is the same user as the caller's
11573                     // process, or can run as root (so can be in any process).
11574                     return cpr.newHolder(null);
11575                 }
11576
11577                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11578                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11579                             + cpr.info.name + " callers=" + Debug.getCallers(6));
11580
11581                 // This is single process, and our app is now connecting to it.
11582                 // See if we are already in the process of launching this
11583                 // provider.
11584                 final int N = mLaunchingProviders.size();
11585                 int i;
11586                 for (i = 0; i < N; i++) {
11587                     if (mLaunchingProviders.get(i) == cpr) {
11588                         break;
11589                     }
11590                 }
11591
11592                 // If the provider is not already being launched, then get it
11593                 // started.
11594                 if (i >= N) {
11595                     final long origId = Binder.clearCallingIdentity();
11596
11597                     try {
11598                         // Content provider is now in use, its package can't be stopped.
11599                         try {
11600                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
11601                             AppGlobals.getPackageManager().setPackageStoppedState(
11602                                     cpr.appInfo.packageName, false, userId);
11603                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
11604                         } catch (RemoteException e) {
11605                         } catch (IllegalArgumentException e) {
11606                             Slog.w(TAG, "Failed trying to unstop package "
11607                                     + cpr.appInfo.packageName + ": " + e);
11608                         }
11609
11610                         // Use existing process if already started
11611                         checkTime(startTime, "getContentProviderImpl: looking for process record");
11612                         ProcessRecord proc = getProcessRecordLocked(
11613                                 cpi.processName, cpr.appInfo.uid, false);
11614                         if (proc != null && proc.thread != null && !proc.killed) {
11615                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11616                                     "Installing in existing process " + proc);
11617                             if (!proc.pubProviders.containsKey(cpi.name)) {
11618                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
11619                                 proc.pubProviders.put(cpi.name, cpr);
11620                                 try {
11621                                     proc.thread.scheduleInstallProvider(cpi);
11622                                 } catch (RemoteException e) {
11623                                 }
11624                             }
11625                         } else {
11626                             checkTime(startTime, "getContentProviderImpl: before start process");
11627                             proc = startProcessLocked(cpi.processName,
11628                                     cpr.appInfo, false, 0, "content provider",
11629                                     new ComponentName(cpi.applicationInfo.packageName,
11630                                             cpi.name), false, false, false);
11631                             checkTime(startTime, "getContentProviderImpl: after start process");
11632                             if (proc == null) {
11633                                 Slog.w(TAG, "Unable to launch app "
11634                                         + cpi.applicationInfo.packageName + "/"
11635                                         + cpi.applicationInfo.uid + " for provider "
11636                                         + name + ": process is bad");
11637                                 return null;
11638                             }
11639                         }
11640                         cpr.launchingApp = proc;
11641                         mLaunchingProviders.add(cpr);
11642                     } finally {
11643                         Binder.restoreCallingIdentity(origId);
11644                     }
11645                 }
11646
11647                 checkTime(startTime, "getContentProviderImpl: updating data structures");
11648
11649                 // Make sure the provider is published (the same provider class
11650                 // may be published under multiple names).
11651                 if (firstClass) {
11652                     mProviderMap.putProviderByClass(comp, cpr);
11653                 }
11654
11655                 mProviderMap.putProviderByName(name, cpr);
11656                 conn = incProviderCountLocked(r, cpr, token, stable);
11657                 if (conn != null) {
11658                     conn.waiting = true;
11659                 }
11660             }
11661             checkTime(startTime, "getContentProviderImpl: done!");
11662
11663             grantEphemeralAccessLocked(userId, null /*intent*/,
11664                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11665         }
11666
11667         // Wait for the provider to be published...
11668         synchronized (cpr) {
11669             while (cpr.provider == null) {
11670                 if (cpr.launchingApp == null) {
11671                     Slog.w(TAG, "Unable to launch app "
11672                             + cpi.applicationInfo.packageName + "/"
11673                             + cpi.applicationInfo.uid + " for provider "
11674                             + name + ": launching app became null");
11675                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11676                             UserHandle.getUserId(cpi.applicationInfo.uid),
11677                             cpi.applicationInfo.packageName,
11678                             cpi.applicationInfo.uid, name);
11679                     return null;
11680                 }
11681                 try {
11682                     if (DEBUG_MU) Slog.v(TAG_MU,
11683                             "Waiting to start provider " + cpr
11684                             + " launchingApp=" + cpr.launchingApp);
11685                     if (conn != null) {
11686                         conn.waiting = true;
11687                     }
11688                     cpr.wait();
11689                 } catch (InterruptedException ex) {
11690                 } finally {
11691                     if (conn != null) {
11692                         conn.waiting = false;
11693                     }
11694                 }
11695             }
11696         }
11697         return cpr != null ? cpr.newHolder(conn) : null;
11698     }
11699
11700     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11701             ProcessRecord r, final int userId) {
11702         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11703                 cpi.packageName, userId)) {
11704
11705             final boolean callerForeground = r == null || r.setSchedGroup
11706                     != ProcessList.SCHED_GROUP_BACKGROUND;
11707
11708             // Show a permission review UI only for starting from a foreground app
11709             if (!callerForeground) {
11710                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11711                         + cpi.packageName + " requires a permissions review");
11712                 return false;
11713             }
11714
11715             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11716             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11717                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11718             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11719
11720             if (DEBUG_PERMISSIONS_REVIEW) {
11721                 Slog.i(TAG, "u" + userId + " Launching permission review "
11722                         + "for package " + cpi.packageName);
11723             }
11724
11725             final UserHandle userHandle = new UserHandle(userId);
11726             mHandler.post(new Runnable() {
11727                 @Override
11728                 public void run() {
11729                     mContext.startActivityAsUser(intent, userHandle);
11730                 }
11731             });
11732
11733             return false;
11734         }
11735
11736         return true;
11737     }
11738
11739     PackageManagerInternal getPackageManagerInternalLocked() {
11740         if (mPackageManagerInt == null) {
11741             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11742         }
11743         return mPackageManagerInt;
11744     }
11745
11746     @Override
11747     public final ContentProviderHolder getContentProvider(
11748             IApplicationThread caller, String name, int userId, boolean stable) {
11749         enforceNotIsolatedCaller("getContentProvider");
11750         if (caller == null) {
11751             String msg = "null IApplicationThread when getting content provider "
11752                     + name;
11753             Slog.w(TAG, msg);
11754             throw new SecurityException(msg);
11755         }
11756         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11757         // with cross-user grant.
11758         return getContentProviderImpl(caller, name, null, stable, userId);
11759     }
11760
11761     public ContentProviderHolder getContentProviderExternal(
11762             String name, int userId, IBinder token) {
11763         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11764             "Do not have permission in call getContentProviderExternal()");
11765         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11766                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11767         return getContentProviderExternalUnchecked(name, token, userId);
11768     }
11769
11770     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11771             IBinder token, int userId) {
11772         return getContentProviderImpl(null, name, token, true, userId);
11773     }
11774
11775     /**
11776      * Drop a content provider from a ProcessRecord's bookkeeping
11777      */
11778     public void removeContentProvider(IBinder connection, boolean stable) {
11779         enforceNotIsolatedCaller("removeContentProvider");
11780         long ident = Binder.clearCallingIdentity();
11781         try {
11782             synchronized (this) {
11783                 ContentProviderConnection conn;
11784                 try {
11785                     conn = (ContentProviderConnection)connection;
11786                 } catch (ClassCastException e) {
11787                     String msg ="removeContentProvider: " + connection
11788                             + " not a ContentProviderConnection";
11789                     Slog.w(TAG, msg);
11790                     throw new IllegalArgumentException(msg);
11791                 }
11792                 if (conn == null) {
11793                     throw new NullPointerException("connection is null");
11794                 }
11795                 if (decProviderCountLocked(conn, null, null, stable)) {
11796                     updateOomAdjLocked();
11797                 }
11798             }
11799         } finally {
11800             Binder.restoreCallingIdentity(ident);
11801         }
11802     }
11803
11804     public void removeContentProviderExternal(String name, IBinder token) {
11805         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11806             "Do not have permission in call removeContentProviderExternal()");
11807         int userId = UserHandle.getCallingUserId();
11808         long ident = Binder.clearCallingIdentity();
11809         try {
11810             removeContentProviderExternalUnchecked(name, token, userId);
11811         } finally {
11812             Binder.restoreCallingIdentity(ident);
11813         }
11814     }
11815
11816     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11817         synchronized (this) {
11818             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11819             if(cpr == null) {
11820                 //remove from mProvidersByClass
11821                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11822                 return;
11823             }
11824
11825             //update content provider record entry info
11826             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11827             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11828             if (localCpr.hasExternalProcessHandles()) {
11829                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11830                     updateOomAdjLocked();
11831                 } else {
11832                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11833                             + " with no external reference for token: "
11834                             + token + ".");
11835                 }
11836             } else {
11837                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11838                         + " with no external references.");
11839             }
11840         }
11841     }
11842
11843     public final void publishContentProviders(IApplicationThread caller,
11844             List<ContentProviderHolder> providers) {
11845         if (providers == null) {
11846             return;
11847         }
11848
11849         enforceNotIsolatedCaller("publishContentProviders");
11850         synchronized (this) {
11851             final ProcessRecord r = getRecordForAppLocked(caller);
11852             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11853             if (r == null) {
11854                 throw new SecurityException(
11855                         "Unable to find app for caller " + caller
11856                       + " (pid=" + Binder.getCallingPid()
11857                       + ") when publishing content providers");
11858             }
11859
11860             final long origId = Binder.clearCallingIdentity();
11861
11862             final int N = providers.size();
11863             for (int i = 0; i < N; i++) {
11864                 ContentProviderHolder src = providers.get(i);
11865                 if (src == null || src.info == null || src.provider == null) {
11866                     continue;
11867                 }
11868                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11869                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11870                 if (dst != null) {
11871                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11872                     mProviderMap.putProviderByClass(comp, dst);
11873                     String names[] = dst.info.authority.split(";");
11874                     for (int j = 0; j < names.length; j++) {
11875                         mProviderMap.putProviderByName(names[j], dst);
11876                     }
11877
11878                     int launchingCount = mLaunchingProviders.size();
11879                     int j;
11880                     boolean wasInLaunchingProviders = false;
11881                     for (j = 0; j < launchingCount; j++) {
11882                         if (mLaunchingProviders.get(j) == dst) {
11883                             mLaunchingProviders.remove(j);
11884                             wasInLaunchingProviders = true;
11885                             j--;
11886                             launchingCount--;
11887                         }
11888                     }
11889                     if (wasInLaunchingProviders) {
11890                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11891                     }
11892                     synchronized (dst) {
11893                         dst.provider = src.provider;
11894                         dst.proc = r;
11895                         dst.notifyAll();
11896                     }
11897                     updateOomAdjLocked(r, true);
11898                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11899                             src.info.authority);
11900                 }
11901             }
11902
11903             Binder.restoreCallingIdentity(origId);
11904         }
11905     }
11906
11907     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11908         ContentProviderConnection conn;
11909         try {
11910             conn = (ContentProviderConnection)connection;
11911         } catch (ClassCastException e) {
11912             String msg ="refContentProvider: " + connection
11913                     + " not a ContentProviderConnection";
11914             Slog.w(TAG, msg);
11915             throw new IllegalArgumentException(msg);
11916         }
11917         if (conn == null) {
11918             throw new NullPointerException("connection is null");
11919         }
11920
11921         synchronized (this) {
11922             if (stable > 0) {
11923                 conn.numStableIncs += stable;
11924             }
11925             stable = conn.stableCount + stable;
11926             if (stable < 0) {
11927                 throw new IllegalStateException("stableCount < 0: " + stable);
11928             }
11929
11930             if (unstable > 0) {
11931                 conn.numUnstableIncs += unstable;
11932             }
11933             unstable = conn.unstableCount + unstable;
11934             if (unstable < 0) {
11935                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11936             }
11937
11938             if ((stable+unstable) <= 0) {
11939                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11940                         + stable + " unstable=" + unstable);
11941             }
11942             conn.stableCount = stable;
11943             conn.unstableCount = unstable;
11944             return !conn.dead;
11945         }
11946     }
11947
11948     public void unstableProviderDied(IBinder connection) {
11949         ContentProviderConnection conn;
11950         try {
11951             conn = (ContentProviderConnection)connection;
11952         } catch (ClassCastException e) {
11953             String msg ="refContentProvider: " + connection
11954                     + " not a ContentProviderConnection";
11955             Slog.w(TAG, msg);
11956             throw new IllegalArgumentException(msg);
11957         }
11958         if (conn == null) {
11959             throw new NullPointerException("connection is null");
11960         }
11961
11962         // Safely retrieve the content provider associated with the connection.
11963         IContentProvider provider;
11964         synchronized (this) {
11965             provider = conn.provider.provider;
11966         }
11967
11968         if (provider == null) {
11969             // Um, yeah, we're way ahead of you.
11970             return;
11971         }
11972
11973         // Make sure the caller is being honest with us.
11974         if (provider.asBinder().pingBinder()) {
11975             // Er, no, still looks good to us.
11976             synchronized (this) {
11977                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11978                         + " says " + conn + " died, but we don't agree");
11979                 return;
11980             }
11981         }
11982
11983         // Well look at that!  It's dead!
11984         synchronized (this) {
11985             if (conn.provider.provider != provider) {
11986                 // But something changed...  good enough.
11987                 return;
11988             }
11989
11990             ProcessRecord proc = conn.provider.proc;
11991             if (proc == null || proc.thread == null) {
11992                 // Seems like the process is already cleaned up.
11993                 return;
11994             }
11995
11996             // As far as we're concerned, this is just like receiving a
11997             // death notification...  just a bit prematurely.
11998             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11999                     + ") early provider death");
12000             final long ident = Binder.clearCallingIdentity();
12001             try {
12002                 appDiedLocked(proc);
12003             } finally {
12004                 Binder.restoreCallingIdentity(ident);
12005             }
12006         }
12007     }
12008
12009     @Override
12010     public void appNotRespondingViaProvider(IBinder connection) {
12011         enforceCallingPermission(
12012                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12013
12014         final ContentProviderConnection conn = (ContentProviderConnection) connection;
12015         if (conn == null) {
12016             Slog.w(TAG, "ContentProviderConnection is null");
12017             return;
12018         }
12019
12020         final ProcessRecord host = conn.provider.proc;
12021         if (host == null) {
12022             Slog.w(TAG, "Failed to find hosting ProcessRecord");
12023             return;
12024         }
12025
12026         mHandler.post(new Runnable() {
12027             @Override
12028             public void run() {
12029                 mAppErrors.appNotResponding(host, null, null, false,
12030                         "ContentProvider not responding");
12031             }
12032         });
12033     }
12034
12035     public final void installSystemProviders() {
12036         List<ProviderInfo> providers;
12037         synchronized (this) {
12038             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12039             providers = generateApplicationProvidersLocked(app);
12040             if (providers != null) {
12041                 for (int i=providers.size()-1; i>=0; i--) {
12042                     ProviderInfo pi = (ProviderInfo)providers.get(i);
12043                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12044                         Slog.w(TAG, "Not installing system proc provider " + pi.name
12045                                 + ": not system .apk");
12046                         providers.remove(i);
12047                     }
12048                 }
12049             }
12050         }
12051         if (providers != null) {
12052             mSystemThread.installSystemProviders(providers);
12053         }
12054
12055         mConstants.start(mContext.getContentResolver());
12056         mCoreSettingsObserver = new CoreSettingsObserver(this);
12057         mFontScaleSettingObserver = new FontScaleSettingObserver();
12058
12059         // Now that the settings provider is published we can consider sending
12060         // in a rescue party.
12061         RescueParty.onSettingsProviderPublished(mContext);
12062
12063         //mUsageStatsService.monitorPackages();
12064     }
12065
12066     private void startPersistentApps(int matchFlags) {
12067         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12068
12069         synchronized (this) {
12070             try {
12071                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12072                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12073                 for (ApplicationInfo app : apps) {
12074                     if (!"android".equals(app.packageName)) {
12075                         addAppLocked(app, null, false, null /* ABI override */);
12076                     }
12077                 }
12078             } catch (RemoteException ex) {
12079             }
12080         }
12081     }
12082
12083     /**
12084      * When a user is unlocked, we need to install encryption-unaware providers
12085      * belonging to any running apps.
12086      */
12087     private void installEncryptionUnawareProviders(int userId) {
12088         // We're only interested in providers that are encryption unaware, and
12089         // we don't care about uninstalled apps, since there's no way they're
12090         // running at this point.
12091         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12092
12093         synchronized (this) {
12094             final int NP = mProcessNames.getMap().size();
12095             for (int ip = 0; ip < NP; ip++) {
12096                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12097                 final int NA = apps.size();
12098                 for (int ia = 0; ia < NA; ia++) {
12099                     final ProcessRecord app = apps.valueAt(ia);
12100                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
12101
12102                     final int NG = app.pkgList.size();
12103                     for (int ig = 0; ig < NG; ig++) {
12104                         try {
12105                             final String pkgName = app.pkgList.keyAt(ig);
12106                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12107                                     .getPackageInfo(pkgName, matchFlags, userId);
12108                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12109                                 for (ProviderInfo pi : pkgInfo.providers) {
12110                                     // TODO: keep in sync with generateApplicationProvidersLocked
12111                                     final boolean processMatch = Objects.equals(pi.processName,
12112                                             app.processName) || pi.multiprocess;
12113                                     final boolean userMatch = isSingleton(pi.processName,
12114                                             pi.applicationInfo, pi.name, pi.flags)
12115                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
12116                                     if (processMatch && userMatch) {
12117                                         Log.v(TAG, "Installing " + pi);
12118                                         app.thread.scheduleInstallProvider(pi);
12119                                     } else {
12120                                         Log.v(TAG, "Skipping " + pi);
12121                                     }
12122                                 }
12123                             }
12124                         } catch (RemoteException ignored) {
12125                         }
12126                     }
12127                 }
12128             }
12129         }
12130     }
12131
12132     /**
12133      * Allows apps to retrieve the MIME type of a URI.
12134      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12135      * users, then it does not need permission to access the ContentProvider.
12136      * Either, it needs cross-user uri grants.
12137      *
12138      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12139      *
12140      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12141      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12142      */
12143     public String getProviderMimeType(Uri uri, int userId) {
12144         enforceNotIsolatedCaller("getProviderMimeType");
12145         final String name = uri.getAuthority();
12146         int callingUid = Binder.getCallingUid();
12147         int callingPid = Binder.getCallingPid();
12148         long ident = 0;
12149         boolean clearedIdentity = false;
12150         synchronized (this) {
12151             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12152         }
12153         if (canClearIdentity(callingPid, callingUid, userId)) {
12154             clearedIdentity = true;
12155             ident = Binder.clearCallingIdentity();
12156         }
12157         ContentProviderHolder holder = null;
12158         try {
12159             holder = getContentProviderExternalUnchecked(name, null, userId);
12160             if (holder != null) {
12161                 return holder.provider.getType(uri);
12162             }
12163         } catch (RemoteException e) {
12164             Log.w(TAG, "Content provider dead retrieving " + uri, e);
12165             return null;
12166         } catch (Exception e) {
12167             Log.w(TAG, "Exception while determining type of " + uri, e);
12168             return null;
12169         } finally {
12170             // We need to clear the identity to call removeContentProviderExternalUnchecked
12171             if (!clearedIdentity) {
12172                 ident = Binder.clearCallingIdentity();
12173             }
12174             try {
12175                 if (holder != null) {
12176                     removeContentProviderExternalUnchecked(name, null, userId);
12177                 }
12178             } finally {
12179                 Binder.restoreCallingIdentity(ident);
12180             }
12181         }
12182
12183         return null;
12184     }
12185
12186     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12187         if (UserHandle.getUserId(callingUid) == userId) {
12188             return true;
12189         }
12190         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12191                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12192                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12193                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12194                 return true;
12195         }
12196         return false;
12197     }
12198
12199     // =========================================================
12200     // GLOBAL MANAGEMENT
12201     // =========================================================
12202
12203     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12204             boolean isolated, int isolatedUid) {
12205         String proc = customProcess != null ? customProcess : info.processName;
12206         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12207         final int userId = UserHandle.getUserId(info.uid);
12208         int uid = info.uid;
12209         if (isolated) {
12210             if (isolatedUid == 0) {
12211                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12212                 while (true) {
12213                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12214                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12215                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12216                     }
12217                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12218                     mNextIsolatedProcessUid++;
12219                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12220                         // No process for this uid, use it.
12221                         break;
12222                     }
12223                     stepsLeft--;
12224                     if (stepsLeft <= 0) {
12225                         return null;
12226                     }
12227                 }
12228             } else {
12229                 // Special case for startIsolatedProcess (internal only), where
12230                 // the uid of the isolated process is specified by the caller.
12231                 uid = isolatedUid;
12232             }
12233             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12234
12235             // Register the isolated UID with this application so BatteryStats knows to
12236             // attribute resource usage to the application.
12237             //
12238             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12239             // about the process state of the isolated UID *before* it is registered with the
12240             // owning application.
12241             mBatteryStatsService.addIsolatedUid(uid, info.uid);
12242         }
12243         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12244         if (!mBooted && !mBooting
12245                 && userId == UserHandle.USER_SYSTEM
12246                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12247             r.persistent = true;
12248             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12249         }
12250         addProcessNameLocked(r);
12251         return r;
12252     }
12253
12254     private boolean uidOnBackgroundWhitelist(final int uid) {
12255         final int appId = UserHandle.getAppId(uid);
12256         final int[] whitelist = mBackgroundAppIdWhitelist;
12257         final int N = whitelist.length;
12258         for (int i = 0; i < N; i++) {
12259             if (appId == whitelist[i]) {
12260                 return true;
12261             }
12262         }
12263         return false;
12264     }
12265
12266     @Override
12267     public void backgroundWhitelistUid(final int uid) {
12268         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12269             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12270         }
12271
12272         if (DEBUG_BACKGROUND_CHECK) {
12273             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12274         }
12275         synchronized (this) {
12276             final int N = mBackgroundAppIdWhitelist.length;
12277             int[] newList = new int[N+1];
12278             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12279             newList[N] = UserHandle.getAppId(uid);
12280             mBackgroundAppIdWhitelist = newList;
12281         }
12282     }
12283
12284     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12285             String abiOverride) {
12286         ProcessRecord app;
12287         if (!isolated) {
12288             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12289                     info.uid, true);
12290         } else {
12291             app = null;
12292         }
12293
12294         if (app == null) {
12295             app = newProcessRecordLocked(info, customProcess, isolated, 0);
12296             updateLruProcessLocked(app, false, null);
12297             updateOomAdjLocked();
12298         }
12299
12300         // This package really, really can not be stopped.
12301         try {
12302             AppGlobals.getPackageManager().setPackageStoppedState(
12303                     info.packageName, false, UserHandle.getUserId(app.uid));
12304         } catch (RemoteException e) {
12305         } catch (IllegalArgumentException e) {
12306             Slog.w(TAG, "Failed trying to unstop package "
12307                     + info.packageName + ": " + e);
12308         }
12309
12310         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12311             app.persistent = true;
12312             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12313         }
12314         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12315             mPersistentStartingProcesses.add(app);
12316             startProcessLocked(app, "added application",
12317                     customProcess != null ? customProcess : app.processName, abiOverride,
12318                     null /* entryPoint */, null /* entryPointArgs */);
12319         }
12320
12321         return app;
12322     }
12323
12324     public void unhandledBack() {
12325         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12326                 "unhandledBack()");
12327
12328         synchronized(this) {
12329             final long origId = Binder.clearCallingIdentity();
12330             try {
12331                 getFocusedStack().unhandledBackLocked();
12332             } finally {
12333                 Binder.restoreCallingIdentity(origId);
12334             }
12335         }
12336     }
12337
12338     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12339         enforceNotIsolatedCaller("openContentUri");
12340         final int userId = UserHandle.getCallingUserId();
12341         final Uri uri = Uri.parse(uriString);
12342         String name = uri.getAuthority();
12343         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12344         ParcelFileDescriptor pfd = null;
12345         if (cph != null) {
12346             // We record the binder invoker's uid in thread-local storage before
12347             // going to the content provider to open the file.  Later, in the code
12348             // that handles all permissions checks, we look for this uid and use
12349             // that rather than the Activity Manager's own uid.  The effect is that
12350             // we do the check against the caller's permissions even though it looks
12351             // to the content provider like the Activity Manager itself is making
12352             // the request.
12353             Binder token = new Binder();
12354             sCallerIdentity.set(new Identity(
12355                     token, Binder.getCallingPid(), Binder.getCallingUid()));
12356             try {
12357                 pfd = cph.provider.openFile(null, uri, "r", null, token);
12358             } catch (FileNotFoundException e) {
12359                 // do nothing; pfd will be returned null
12360             } finally {
12361                 // Ensure that whatever happens, we clean up the identity state
12362                 sCallerIdentity.remove();
12363                 // Ensure we're done with the provider.
12364                 removeContentProviderExternalUnchecked(name, null, userId);
12365             }
12366         } else {
12367             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12368         }
12369         return pfd;
12370     }
12371
12372     // Actually is sleeping or shutting down or whatever else in the future
12373     // is an inactive state.
12374     boolean isSleepingOrShuttingDownLocked() {
12375         return isSleepingLocked() || mShuttingDown;
12376     }
12377
12378     boolean isShuttingDownLocked() {
12379         return mShuttingDown;
12380     }
12381
12382     boolean isSleepingLocked() {
12383         return mSleeping;
12384     }
12385
12386     void onWakefulnessChanged(int wakefulness) {
12387         synchronized(this) {
12388             mWakefulness = wakefulness;
12389             updateSleepIfNeededLocked();
12390         }
12391     }
12392
12393     void finishRunningVoiceLocked() {
12394         if (mRunningVoice != null) {
12395             mRunningVoice = null;
12396             mVoiceWakeLock.release();
12397             updateSleepIfNeededLocked();
12398         }
12399     }
12400
12401     void startTimeTrackingFocusedActivityLocked() {
12402         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12403         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12404             mCurAppTimeTracker.start(resumedActivity.packageName);
12405         }
12406     }
12407
12408     void updateSleepIfNeededLocked() {
12409         final boolean shouldSleep = shouldSleepLocked();
12410         if (mSleeping && !shouldSleep) {
12411             mSleeping = false;
12412             startTimeTrackingFocusedActivityLocked();
12413             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12414             mStackSupervisor.comeOutOfSleepIfNeededLocked();
12415             sendNotifyVrManagerOfSleepState(false);
12416             updateOomAdjLocked();
12417         } else if (!mSleeping && shouldSleep) {
12418             mSleeping = true;
12419             if (mCurAppTimeTracker != null) {
12420                 mCurAppTimeTracker.stop();
12421             }
12422             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12423             mStackSupervisor.goingToSleepLocked();
12424             sendNotifyVrManagerOfSleepState(true);
12425             updateOomAdjLocked();
12426
12427             // Initialize the wake times of all processes.
12428             checkExcessivePowerUsageLocked(false);
12429             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12430             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12431             mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
12432         }
12433
12434         // Also update state in a special way for running foreground services UI.
12435         switch (mWakefulness) {
12436             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12437             case PowerManagerInternal.WAKEFULNESS_DREAMING:
12438             case PowerManagerInternal.WAKEFULNESS_DOZING:
12439                 mServices.updateScreenStateLocked(false);
12440                 break;
12441             case PowerManagerInternal.WAKEFULNESS_AWAKE:
12442             default:
12443                 mServices.updateScreenStateLocked(true);
12444                 break;
12445         }
12446     }
12447
12448     private boolean shouldSleepLocked() {
12449         // Resume applications while running a voice interactor.
12450         if (mRunningVoice != null) {
12451             return false;
12452         }
12453
12454         // TODO: Transform the lock screen state into a sleep token instead.
12455         switch (mWakefulness) {
12456             case PowerManagerInternal.WAKEFULNESS_AWAKE:
12457             case PowerManagerInternal.WAKEFULNESS_DREAMING:
12458             case PowerManagerInternal.WAKEFULNESS_DOZING:
12459                 // Pause applications whenever the lock screen is shown or any sleep
12460                 // tokens have been acquired.
12461                 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12462             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12463             default:
12464                 // If we're asleep then pause applications unconditionally.
12465                 return true;
12466         }
12467     }
12468
12469     /** Pokes the task persister. */
12470     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12471         mRecentTasks.notifyTaskPersisterLocked(task, flush);
12472     }
12473
12474     /**
12475      * Notifies all listeners when the pinned stack animation starts.
12476      */
12477     @Override
12478     public void notifyPinnedStackAnimationStarted() {
12479         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12480     }
12481
12482     /**
12483      * Notifies all listeners when the pinned stack animation ends.
12484      */
12485     @Override
12486     public void notifyPinnedStackAnimationEnded() {
12487         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12488     }
12489
12490     @Override
12491     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12492         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12493     }
12494
12495     @Override
12496     public boolean shutdown(int timeout) {
12497         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12498                 != PackageManager.PERMISSION_GRANTED) {
12499             throw new SecurityException("Requires permission "
12500                     + android.Manifest.permission.SHUTDOWN);
12501         }
12502
12503         boolean timedout = false;
12504
12505         synchronized(this) {
12506             mShuttingDown = true;
12507             updateEventDispatchingLocked();
12508             timedout = mStackSupervisor.shutdownLocked(timeout);
12509         }
12510
12511         mAppOpsService.shutdown();
12512         if (mUsageStatsService != null) {
12513             mUsageStatsService.prepareShutdown();
12514         }
12515         mBatteryStatsService.shutdown();
12516         synchronized (this) {
12517             mProcessStats.shutdownLocked();
12518             notifyTaskPersisterLocked(null, true);
12519         }
12520
12521         return timedout;
12522     }
12523
12524     public final void activitySlept(IBinder token) {
12525         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12526
12527         final long origId = Binder.clearCallingIdentity();
12528
12529         synchronized (this) {
12530             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12531             if (r != null) {
12532                 mStackSupervisor.activitySleptLocked(r);
12533             }
12534         }
12535
12536         Binder.restoreCallingIdentity(origId);
12537     }
12538
12539     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12540         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12541         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12542         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12543             boolean wasRunningVoice = mRunningVoice != null;
12544             mRunningVoice = session;
12545             if (!wasRunningVoice) {
12546                 mVoiceWakeLock.acquire();
12547                 updateSleepIfNeededLocked();
12548             }
12549         }
12550     }
12551
12552     private void updateEventDispatchingLocked() {
12553         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12554     }
12555
12556     @Override
12557     public void setLockScreenShown(boolean showing) {
12558         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12559                 != PackageManager.PERMISSION_GRANTED) {
12560             throw new SecurityException("Requires permission "
12561                     + android.Manifest.permission.DEVICE_POWER);
12562         }
12563
12564         synchronized(this) {
12565             long ident = Binder.clearCallingIdentity();
12566             try {
12567                 mKeyguardController.setKeyguardShown(showing);
12568             } finally {
12569                 Binder.restoreCallingIdentity(ident);
12570             }
12571         }
12572         closeSystemDialogs("setLockScreenShown");
12573     }
12574
12575     @Override
12576     public void notifyLockedProfile(@UserIdInt int userId) {
12577         try {
12578             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12579                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12580             }
12581         } catch (RemoteException ex) {
12582             throw new SecurityException("Fail to check is caller a privileged app", ex);
12583         }
12584
12585         synchronized (this) {
12586             final long ident = Binder.clearCallingIdentity();
12587             try {
12588                 if (mUserController.shouldConfirmCredentials(userId)) {
12589                     if (mKeyguardController.isKeyguardLocked()) {
12590                         // Showing launcher to avoid user entering credential twice.
12591                         final int currentUserId = mUserController.getCurrentUserIdLocked();
12592                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12593                     }
12594                     mStackSupervisor.lockAllProfileTasks(userId);
12595                 }
12596             } finally {
12597                 Binder.restoreCallingIdentity(ident);
12598             }
12599         }
12600     }
12601
12602     @Override
12603     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12604         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12605         synchronized (this) {
12606             final long ident = Binder.clearCallingIdentity();
12607             try {
12608                 mActivityStarter.startConfirmCredentialIntent(intent, options);
12609             } finally {
12610                 Binder.restoreCallingIdentity(ident);
12611             }
12612         }
12613     }
12614
12615     @Override
12616     public void stopAppSwitches() {
12617         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12618                 != PackageManager.PERMISSION_GRANTED) {
12619             throw new SecurityException("viewquires permission "
12620                     + android.Manifest.permission.STOP_APP_SWITCHES);
12621         }
12622
12623         synchronized(this) {
12624             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12625                     + APP_SWITCH_DELAY_TIME;
12626             mDidAppSwitch = false;
12627             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12628             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12629             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12630         }
12631     }
12632
12633     public void resumeAppSwitches() {
12634         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12635                 != PackageManager.PERMISSION_GRANTED) {
12636             throw new SecurityException("Requires permission "
12637                     + android.Manifest.permission.STOP_APP_SWITCHES);
12638         }
12639
12640         synchronized(this) {
12641             // Note that we don't execute any pending app switches... we will
12642             // let those wait until either the timeout, or the next start
12643             // activity request.
12644             mAppSwitchesAllowedTime = 0;
12645         }
12646     }
12647
12648     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12649             int callingPid, int callingUid, String name) {
12650         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12651             return true;
12652         }
12653
12654         int perm = checkComponentPermission(
12655                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12656                 sourceUid, -1, true);
12657         if (perm == PackageManager.PERMISSION_GRANTED) {
12658             return true;
12659         }
12660
12661         // If the actual IPC caller is different from the logical source, then
12662         // also see if they are allowed to control app switches.
12663         if (callingUid != -1 && callingUid != sourceUid) {
12664             perm = checkComponentPermission(
12665                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12666                     callingUid, -1, true);
12667             if (perm == PackageManager.PERMISSION_GRANTED) {
12668                 return true;
12669             }
12670         }
12671
12672         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12673         return false;
12674     }
12675
12676     public void setDebugApp(String packageName, boolean waitForDebugger,
12677             boolean persistent) {
12678         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12679                 "setDebugApp()");
12680
12681         long ident = Binder.clearCallingIdentity();
12682         try {
12683             // Note that this is not really thread safe if there are multiple
12684             // callers into it at the same time, but that's not a situation we
12685             // care about.
12686             if (persistent) {
12687                 final ContentResolver resolver = mContext.getContentResolver();
12688                 Settings.Global.putString(
12689                     resolver, Settings.Global.DEBUG_APP,
12690                     packageName);
12691                 Settings.Global.putInt(
12692                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12693                     waitForDebugger ? 1 : 0);
12694             }
12695
12696             synchronized (this) {
12697                 if (!persistent) {
12698                     mOrigDebugApp = mDebugApp;
12699                     mOrigWaitForDebugger = mWaitForDebugger;
12700                 }
12701                 mDebugApp = packageName;
12702                 mWaitForDebugger = waitForDebugger;
12703                 mDebugTransient = !persistent;
12704                 if (packageName != null) {
12705                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12706                             false, UserHandle.USER_ALL, "set debug app");
12707                 }
12708             }
12709         } finally {
12710             Binder.restoreCallingIdentity(ident);
12711         }
12712     }
12713
12714     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12715         synchronized (this) {
12716             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12717             if (!isDebuggable) {
12718                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12719                     throw new SecurityException("Process not debuggable: " + app.packageName);
12720                 }
12721             }
12722
12723             mTrackAllocationApp = processName;
12724         }
12725     }
12726
12727     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12728         synchronized (this) {
12729             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12730             if (!isDebuggable) {
12731                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12732                     throw new SecurityException("Process not debuggable: " + app.packageName);
12733                 }
12734             }
12735             mProfileApp = processName;
12736             mProfileFile = profilerInfo.profileFile;
12737             if (mProfileFd != null) {
12738                 try {
12739                     mProfileFd.close();
12740                 } catch (IOException e) {
12741                 }
12742                 mProfileFd = null;
12743             }
12744             mProfileFd = profilerInfo.profileFd;
12745             mSamplingInterval = profilerInfo.samplingInterval;
12746             mAutoStopProfiler = profilerInfo.autoStopProfiler;
12747             mStreamingOutput = profilerInfo.streamingOutput;
12748             mProfileType = 0;
12749         }
12750     }
12751
12752     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12753         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12754         if (!isDebuggable) {
12755             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12756                 throw new SecurityException("Process not debuggable: " + app.packageName);
12757             }
12758         }
12759         mNativeDebuggingApp = processName;
12760     }
12761
12762     @Override
12763     public void setAlwaysFinish(boolean enabled) {
12764         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12765                 "setAlwaysFinish()");
12766
12767         long ident = Binder.clearCallingIdentity();
12768         try {
12769             Settings.Global.putInt(
12770                     mContext.getContentResolver(),
12771                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12772
12773             synchronized (this) {
12774                 mAlwaysFinishActivities = enabled;
12775             }
12776         } finally {
12777             Binder.restoreCallingIdentity(ident);
12778         }
12779     }
12780
12781     @Override
12782     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12783         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12784                 "setActivityController()");
12785         synchronized (this) {
12786             mController = controller;
12787             mControllerIsAMonkey = imAMonkey;
12788             Watchdog.getInstance().setActivityController(controller);
12789         }
12790     }
12791
12792     @Override
12793     public void setUserIsMonkey(boolean userIsMonkey) {
12794         synchronized (this) {
12795             synchronized (mPidsSelfLocked) {
12796                 final int callingPid = Binder.getCallingPid();
12797                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12798                 if (proc == null) {
12799                     throw new SecurityException("Unknown process: " + callingPid);
12800                 }
12801                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12802                     throw new SecurityException("Only an instrumentation process "
12803                             + "with a UiAutomation can call setUserIsMonkey");
12804                 }
12805             }
12806             mUserIsMonkey = userIsMonkey;
12807         }
12808     }
12809
12810     @Override
12811     public boolean isUserAMonkey() {
12812         synchronized (this) {
12813             // If there is a controller also implies the user is a monkey.
12814             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12815         }
12816     }
12817
12818     /**
12819      * @deprecated This method is only used by a few internal components and it will soon be
12820      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12821      * No new code should be calling it.
12822      */
12823     @Deprecated
12824     @Override
12825     public void requestBugReport(int bugreportType) {
12826         String extraOptions = null;
12827         switch (bugreportType) {
12828             case ActivityManager.BUGREPORT_OPTION_FULL:
12829                 // Default options.
12830                 break;
12831             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12832                 extraOptions = "bugreportplus";
12833                 break;
12834             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12835                 extraOptions = "bugreportremote";
12836                 break;
12837             case ActivityManager.BUGREPORT_OPTION_WEAR:
12838                 extraOptions = "bugreportwear";
12839                 break;
12840             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12841                 extraOptions = "bugreporttelephony";
12842                 break;
12843             default:
12844                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12845                         + bugreportType);
12846         }
12847         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12848         if (extraOptions != null) {
12849             SystemProperties.set("dumpstate.options", extraOptions);
12850         }
12851         SystemProperties.set("ctl.start", "bugreport");
12852     }
12853
12854     /**
12855      * @deprecated This method is only used by a few internal components and it will soon be
12856      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12857      * No new code should be calling it.
12858      */
12859     @Deprecated
12860     @Override
12861     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12862
12863         if (!TextUtils.isEmpty(shareTitle)) {
12864             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12865                 String errorStr = "shareTitle should be less than " +
12866                         MAX_BUGREPORT_TITLE_SIZE + " characters";
12867                 throw new IllegalArgumentException(errorStr);
12868             } else {
12869                 if (!TextUtils.isEmpty(shareDescription)) {
12870                     int length;
12871                     try {
12872                         length = shareDescription.getBytes("UTF-8").length;
12873                     } catch (UnsupportedEncodingException e) {
12874                         String errorStr = "shareDescription: UnsupportedEncodingException";
12875                         throw new IllegalArgumentException(errorStr);
12876                     }
12877                     if (length > SystemProperties.PROP_VALUE_MAX) {
12878                         String errorStr = "shareTitle should be less than " +
12879                                 SystemProperties.PROP_VALUE_MAX + " bytes";
12880                         throw new IllegalArgumentException(errorStr);
12881                     } else {
12882                         SystemProperties.set("dumpstate.options.description", shareDescription);
12883                     }
12884                 }
12885                 SystemProperties.set("dumpstate.options.title", shareTitle);
12886             }
12887         }
12888
12889         Slog.d(TAG, "Bugreport notification title " + shareTitle
12890                 + " description " + shareDescription);
12891         requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12892     }
12893
12894     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12895         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12896     }
12897
12898     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12899         if (r != null && (r.instr != null || r.usingWrapper)) {
12900             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12901         }
12902         return KEY_DISPATCHING_TIMEOUT;
12903     }
12904
12905     @Override
12906     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12907         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12908                 != PackageManager.PERMISSION_GRANTED) {
12909             throw new SecurityException("Requires permission "
12910                     + android.Manifest.permission.FILTER_EVENTS);
12911         }
12912         ProcessRecord proc;
12913         long timeout;
12914         synchronized (this) {
12915             synchronized (mPidsSelfLocked) {
12916                 proc = mPidsSelfLocked.get(pid);
12917             }
12918             timeout = getInputDispatchingTimeoutLocked(proc);
12919         }
12920
12921         if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12922             return -1;
12923         }
12924
12925         return timeout;
12926     }
12927
12928     /**
12929      * Handle input dispatching timeouts.
12930      * Returns whether input dispatching should be aborted or not.
12931      */
12932     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12933             final ActivityRecord activity, final ActivityRecord parent,
12934             final boolean aboveSystem, String reason) {
12935         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12936                 != PackageManager.PERMISSION_GRANTED) {
12937             throw new SecurityException("Requires permission "
12938                     + android.Manifest.permission.FILTER_EVENTS);
12939         }
12940
12941         final String annotation;
12942         if (reason == null) {
12943             annotation = "Input dispatching timed out";
12944         } else {
12945             annotation = "Input dispatching timed out (" + reason + ")";
12946         }
12947
12948         if (proc != null) {
12949             synchronized (this) {
12950                 if (proc.debugging) {
12951                     return false;
12952                 }
12953
12954                 if (proc.instr != null) {
12955                     Bundle info = new Bundle();
12956                     info.putString("shortMsg", "keyDispatchingTimedOut");
12957                     info.putString("longMsg", annotation);
12958                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12959                     return true;
12960                 }
12961             }
12962             mHandler.post(new Runnable() {
12963                 @Override
12964                 public void run() {
12965                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12966                 }
12967             });
12968         }
12969
12970         return true;
12971     }
12972
12973     @Override
12974     public Bundle getAssistContextExtras(int requestType) {
12975         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12976                 null, null, true /* focused */, true /* newSessionId */,
12977                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12978         if (pae == null) {
12979             return null;
12980         }
12981         synchronized (pae) {
12982             while (!pae.haveResult) {
12983                 try {
12984                     pae.wait();
12985                 } catch (InterruptedException e) {
12986                 }
12987             }
12988         }
12989         synchronized (this) {
12990             buildAssistBundleLocked(pae, pae.result);
12991             mPendingAssistExtras.remove(pae);
12992             mUiHandler.removeCallbacks(pae);
12993         }
12994         return pae.extras;
12995     }
12996
12997     @Override
12998     public boolean isAssistDataAllowedOnCurrentActivity() {
12999         int userId;
13000         synchronized (this) {
13001             final ActivityStack focusedStack = getFocusedStack();
13002             if (focusedStack == null || focusedStack.isAssistantStack()) {
13003                 return false;
13004             }
13005
13006             final ActivityRecord activity = focusedStack.topActivity();
13007             if (activity == null) {
13008                 return false;
13009             }
13010             userId = activity.userId;
13011         }
13012         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13013                 Context.DEVICE_POLICY_SERVICE);
13014         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13015     }
13016
13017     @Override
13018     public boolean showAssistFromActivity(IBinder token, Bundle args) {
13019         long ident = Binder.clearCallingIdentity();
13020         try {
13021             synchronized (this) {
13022                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13023                 ActivityRecord top = getFocusedStack().topActivity();
13024                 if (top != caller) {
13025                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13026                             + " is not current top " + top);
13027                     return false;
13028                 }
13029                 if (!top.nowVisible) {
13030                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13031                             + " is not visible");
13032                     return false;
13033                 }
13034             }
13035             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13036                     token);
13037         } finally {
13038             Binder.restoreCallingIdentity(ident);
13039         }
13040     }
13041
13042     @Override
13043     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13044             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13045         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13046                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13047                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13048     }
13049
13050     @Override
13051     public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13052             IBinder activityToken, int flags) {
13053         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13054                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13055                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13056     }
13057
13058     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13059             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13060             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13061             int flags) {
13062         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13063                 "enqueueAssistContext()");
13064
13065         synchronized (this) {
13066             ActivityRecord activity = getFocusedStack().topActivity();
13067             if (activity == null) {
13068                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13069                 return null;
13070             }
13071             if (activity.app == null || activity.app.thread == null) {
13072                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13073                 return null;
13074             }
13075             if (focused) {
13076                 if (activityToken != null) {
13077                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13078                     if (activity != caller) {
13079                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13080                                 + " is not current top " + activity);
13081                         return null;
13082                     }
13083                 }
13084             } else {
13085                 activity = ActivityRecord.forTokenLocked(activityToken);
13086                 if (activity == null) {
13087                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13088                             + " couldn't be found");
13089                     return null;
13090                 }
13091             }
13092
13093             PendingAssistExtras pae;
13094             Bundle extras = new Bundle();
13095             if (args != null) {
13096                 extras.putAll(args);
13097             }
13098             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13099             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13100
13101             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13102                     userHandle);
13103             pae.isHome = activity.isHomeActivity();
13104
13105             // Increment the sessionId if necessary
13106             if (newSessionId) {
13107                 mViSessionId++;
13108             }
13109             try {
13110                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13111                         mViSessionId, flags);
13112                 mPendingAssistExtras.add(pae);
13113                 mUiHandler.postDelayed(pae, timeout);
13114             } catch (RemoteException e) {
13115                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13116                 return null;
13117             }
13118             return pae;
13119         }
13120     }
13121
13122     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13123         IResultReceiver receiver;
13124         synchronized (this) {
13125             mPendingAssistExtras.remove(pae);
13126             receiver = pae.receiver;
13127         }
13128         if (receiver != null) {
13129             // Caller wants result sent back to them.
13130             Bundle sendBundle = new Bundle();
13131             // At least return the receiver extras
13132             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13133                     pae.receiverExtras);
13134             try {
13135                 pae.receiver.send(0, sendBundle);
13136             } catch (RemoteException e) {
13137             }
13138         }
13139     }
13140
13141     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13142         if (result != null) {
13143             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13144         }
13145         if (pae.hint != null) {
13146             pae.extras.putBoolean(pae.hint, true);
13147         }
13148     }
13149
13150     /** Called from an app when assist data is ready. */
13151     @Override
13152     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13153             AssistContent content, Uri referrer) {
13154         PendingAssistExtras pae = (PendingAssistExtras)token;
13155         synchronized (pae) {
13156             pae.result = extras;
13157             pae.structure = structure;
13158             pae.content = content;
13159             if (referrer != null) {
13160                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13161             }
13162             if (structure != null) {
13163                 structure.setHomeActivity(pae.isHome);
13164             }
13165             pae.haveResult = true;
13166             pae.notifyAll();
13167             if (pae.intent == null && pae.receiver == null) {
13168                 // Caller is just waiting for the result.
13169                 return;
13170             }
13171         }
13172
13173         // We are now ready to launch the assist activity.
13174         IResultReceiver sendReceiver = null;
13175         Bundle sendBundle = null;
13176         synchronized (this) {
13177             buildAssistBundleLocked(pae, extras);
13178             boolean exists = mPendingAssistExtras.remove(pae);
13179             mUiHandler.removeCallbacks(pae);
13180             if (!exists) {
13181                 // Timed out.
13182                 return;
13183             }
13184             if ((sendReceiver=pae.receiver) != null) {
13185                 // Caller wants result sent back to them.
13186                 sendBundle = new Bundle();
13187                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13188                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13189                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13190                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13191                         pae.receiverExtras);
13192             }
13193         }
13194         if (sendReceiver != null) {
13195             try {
13196                 sendReceiver.send(0, sendBundle);
13197             } catch (RemoteException e) {
13198             }
13199             return;
13200         }
13201
13202         long ident = Binder.clearCallingIdentity();
13203         try {
13204             pae.intent.replaceExtras(pae.extras);
13205             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13206                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
13207                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13208             closeSystemDialogs("assist");
13209             try {
13210                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13211             } catch (ActivityNotFoundException e) {
13212                 Slog.w(TAG, "No activity to handle assist action.", e);
13213             }
13214         } finally {
13215             Binder.restoreCallingIdentity(ident);
13216         }
13217     }
13218
13219     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13220             Bundle args) {
13221         return enqueueAssistContext(requestType, intent, hint, null, null, null,
13222                 true /* focused */, true /* newSessionId */, userHandle, args,
13223                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13224     }
13225
13226     public void registerProcessObserver(IProcessObserver observer) {
13227         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13228                 "registerProcessObserver()");
13229         synchronized (this) {
13230             mProcessObservers.register(observer);
13231         }
13232     }
13233
13234     @Override
13235     public void unregisterProcessObserver(IProcessObserver observer) {
13236         synchronized (this) {
13237             mProcessObservers.unregister(observer);
13238         }
13239     }
13240
13241     @Override
13242     public int getUidProcessState(int uid, String callingPackage) {
13243         if (!hasUsageStatsPermission(callingPackage)) {
13244             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13245                     "getUidProcessState");
13246         }
13247
13248         synchronized (this) {
13249             UidRecord uidRec = mActiveUids.get(uid);
13250             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13251         }
13252     }
13253
13254     @Override
13255     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13256             String callingPackage) {
13257         if (!hasUsageStatsPermission(callingPackage)) {
13258             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13259                     "registerUidObserver");
13260         }
13261         synchronized (this) {
13262             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13263                     callingPackage, which, cutpoint));
13264         }
13265     }
13266
13267     @Override
13268     public void unregisterUidObserver(IUidObserver observer) {
13269         synchronized (this) {
13270             mUidObservers.unregister(observer);
13271         }
13272     }
13273
13274     @Override
13275     public boolean convertFromTranslucent(IBinder token) {
13276         final long origId = Binder.clearCallingIdentity();
13277         try {
13278             synchronized (this) {
13279                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13280                 if (r == null) {
13281                     return false;
13282                 }
13283                 final boolean translucentChanged = r.changeWindowTranslucency(true);
13284                 if (translucentChanged) {
13285                     r.getStack().releaseBackgroundResources(r);
13286                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13287                 }
13288                 mWindowManager.setAppFullscreen(token, true);
13289                 return translucentChanged;
13290             }
13291         } finally {
13292             Binder.restoreCallingIdentity(origId);
13293         }
13294     }
13295
13296     @Override
13297     public boolean convertToTranslucent(IBinder token, Bundle options) {
13298         final long origId = Binder.clearCallingIdentity();
13299         try {
13300             synchronized (this) {
13301                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13302                 if (r == null) {
13303                     return false;
13304                 }
13305                 final TaskRecord task = r.getTask();
13306                 int index = task.mActivities.lastIndexOf(r);
13307                 if (index > 0) {
13308                     ActivityRecord under = task.mActivities.get(index - 1);
13309                     under.returningOptions = ActivityOptions.fromBundle(options);
13310                 }
13311                 final boolean translucentChanged = r.changeWindowTranslucency(false);
13312                 if (translucentChanged) {
13313                     r.getStack().convertActivityToTranslucent(r);
13314                 }
13315                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13316                 mWindowManager.setAppFullscreen(token, false);
13317                 return translucentChanged;
13318             }
13319         } finally {
13320             Binder.restoreCallingIdentity(origId);
13321         }
13322     }
13323
13324     @Override
13325     public boolean requestVisibleBehind(IBinder token, boolean visible) {
13326         final long origId = Binder.clearCallingIdentity();
13327         try {
13328             synchronized (this) {
13329                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13330                 if (r != null) {
13331                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13332                 }
13333             }
13334             return false;
13335         } finally {
13336             Binder.restoreCallingIdentity(origId);
13337         }
13338     }
13339
13340     @Override
13341     public boolean isBackgroundVisibleBehind(IBinder token) {
13342         final long origId = Binder.clearCallingIdentity();
13343         try {
13344             synchronized (this) {
13345                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
13346                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13347                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13348                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13349                 return visible;
13350             }
13351         } finally {
13352             Binder.restoreCallingIdentity(origId);
13353         }
13354     }
13355
13356     @Override
13357     public Bundle getActivityOptions(IBinder token) {
13358         final long origId = Binder.clearCallingIdentity();
13359         try {
13360             synchronized (this) {
13361                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13362                 if (r != null) {
13363                     final ActivityOptions activityOptions = r.pendingOptions;
13364                     r.pendingOptions = null;
13365                     return activityOptions == null ? null : activityOptions.toBundle();
13366                 }
13367                 return null;
13368             }
13369         } finally {
13370             Binder.restoreCallingIdentity(origId);
13371         }
13372     }
13373
13374     @Override
13375     public void setImmersive(IBinder token, boolean immersive) {
13376         synchronized(this) {
13377             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13378             if (r == null) {
13379                 throw new IllegalArgumentException();
13380             }
13381             r.immersive = immersive;
13382
13383             // update associated state if we're frontmost
13384             if (r == mStackSupervisor.getResumedActivityLocked()) {
13385                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13386                 applyUpdateLockStateLocked(r);
13387             }
13388         }
13389     }
13390
13391     @Override
13392     public boolean isImmersive(IBinder token) {
13393         synchronized (this) {
13394             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13395             if (r == null) {
13396                 throw new IllegalArgumentException();
13397             }
13398             return r.immersive;
13399         }
13400     }
13401
13402     @Override
13403     public void setVrThread(int tid) {
13404         enforceSystemHasVrFeature();
13405         synchronized (this) {
13406             synchronized (mPidsSelfLocked) {
13407                 final int pid = Binder.getCallingPid();
13408                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13409                 mVrController.setVrThreadLocked(tid, pid, proc);
13410             }
13411         }
13412     }
13413
13414     @Override
13415     public void setPersistentVrThread(int tid) {
13416         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13417             final String msg = "Permission Denial: setPersistentVrThread() from pid="
13418                     + Binder.getCallingPid()
13419                     + ", uid=" + Binder.getCallingUid()
13420                     + " requires " + permission.RESTRICTED_VR_ACCESS;
13421             Slog.w(TAG, msg);
13422             throw new SecurityException(msg);
13423         }
13424         enforceSystemHasVrFeature();
13425         synchronized (this) {
13426             synchronized (mPidsSelfLocked) {
13427                 final int pid = Binder.getCallingPid();
13428                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13429                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13430             }
13431         }
13432     }
13433
13434     /**
13435      * Schedule the given thread a normal scheduling priority.
13436      *
13437      * @param newTid the tid of the thread to adjust the scheduling of.
13438      * @param suppressLogs {@code true} if any error logging should be disabled.
13439      *
13440      * @return {@code true} if this succeeded.
13441      */
13442     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13443         try {
13444             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13445             return true;
13446         } catch (IllegalArgumentException e) {
13447             if (!suppressLogs) {
13448                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13449             }
13450         }
13451         return false;
13452     }
13453
13454     /**
13455      * Schedule the given thread an FIFO scheduling priority.
13456      *
13457      * @param newTid the tid of the thread to adjust the scheduling of.
13458      * @param suppressLogs {@code true} if any error logging should be disabled.
13459      *
13460      * @return {@code true} if this succeeded.
13461      */
13462     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13463         try {
13464             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13465             return true;
13466         } catch (IllegalArgumentException e) {
13467             if (!suppressLogs) {
13468                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13469             }
13470         }
13471         return false;
13472     }
13473
13474     /**
13475      * Check that we have the features required for VR-related API calls, and throw an exception if
13476      * not.
13477      */
13478     private void enforceSystemHasVrFeature() {
13479         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13480             throw new UnsupportedOperationException("VR mode not supported on this device!");
13481         }
13482     }
13483
13484     @Override
13485     public void setRenderThread(int tid) {
13486         synchronized (this) {
13487             ProcessRecord proc;
13488             int pid = Binder.getCallingPid();
13489             if (pid == Process.myPid()) {
13490                 demoteSystemServerRenderThread(tid);
13491                 return;
13492             }
13493             synchronized (mPidsSelfLocked) {
13494                 proc = mPidsSelfLocked.get(pid);
13495                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13496                     // ensure the tid belongs to the process
13497                     if (!isThreadInProcess(pid, tid)) {
13498                         throw new IllegalArgumentException(
13499                             "Render thread does not belong to process");
13500                     }
13501                     proc.renderThreadTid = tid;
13502                     if (DEBUG_OOM_ADJ) {
13503                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13504                     }
13505                     // promote to FIFO now
13506                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13507                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13508                         if (mUseFifoUiScheduling) {
13509                             setThreadScheduler(proc.renderThreadTid,
13510                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13511                         } else {
13512                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13513                         }
13514                     }
13515                 } else {
13516                     if (DEBUG_OOM_ADJ) {
13517                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13518                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
13519                                mUseFifoUiScheduling);
13520                     }
13521                 }
13522             }
13523         }
13524     }
13525
13526     /**
13527      * We only use RenderThread in system_server to store task snapshots to the disk, which should
13528      * happen in the background. Thus, demote render thread from system_server to a lower priority.
13529      *
13530      * @param tid the tid of the RenderThread
13531      */
13532     private void demoteSystemServerRenderThread(int tid) {
13533         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13534     }
13535
13536     @Override
13537     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13538         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13539             throw new UnsupportedOperationException("VR mode not supported on this device!");
13540         }
13541
13542         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13543
13544         ActivityRecord r;
13545         synchronized (this) {
13546             r = ActivityRecord.isInStackLocked(token);
13547         }
13548
13549         if (r == null) {
13550             throw new IllegalArgumentException();
13551         }
13552
13553         int err;
13554         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13555                 VrManagerInternal.NO_ERROR) {
13556             return err;
13557         }
13558
13559         synchronized(this) {
13560             r.requestedVrComponent = (enabled) ? packageName : null;
13561
13562             // Update associated state if this activity is currently focused
13563             if (r == mStackSupervisor.getResumedActivityLocked()) {
13564                 applyUpdateVrModeLocked(r);
13565             }
13566             return 0;
13567         }
13568     }
13569
13570     @Override
13571     public boolean isVrModePackageEnabled(ComponentName packageName) {
13572         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13573             throw new UnsupportedOperationException("VR mode not supported on this device!");
13574         }
13575
13576         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13577
13578         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13579                 VrManagerInternal.NO_ERROR;
13580     }
13581
13582     public boolean isTopActivityImmersive() {
13583         enforceNotIsolatedCaller("startActivity");
13584         synchronized (this) {
13585             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13586             return (r != null) ? r.immersive : false;
13587         }
13588     }
13589
13590     /**
13591      * @return whether the system should disable UI modes incompatible with VR mode.
13592      */
13593     boolean shouldDisableNonVrUiLocked() {
13594         return mVrController.shouldDisableNonVrUiLocked();
13595     }
13596
13597     @Override
13598     public boolean isTopOfTask(IBinder token) {
13599         synchronized (this) {
13600             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13601             if (r == null) {
13602                 throw new IllegalArgumentException();
13603             }
13604             return r.getTask().getTopActivity() == r;
13605         }
13606     }
13607
13608     @Override
13609     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13610         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13611             String msg = "Permission Denial: setHasTopUi() from pid="
13612                     + Binder.getCallingPid()
13613                     + ", uid=" + Binder.getCallingUid()
13614                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13615             Slog.w(TAG, msg);
13616             throw new SecurityException(msg);
13617         }
13618         final int pid = Binder.getCallingPid();
13619         final long origId = Binder.clearCallingIdentity();
13620         try {
13621             synchronized (this) {
13622                 boolean changed = false;
13623                 ProcessRecord pr;
13624                 synchronized (mPidsSelfLocked) {
13625                     pr = mPidsSelfLocked.get(pid);
13626                     if (pr == null) {
13627                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13628                         return;
13629                     }
13630                     if (pr.hasTopUi != hasTopUi) {
13631                         if (DEBUG_OOM_ADJ) {
13632                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13633                         }
13634                         pr.hasTopUi = hasTopUi;
13635                         changed = true;
13636                     }
13637                 }
13638                 if (changed) {
13639                     updateOomAdjLocked(pr, true);
13640                 }
13641             }
13642         } finally {
13643             Binder.restoreCallingIdentity(origId);
13644         }
13645     }
13646
13647     public final void enterSafeMode() {
13648         synchronized(this) {
13649             // It only makes sense to do this before the system is ready
13650             // and started launching other packages.
13651             if (!mSystemReady) {
13652                 try {
13653                     AppGlobals.getPackageManager().enterSafeMode();
13654                 } catch (RemoteException e) {
13655                 }
13656             }
13657
13658             mSafeMode = true;
13659         }
13660     }
13661
13662     public final void showSafeModeOverlay() {
13663         View v = LayoutInflater.from(mContext).inflate(
13664                 com.android.internal.R.layout.safe_mode, null);
13665         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13666         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13667         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13668         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13669         lp.gravity = Gravity.BOTTOM | Gravity.START;
13670         lp.format = v.getBackground().getOpacity();
13671         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13672                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13673         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13674         ((WindowManager)mContext.getSystemService(
13675                 Context.WINDOW_SERVICE)).addView(v, lp);
13676     }
13677
13678     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13679         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13680             return;
13681         }
13682         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13683         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13684         synchronized (stats) {
13685             if (mBatteryStatsService.isOnBattery()) {
13686                 mBatteryStatsService.enforceCallingPermission();
13687                 int MY_UID = Binder.getCallingUid();
13688                 final int uid;
13689                 if (sender == null) {
13690                     uid = sourceUid;
13691                 } else {
13692                     uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13693                 }
13694                 BatteryStatsImpl.Uid.Pkg pkg =
13695                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13696                             sourcePkg != null ? sourcePkg : rec.key.packageName);
13697                 pkg.noteWakeupAlarmLocked(tag);
13698             }
13699         }
13700     }
13701
13702     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13703         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13704             return;
13705         }
13706         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13707         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13708         synchronized (stats) {
13709             mBatteryStatsService.enforceCallingPermission();
13710             int MY_UID = Binder.getCallingUid();
13711             final int uid;
13712             if (sender == null) {
13713                 uid = sourceUid;
13714             } else {
13715                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13716             }
13717             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13718         }
13719     }
13720
13721     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13722         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13723             return;
13724         }
13725         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13726         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13727         synchronized (stats) {
13728             mBatteryStatsService.enforceCallingPermission();
13729             int MY_UID = Binder.getCallingUid();
13730             final int uid;
13731             if (sender == null) {
13732                 uid = sourceUid;
13733             } else {
13734                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13735             }
13736             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13737         }
13738     }
13739
13740     public boolean killPids(int[] pids, String pReason, boolean secure) {
13741         if (Binder.getCallingUid() != SYSTEM_UID) {
13742             throw new SecurityException("killPids only available to the system");
13743         }
13744         String reason = (pReason == null) ? "Unknown" : pReason;
13745         // XXX Note: don't acquire main activity lock here, because the window
13746         // manager calls in with its locks held.
13747
13748         boolean killed = false;
13749         synchronized (mPidsSelfLocked) {
13750             int worstType = 0;
13751             for (int i=0; i<pids.length; i++) {
13752                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13753                 if (proc != null) {
13754                     int type = proc.setAdj;
13755                     if (type > worstType) {
13756                         worstType = type;
13757                     }
13758                 }
13759             }
13760
13761             // If the worst oom_adj is somewhere in the cached proc LRU range,
13762             // then constrain it so we will kill all cached procs.
13763             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13764                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13765                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13766             }
13767
13768             // If this is not a secure call, don't let it kill processes that
13769             // are important.
13770             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13771                 worstType = ProcessList.SERVICE_ADJ;
13772             }
13773
13774             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13775             for (int i=0; i<pids.length; i++) {
13776                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13777                 if (proc == null) {
13778                     continue;
13779                 }
13780                 int adj = proc.setAdj;
13781                 if (adj >= worstType && !proc.killedByAm) {
13782                     proc.kill(reason, true);
13783                     killed = true;
13784                 }
13785             }
13786         }
13787         return killed;
13788     }
13789
13790     @Override
13791     public void killUid(int appId, int userId, String reason) {
13792         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13793         synchronized (this) {
13794             final long identity = Binder.clearCallingIdentity();
13795             try {
13796                 killPackageProcessesLocked(null, appId, userId,
13797                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13798                         reason != null ? reason : "kill uid");
13799             } finally {
13800                 Binder.restoreCallingIdentity(identity);
13801             }
13802         }
13803     }
13804
13805     @Override
13806     public boolean killProcessesBelowForeground(String reason) {
13807         if (Binder.getCallingUid() != SYSTEM_UID) {
13808             throw new SecurityException("killProcessesBelowForeground() only available to system");
13809         }
13810
13811         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13812     }
13813
13814     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13815         if (Binder.getCallingUid() != SYSTEM_UID) {
13816             throw new SecurityException("killProcessesBelowAdj() only available to system");
13817         }
13818
13819         boolean killed = false;
13820         synchronized (mPidsSelfLocked) {
13821             final int size = mPidsSelfLocked.size();
13822             for (int i = 0; i < size; i++) {
13823                 final int pid = mPidsSelfLocked.keyAt(i);
13824                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13825                 if (proc == null) continue;
13826
13827                 final int adj = proc.setAdj;
13828                 if (adj > belowAdj && !proc.killedByAm) {
13829                     proc.kill(reason, true);
13830                     killed = true;
13831                 }
13832             }
13833         }
13834         return killed;
13835     }
13836
13837     @Override
13838     public void hang(final IBinder who, boolean allowRestart) {
13839         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13840                 != PackageManager.PERMISSION_GRANTED) {
13841             throw new SecurityException("Requires permission "
13842                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13843         }
13844
13845         final IBinder.DeathRecipient death = new DeathRecipient() {
13846             @Override
13847             public void binderDied() {
13848                 synchronized (this) {
13849                     notifyAll();
13850                 }
13851             }
13852         };
13853
13854         try {
13855             who.linkToDeath(death, 0);
13856         } catch (RemoteException e) {
13857             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13858             return;
13859         }
13860
13861         synchronized (this) {
13862             Watchdog.getInstance().setAllowRestart(allowRestart);
13863             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13864             synchronized (death) {
13865                 while (who.isBinderAlive()) {
13866                     try {
13867                         death.wait();
13868                     } catch (InterruptedException e) {
13869                     }
13870                 }
13871             }
13872             Watchdog.getInstance().setAllowRestart(true);
13873         }
13874     }
13875
13876     @Override
13877     public void restart() {
13878         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13879                 != PackageManager.PERMISSION_GRANTED) {
13880             throw new SecurityException("Requires permission "
13881                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13882         }
13883
13884         Log.i(TAG, "Sending shutdown broadcast...");
13885
13886         BroadcastReceiver br = new BroadcastReceiver() {
13887             @Override public void onReceive(Context context, Intent intent) {
13888                 // Now the broadcast is done, finish up the low-level shutdown.
13889                 Log.i(TAG, "Shutting down activity manager...");
13890                 shutdown(10000);
13891                 Log.i(TAG, "Shutdown complete, restarting!");
13892                 killProcess(myPid());
13893                 System.exit(10);
13894             }
13895         };
13896
13897         // First send the high-level shut down broadcast.
13898         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13899         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13900         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13901         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13902         mContext.sendOrderedBroadcastAsUser(intent,
13903                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13904         */
13905         br.onReceive(mContext, intent);
13906     }
13907
13908     private long getLowRamTimeSinceIdle(long now) {
13909         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13910     }
13911
13912     @Override
13913     public void performIdleMaintenance() {
13914         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13915                 != PackageManager.PERMISSION_GRANTED) {
13916             throw new SecurityException("Requires permission "
13917                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13918         }
13919
13920         synchronized (this) {
13921             final long now = SystemClock.uptimeMillis();
13922             final long timeSinceLastIdle = now - mLastIdleTime;
13923             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13924             mLastIdleTime = now;
13925             mLowRamTimeSinceLastIdle = 0;
13926             if (mLowRamStartTime != 0) {
13927                 mLowRamStartTime = now;
13928             }
13929
13930             StringBuilder sb = new StringBuilder(128);
13931             sb.append("Idle maintenance over ");
13932             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13933             sb.append(" low RAM for ");
13934             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13935             Slog.i(TAG, sb.toString());
13936
13937             // If at least 1/3 of our time since the last idle period has been spent
13938             // with RAM low, then we want to kill processes.
13939             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13940
13941             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13942                 ProcessRecord proc = mLruProcesses.get(i);
13943                 if (proc.notCachedSinceIdle) {
13944                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13945                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13946                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13947                         if (doKilling && proc.initialIdlePss != 0
13948                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13949                             sb = new StringBuilder(128);
13950                             sb.append("Kill");
13951                             sb.append(proc.processName);
13952                             sb.append(" in idle maint: pss=");
13953                             sb.append(proc.lastPss);
13954                             sb.append(", swapPss=");
13955                             sb.append(proc.lastSwapPss);
13956                             sb.append(", initialPss=");
13957                             sb.append(proc.initialIdlePss);
13958                             sb.append(", period=");
13959                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13960                             sb.append(", lowRamPeriod=");
13961                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13962                             Slog.wtfQuiet(TAG, sb.toString());
13963                             proc.kill("idle maint (pss " + proc.lastPss
13964                                     + " from " + proc.initialIdlePss + ")", true);
13965                         }
13966                     }
13967                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13968                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13969                     proc.notCachedSinceIdle = true;
13970                     proc.initialIdlePss = 0;
13971                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13972                             mTestPssMode, isSleepingLocked(), now);
13973                 }
13974             }
13975
13976             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13977             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13978         }
13979     }
13980
13981     @Override
13982     public void sendIdleJobTrigger() {
13983         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13984                 != PackageManager.PERMISSION_GRANTED) {
13985             throw new SecurityException("Requires permission "
13986                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13987         }
13988
13989         final long ident = Binder.clearCallingIdentity();
13990         try {
13991             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13992                     .setPackage("android")
13993                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13994             broadcastIntent(null, intent, null, null, 0, null, null, null,
13995                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13996         } finally {
13997             Binder.restoreCallingIdentity(ident);
13998         }
13999     }
14000
14001     private void retrieveSettings() {
14002         final ContentResolver resolver = mContext.getContentResolver();
14003         final boolean freeformWindowManagement =
14004                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14005                         || Settings.Global.getInt(
14006                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14007         final boolean supportsPictureInPicture =
14008                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14009
14010         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14011         final boolean supportsSplitScreenMultiWindow =
14012                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14013         final boolean supportsMultiDisplay = mContext.getPackageManager()
14014                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14015         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14016         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14017         final boolean alwaysFinishActivities =
14018                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14019         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14020         final boolean forceResizable = Settings.Global.getInt(
14021                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14022         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14023                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14024         final boolean supportsLeanbackOnly =
14025                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14026
14027         // Transfer any global setting for forcing RTL layout, into a System Property
14028         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14029
14030         final Configuration configuration = new Configuration();
14031         Settings.System.getConfiguration(resolver, configuration);
14032         if (forceRtl) {
14033             // This will take care of setting the correct layout direction flags
14034             configuration.setLayoutDirection(configuration.locale);
14035         }
14036
14037         synchronized (this) {
14038             mDebugApp = mOrigDebugApp = debugApp;
14039             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14040             mAlwaysFinishActivities = alwaysFinishActivities;
14041             mSupportsLeanbackOnly = supportsLeanbackOnly;
14042             mForceResizableActivities = forceResizable;
14043             final boolean multiWindowFormEnabled = freeformWindowManagement
14044                     || supportsSplitScreenMultiWindow
14045                     || supportsPictureInPicture
14046                     || supportsMultiDisplay;
14047             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14048                 mSupportsMultiWindow = true;
14049                 mSupportsFreeformWindowManagement = freeformWindowManagement;
14050                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14051                 mSupportsPictureInPicture = supportsPictureInPicture;
14052                 mSupportsMultiDisplay = supportsMultiDisplay;
14053             } else {
14054                 mSupportsMultiWindow = false;
14055                 mSupportsFreeformWindowManagement = false;
14056                 mSupportsSplitScreenMultiWindow = false;
14057                 mSupportsPictureInPicture = false;
14058                 mSupportsMultiDisplay = false;
14059             }
14060             mWindowManager.setForceResizableTasks(mForceResizableActivities);
14061             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14062             // This happens before any activities are started, so we can change global configuration
14063             // in-place.
14064             updateConfigurationLocked(configuration, null, true);
14065             final Configuration globalConfig = getGlobalConfiguration();
14066             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14067
14068             // Load resources only after the current configuration has been set.
14069             final Resources res = mContext.getResources();
14070             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14071             mThumbnailWidth = res.getDimensionPixelSize(
14072                     com.android.internal.R.dimen.thumbnail_width);
14073             mThumbnailHeight = res.getDimensionPixelSize(
14074                     com.android.internal.R.dimen.thumbnail_height);
14075             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14076                     com.android.internal.R.string.config_appsNotReportingCrashes));
14077             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14078                     com.android.internal.R.bool.config_customUserSwitchUi);
14079             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14080                 mFullscreenThumbnailScale = (float) res
14081                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14082                     (float) globalConfig.screenWidthDp;
14083             } else {
14084                 mFullscreenThumbnailScale = res.getFraction(
14085                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14086             }
14087             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14088         }
14089     }
14090
14091     public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
14092         traceLog.traceBegin("PhaseActivityManagerReady");
14093         synchronized(this) {
14094             if (mSystemReady) {
14095                 // If we're done calling all the receivers, run the next "boot phase" passed in
14096                 // by the SystemServer
14097                 if (goingCallback != null) {
14098                     goingCallback.run();
14099                 }
14100                 return;
14101             }
14102
14103             mLocalDeviceIdleController
14104                     = LocalServices.getService(DeviceIdleController.LocalService.class);
14105             mAssistUtils = new AssistUtils(mContext);
14106             mVrController.onSystemReady();
14107             // Make sure we have the current profile info, since it is needed for security checks.
14108             mUserController.onSystemReady();
14109             mRecentTasks.onSystemReadyLocked();
14110             mAppOpsService.systemReady();
14111             mSystemReady = true;
14112         }
14113
14114         ArrayList<ProcessRecord> procsToKill = null;
14115         synchronized(mPidsSelfLocked) {
14116             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14117                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14118                 if (!isAllowedWhileBooting(proc.info)){
14119                     if (procsToKill == null) {
14120                         procsToKill = new ArrayList<ProcessRecord>();
14121                     }
14122                     procsToKill.add(proc);
14123                 }
14124             }
14125         }
14126
14127         synchronized(this) {
14128             if (procsToKill != null) {
14129                 for (int i=procsToKill.size()-1; i>=0; i--) {
14130                     ProcessRecord proc = procsToKill.get(i);
14131                     Slog.i(TAG, "Removing system update proc: " + proc);
14132                     removeProcessLocked(proc, true, false, "system update done");
14133                 }
14134             }
14135
14136             // Now that we have cleaned up any update processes, we
14137             // are ready to start launching real processes and know that
14138             // we won't trample on them any more.
14139             mProcessesReady = true;
14140         }
14141
14142         Slog.i(TAG, "System now ready");
14143         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14144             SystemClock.uptimeMillis());
14145
14146         synchronized(this) {
14147             // Make sure we have no pre-ready processes sitting around.
14148
14149             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14150                 ResolveInfo ri = mContext.getPackageManager()
14151                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14152                                 STOCK_PM_FLAGS);
14153                 CharSequence errorMsg = null;
14154                 if (ri != null) {
14155                     ActivityInfo ai = ri.activityInfo;
14156                     ApplicationInfo app = ai.applicationInfo;
14157                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14158                         mTopAction = Intent.ACTION_FACTORY_TEST;
14159                         mTopData = null;
14160                         mTopComponent = new ComponentName(app.packageName,
14161                                 ai.name);
14162                     } else {
14163                         errorMsg = mContext.getResources().getText(
14164                                 com.android.internal.R.string.factorytest_not_system);
14165                     }
14166                 } else {
14167                     errorMsg = mContext.getResources().getText(
14168                             com.android.internal.R.string.factorytest_no_action);
14169                 }
14170                 if (errorMsg != null) {
14171                     mTopAction = null;
14172                     mTopData = null;
14173                     mTopComponent = null;
14174                     Message msg = Message.obtain();
14175                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14176                     msg.getData().putCharSequence("msg", errorMsg);
14177                     mUiHandler.sendMessage(msg);
14178                 }
14179             }
14180         }
14181
14182         retrieveSettings();
14183         final int currentUserId;
14184         synchronized (this) {
14185             currentUserId = mUserController.getCurrentUserIdLocked();
14186             readGrantedUriPermissionsLocked();
14187         }
14188
14189         if (goingCallback != null) goingCallback.run();
14190         traceLog.traceBegin("ActivityManagerStartApps");
14191         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14192                 Integer.toString(currentUserId), currentUserId);
14193         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14194                 Integer.toString(currentUserId), currentUserId);
14195         mSystemServiceManager.startUser(currentUserId);
14196
14197         synchronized (this) {
14198             // Only start up encryption-aware persistent apps; once user is
14199             // unlocked we'll come back around and start unaware apps
14200             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14201
14202             // Start up initial activity.
14203             mBooting = true;
14204             // Enable home activity for system user, so that the system can always boot. We don't
14205             // do this when the system user is not setup since the setup wizard should be the one
14206             // to handle home activity in this case.
14207             if (UserManager.isSplitSystemUser() &&
14208                     Settings.Secure.getInt(mContext.getContentResolver(),
14209                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14210                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14211                 try {
14212                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14213                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14214                             UserHandle.USER_SYSTEM);
14215                 } catch (RemoteException e) {
14216                     throw e.rethrowAsRuntimeException();
14217                 }
14218             }
14219             startHomeActivityLocked(currentUserId, "systemReady");
14220
14221             try {
14222                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14223                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14224                             + " data partition or your device will be unstable.");
14225                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14226                 }
14227             } catch (RemoteException e) {
14228             }
14229
14230             if (!Build.isBuildConsistent()) {
14231                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14232                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14233             }
14234
14235             long ident = Binder.clearCallingIdentity();
14236             try {
14237                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14238                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14239                         | Intent.FLAG_RECEIVER_FOREGROUND);
14240                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14241                 broadcastIntentLocked(null, null, intent,
14242                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14243                         null, false, false, MY_PID, SYSTEM_UID,
14244                         currentUserId);
14245                 intent = new Intent(Intent.ACTION_USER_STARTING);
14246                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14247                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14248                 broadcastIntentLocked(null, null, intent,
14249                         null, new IIntentReceiver.Stub() {
14250                             @Override
14251                             public void performReceive(Intent intent, int resultCode, String data,
14252                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14253                                     throws RemoteException {
14254                             }
14255                         }, 0, null, null,
14256                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14257                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14258             } catch (Throwable t) {
14259                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14260             } finally {
14261                 Binder.restoreCallingIdentity(ident);
14262             }
14263             mStackSupervisor.resumeFocusedStackTopActivityLocked();
14264             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14265             traceLog.traceEnd(); // ActivityManagerStartApps
14266             traceLog.traceEnd(); // PhaseActivityManagerReady
14267         }
14268     }
14269
14270     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14271         synchronized (this) {
14272             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14273         }
14274     }
14275
14276     void skipCurrentReceiverLocked(ProcessRecord app) {
14277         for (BroadcastQueue queue : mBroadcastQueues) {
14278             queue.skipCurrentReceiverLocked(app);
14279         }
14280     }
14281
14282     /**
14283      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14284      * The application process will exit immediately after this call returns.
14285      * @param app object of the crashing app, null for the system server
14286      * @param crashInfo describing the exception
14287      */
14288     public void handleApplicationCrash(IBinder app,
14289             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14290         ProcessRecord r = findAppProcess(app, "Crash");
14291         final String processName = app == null ? "system_server"
14292                 : (r == null ? "unknown" : r.processName);
14293
14294         handleApplicationCrashInner("crash", r, processName, crashInfo);
14295     }
14296
14297     /* Native crash reporting uses this inner version because it needs to be somewhat
14298      * decoupled from the AM-managed cleanup lifecycle
14299      */
14300     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14301             ApplicationErrorReport.CrashInfo crashInfo) {
14302         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14303                 UserHandle.getUserId(Binder.getCallingUid()), processName,
14304                 r == null ? -1 : r.info.flags,
14305                 crashInfo.exceptionClassName,
14306                 crashInfo.exceptionMessage,
14307                 crashInfo.throwFileName,
14308                 crashInfo.throwLineNumber);
14309
14310         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14311
14312         mAppErrors.crashApplication(r, crashInfo);
14313     }
14314
14315     public void handleApplicationStrictModeViolation(
14316             IBinder app,
14317             int violationMask,
14318             StrictMode.ViolationInfo info) {
14319         ProcessRecord r = findAppProcess(app, "StrictMode");
14320         if (r == null) {
14321             return;
14322         }
14323
14324         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14325             Integer stackFingerprint = info.hashCode();
14326             boolean logIt = true;
14327             synchronized (mAlreadyLoggedViolatedStacks) {
14328                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14329                     logIt = false;
14330                     // TODO: sub-sample into EventLog for these, with
14331                     // the info.durationMillis?  Then we'd get
14332                     // the relative pain numbers, without logging all
14333                     // the stack traces repeatedly.  We'd want to do
14334                     // likewise in the client code, which also does
14335                     // dup suppression, before the Binder call.
14336                 } else {
14337                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14338                         mAlreadyLoggedViolatedStacks.clear();
14339                     }
14340                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14341                 }
14342             }
14343             if (logIt) {
14344                 logStrictModeViolationToDropBox(r, info);
14345             }
14346         }
14347
14348         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14349             AppErrorResult result = new AppErrorResult();
14350             synchronized (this) {
14351                 final long origId = Binder.clearCallingIdentity();
14352
14353                 Message msg = Message.obtain();
14354                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14355                 HashMap<String, Object> data = new HashMap<String, Object>();
14356                 data.put("result", result);
14357                 data.put("app", r);
14358                 data.put("violationMask", violationMask);
14359                 data.put("info", info);
14360                 msg.obj = data;
14361                 mUiHandler.sendMessage(msg);
14362
14363                 Binder.restoreCallingIdentity(origId);
14364             }
14365             int res = result.get();
14366             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14367         }
14368     }
14369
14370     // Depending on the policy in effect, there could be a bunch of
14371     // these in quick succession so we try to batch these together to
14372     // minimize disk writes, number of dropbox entries, and maximize
14373     // compression, by having more fewer, larger records.
14374     private void logStrictModeViolationToDropBox(
14375             ProcessRecord process,
14376             StrictMode.ViolationInfo info) {
14377         if (info == null) {
14378             return;
14379         }
14380         final boolean isSystemApp = process == null ||
14381                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14382                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14383         final String processName = process == null ? "unknown" : process.processName;
14384         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14385         final DropBoxManager dbox = (DropBoxManager)
14386                 mContext.getSystemService(Context.DROPBOX_SERVICE);
14387
14388         // Exit early if the dropbox isn't configured to accept this report type.
14389         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14390
14391         boolean bufferWasEmpty;
14392         boolean needsFlush;
14393         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14394         synchronized (sb) {
14395             bufferWasEmpty = sb.length() == 0;
14396             appendDropBoxProcessHeaders(process, processName, sb);
14397             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14398             sb.append("System-App: ").append(isSystemApp).append("\n");
14399             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14400             if (info.violationNumThisLoop != 0) {
14401                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14402             }
14403             if (info.numAnimationsRunning != 0) {
14404                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14405             }
14406             if (info.broadcastIntentAction != null) {
14407                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14408             }
14409             if (info.durationMillis != -1) {
14410                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14411             }
14412             if (info.numInstances != -1) {
14413                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14414             }
14415             if (info.tags != null) {
14416                 for (String tag : info.tags) {
14417                     sb.append("Span-Tag: ").append(tag).append("\n");
14418                 }
14419             }
14420             sb.append("\n");
14421             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14422                 sb.append(info.crashInfo.stackTrace);
14423                 sb.append("\n");
14424             }
14425             if (info.message != null) {
14426                 sb.append(info.message);
14427                 sb.append("\n");
14428             }
14429
14430             // Only buffer up to ~64k.  Various logging bits truncate
14431             // things at 128k.
14432             needsFlush = (sb.length() > 64 * 1024);
14433         }
14434
14435         // Flush immediately if the buffer's grown too large, or this
14436         // is a non-system app.  Non-system apps are isolated with a
14437         // different tag & policy and not batched.
14438         //
14439         // Batching is useful during internal testing with
14440         // StrictMode settings turned up high.  Without batching,
14441         // thousands of separate files could be created on boot.
14442         if (!isSystemApp || needsFlush) {
14443             new Thread("Error dump: " + dropboxTag) {
14444                 @Override
14445                 public void run() {
14446                     String report;
14447                     synchronized (sb) {
14448                         report = sb.toString();
14449                         sb.delete(0, sb.length());
14450                         sb.trimToSize();
14451                     }
14452                     if (report.length() != 0) {
14453                         dbox.addText(dropboxTag, report);
14454                     }
14455                 }
14456             }.start();
14457             return;
14458         }
14459
14460         // System app batching:
14461         if (!bufferWasEmpty) {
14462             // An existing dropbox-writing thread is outstanding, so
14463             // we don't need to start it up.  The existing thread will
14464             // catch the buffer appends we just did.
14465             return;
14466         }
14467
14468         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14469         // (After this point, we shouldn't access AMS internal data structures.)
14470         new Thread("Error dump: " + dropboxTag) {
14471             @Override
14472             public void run() {
14473                 // 5 second sleep to let stacks arrive and be batched together
14474                 try {
14475                     Thread.sleep(5000);  // 5 seconds
14476                 } catch (InterruptedException e) {}
14477
14478                 String errorReport;
14479                 synchronized (mStrictModeBuffer) {
14480                     errorReport = mStrictModeBuffer.toString();
14481                     if (errorReport.length() == 0) {
14482                         return;
14483                     }
14484                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14485                     mStrictModeBuffer.trimToSize();
14486                 }
14487                 dbox.addText(dropboxTag, errorReport);
14488             }
14489         }.start();
14490     }
14491
14492     /**
14493      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14494      * @param app object of the crashing app, null for the system server
14495      * @param tag reported by the caller
14496      * @param system whether this wtf is coming from the system
14497      * @param crashInfo describing the context of the error
14498      * @return true if the process should exit immediately (WTF is fatal)
14499      */
14500     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14501             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14502         final int callingUid = Binder.getCallingUid();
14503         final int callingPid = Binder.getCallingPid();
14504
14505         if (system) {
14506             // If this is coming from the system, we could very well have low-level
14507             // system locks held, so we want to do this all asynchronously.  And we
14508             // never want this to become fatal, so there is that too.
14509             mHandler.post(new Runnable() {
14510                 @Override public void run() {
14511                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14512                 }
14513             });
14514             return false;
14515         }
14516
14517         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14518                 crashInfo);
14519
14520         final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14521                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14522         final boolean isSystem = (r == null) || r.persistent;
14523
14524         if (isFatal && !isSystem) {
14525             mAppErrors.crashApplication(r, crashInfo);
14526             return true;
14527         } else {
14528             return false;
14529         }
14530     }
14531
14532     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14533             final ApplicationErrorReport.CrashInfo crashInfo) {
14534         final ProcessRecord r = findAppProcess(app, "WTF");
14535         final String processName = app == null ? "system_server"
14536                 : (r == null ? "unknown" : r.processName);
14537
14538         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14539                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14540
14541         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14542
14543         return r;
14544     }
14545
14546     /**
14547      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14548      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14549      */
14550     private ProcessRecord findAppProcess(IBinder app, String reason) {
14551         if (app == null) {
14552             return null;
14553         }
14554
14555         synchronized (this) {
14556             final int NP = mProcessNames.getMap().size();
14557             for (int ip=0; ip<NP; ip++) {
14558                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14559                 final int NA = apps.size();
14560                 for (int ia=0; ia<NA; ia++) {
14561                     ProcessRecord p = apps.valueAt(ia);
14562                     if (p.thread != null && p.thread.asBinder() == app) {
14563                         return p;
14564                     }
14565                 }
14566             }
14567
14568             Slog.w(TAG, "Can't find mystery application for " + reason
14569                     + " from pid=" + Binder.getCallingPid()
14570                     + " uid=" + Binder.getCallingUid() + ": " + app);
14571             return null;
14572         }
14573     }
14574
14575     /**
14576      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14577      * to append various headers to the dropbox log text.
14578      */
14579     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14580             StringBuilder sb) {
14581         // Watchdog thread ends up invoking this function (with
14582         // a null ProcessRecord) to add the stack file to dropbox.
14583         // Do not acquire a lock on this (am) in such cases, as it
14584         // could cause a potential deadlock, if and when watchdog
14585         // is invoked due to unavailability of lock on am and it
14586         // would prevent watchdog from killing system_server.
14587         if (process == null) {
14588             sb.append("Process: ").append(processName).append("\n");
14589             return;
14590         }
14591         // Note: ProcessRecord 'process' is guarded by the service
14592         // instance.  (notably process.pkgList, which could otherwise change
14593         // concurrently during execution of this method)
14594         synchronized (this) {
14595             sb.append("Process: ").append(processName).append("\n");
14596             sb.append("PID: ").append(process.pid).append("\n");
14597             int flags = process.info.flags;
14598             IPackageManager pm = AppGlobals.getPackageManager();
14599             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14600             for (int ip=0; ip<process.pkgList.size(); ip++) {
14601                 String pkg = process.pkgList.keyAt(ip);
14602                 sb.append("Package: ").append(pkg);
14603                 try {
14604                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14605                     if (pi != null) {
14606                         sb.append(" v").append(pi.versionCode);
14607                         if (pi.versionName != null) {
14608                             sb.append(" (").append(pi.versionName).append(")");
14609                         }
14610                     }
14611                 } catch (RemoteException e) {
14612                     Slog.e(TAG, "Error getting package info: " + pkg, e);
14613                 }
14614                 sb.append("\n");
14615             }
14616         }
14617     }
14618
14619     private static String processClass(ProcessRecord process) {
14620         if (process == null || process.pid == MY_PID) {
14621             return "system_server";
14622         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14623             return "system_app";
14624         } else {
14625             return "data_app";
14626         }
14627     }
14628
14629     private volatile long mWtfClusterStart;
14630     private volatile int mWtfClusterCount;
14631
14632     /**
14633      * Write a description of an error (crash, WTF, ANR) to the drop box.
14634      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14635      * @param process which caused the error, null means the system server
14636      * @param activity which triggered the error, null if unknown
14637      * @param parent activity related to the error, null if unknown
14638      * @param subject line related to the error, null if absent
14639      * @param report in long form describing the error, null if absent
14640      * @param dataFile text file to include in the report, null if none
14641      * @param crashInfo giving an application stack trace, null if absent
14642      */
14643     public void addErrorToDropBox(String eventType,
14644             ProcessRecord process, String processName, ActivityRecord activity,
14645             ActivityRecord parent, String subject,
14646             final String report, final File dataFile,
14647             final ApplicationErrorReport.CrashInfo crashInfo) {
14648         // NOTE -- this must never acquire the ActivityManagerService lock,
14649         // otherwise the watchdog may be prevented from resetting the system.
14650
14651         // Bail early if not published yet
14652         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14653         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14654
14655         // Exit early if the dropbox isn't configured to accept this report type.
14656         final String dropboxTag = processClass(process) + "_" + eventType;
14657         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14658
14659         // Rate-limit how often we're willing to do the heavy lifting below to
14660         // collect and record logs; currently 5 logs per 10 second period.
14661         final long now = SystemClock.elapsedRealtime();
14662         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14663             mWtfClusterStart = now;
14664             mWtfClusterCount = 1;
14665         } else {
14666             if (mWtfClusterCount++ >= 5) return;
14667         }
14668
14669         final StringBuilder sb = new StringBuilder(1024);
14670         appendDropBoxProcessHeaders(process, processName, sb);
14671         if (process != null) {
14672             sb.append("Foreground: ")
14673                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14674                     .append("\n");
14675         }
14676         if (activity != null) {
14677             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14678         }
14679         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14680             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14681         }
14682         if (parent != null && parent != activity) {
14683             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14684         }
14685         if (subject != null) {
14686             sb.append("Subject: ").append(subject).append("\n");
14687         }
14688         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14689         if (Debug.isDebuggerConnected()) {
14690             sb.append("Debugger: Connected\n");
14691         }
14692         sb.append("\n");
14693
14694         // Do the rest in a worker thread to avoid blocking the caller on I/O
14695         // (After this point, we shouldn't access AMS internal data structures.)
14696         Thread worker = new Thread("Error dump: " + dropboxTag) {
14697             @Override
14698             public void run() {
14699                 if (report != null) {
14700                     sb.append(report);
14701                 }
14702
14703                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14704                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14705                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14706                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14707
14708                 if (dataFile != null && maxDataFileSize > 0) {
14709                     try {
14710                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14711                                     "\n\n[[TRUNCATED]]"));
14712                     } catch (IOException e) {
14713                         Slog.e(TAG, "Error reading " + dataFile, e);
14714                     }
14715                 }
14716                 if (crashInfo != null && crashInfo.stackTrace != null) {
14717                     sb.append(crashInfo.stackTrace);
14718                 }
14719
14720                 if (lines > 0) {
14721                     sb.append("\n");
14722
14723                     // Merge several logcat streams, and take the last N lines
14724                     InputStreamReader input = null;
14725                     try {
14726                         java.lang.Process logcat = new ProcessBuilder(
14727                                 "/system/bin/timeout", "-k", "15s", "10s",
14728                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14729                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14730                                         .redirectErrorStream(true).start();
14731
14732                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
14733                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
14734                         input = new InputStreamReader(logcat.getInputStream());
14735
14736                         int num;
14737                         char[] buf = new char[8192];
14738                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14739                     } catch (IOException e) {
14740                         Slog.e(TAG, "Error running logcat", e);
14741                     } finally {
14742                         if (input != null) try { input.close(); } catch (IOException e) {}
14743                     }
14744                 }
14745
14746                 dbox.addText(dropboxTag, sb.toString());
14747             }
14748         };
14749
14750         if (process == null) {
14751             // If process is null, we are being called from some internal code
14752             // and may be about to die -- run this synchronously.
14753             worker.run();
14754         } else {
14755             worker.start();
14756         }
14757     }
14758
14759     @Override
14760     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14761         enforceNotIsolatedCaller("getProcessesInErrorState");
14762         // assume our apps are happy - lazy create the list
14763         List<ActivityManager.ProcessErrorStateInfo> errList = null;
14764
14765         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14766                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14767         int userId = UserHandle.getUserId(Binder.getCallingUid());
14768
14769         synchronized (this) {
14770
14771             // iterate across all processes
14772             for (int i=mLruProcesses.size()-1; i>=0; i--) {
14773                 ProcessRecord app = mLruProcesses.get(i);
14774                 if (!allUsers && app.userId != userId) {
14775                     continue;
14776                 }
14777                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14778                     // This one's in trouble, so we'll generate a report for it
14779                     // crashes are higher priority (in case there's a crash *and* an anr)
14780                     ActivityManager.ProcessErrorStateInfo report = null;
14781                     if (app.crashing) {
14782                         report = app.crashingReport;
14783                     } else if (app.notResponding) {
14784                         report = app.notRespondingReport;
14785                     }
14786
14787                     if (report != null) {
14788                         if (errList == null) {
14789                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14790                         }
14791                         errList.add(report);
14792                     } else {
14793                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
14794                                 " crashing = " + app.crashing +
14795                                 " notResponding = " + app.notResponding);
14796                     }
14797                 }
14798             }
14799         }
14800
14801         return errList;
14802     }
14803
14804     static int procStateToImportance(int procState, int memAdj,
14805             ActivityManager.RunningAppProcessInfo currApp,
14806             int clientTargetSdk) {
14807         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14808                 procState, clientTargetSdk);
14809         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14810             currApp.lru = memAdj;
14811         } else {
14812             currApp.lru = 0;
14813         }
14814         return imp;
14815     }
14816
14817     private void fillInProcMemInfo(ProcessRecord app,
14818             ActivityManager.RunningAppProcessInfo outInfo,
14819             int clientTargetSdk) {
14820         outInfo.pid = app.pid;
14821         outInfo.uid = app.info.uid;
14822         if (mHeavyWeightProcess == app) {
14823             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14824         }
14825         if (app.persistent) {
14826             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14827         }
14828         if (app.activities.size() > 0) {
14829             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14830         }
14831         outInfo.lastTrimLevel = app.trimMemoryLevel;
14832         int adj = app.curAdj;
14833         int procState = app.curProcState;
14834         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14835         outInfo.importanceReasonCode = app.adjTypeCode;
14836         outInfo.processState = app.curProcState;
14837     }
14838
14839     @Override
14840     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14841         enforceNotIsolatedCaller("getRunningAppProcesses");
14842
14843         final int callingUid = Binder.getCallingUid();
14844         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14845
14846         // Lazy instantiation of list
14847         List<ActivityManager.RunningAppProcessInfo> runList = null;
14848         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14849                 callingUid) == PackageManager.PERMISSION_GRANTED;
14850         final int userId = UserHandle.getUserId(callingUid);
14851         final boolean allUids = isGetTasksAllowed(
14852                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14853
14854         synchronized (this) {
14855             // Iterate across all processes
14856             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14857                 ProcessRecord app = mLruProcesses.get(i);
14858                 if ((!allUsers && app.userId != userId)
14859                         || (!allUids && app.uid != callingUid)) {
14860                     continue;
14861                 }
14862                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14863                     // Generate process state info for running application
14864                     ActivityManager.RunningAppProcessInfo currApp =
14865                         new ActivityManager.RunningAppProcessInfo(app.processName,
14866                                 app.pid, app.getPackageList());
14867                     fillInProcMemInfo(app, currApp, clientTargetSdk);
14868                     if (app.adjSource instanceof ProcessRecord) {
14869                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14870                         currApp.importanceReasonImportance =
14871                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14872                                         app.adjSourceProcState);
14873                     } else if (app.adjSource instanceof ActivityRecord) {
14874                         ActivityRecord r = (ActivityRecord)app.adjSource;
14875                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14876                     }
14877                     if (app.adjTarget instanceof ComponentName) {
14878                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14879                     }
14880                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14881                     //        + " lru=" + currApp.lru);
14882                     if (runList == null) {
14883                         runList = new ArrayList<>();
14884                     }
14885                     runList.add(currApp);
14886                 }
14887             }
14888         }
14889         return runList;
14890     }
14891
14892     @Override
14893     public List<ApplicationInfo> getRunningExternalApplications() {
14894         enforceNotIsolatedCaller("getRunningExternalApplications");
14895         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14896         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14897         if (runningApps != null && runningApps.size() > 0) {
14898             Set<String> extList = new HashSet<String>();
14899             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14900                 if (app.pkgList != null) {
14901                     for (String pkg : app.pkgList) {
14902                         extList.add(pkg);
14903                     }
14904                 }
14905             }
14906             IPackageManager pm = AppGlobals.getPackageManager();
14907             for (String pkg : extList) {
14908                 try {
14909                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14910                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14911                         retList.add(info);
14912                     }
14913                 } catch (RemoteException e) {
14914                 }
14915             }
14916         }
14917         return retList;
14918     }
14919
14920     @Override
14921     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14922         enforceNotIsolatedCaller("getMyMemoryState");
14923
14924         final int callingUid = Binder.getCallingUid();
14925         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14926
14927         synchronized (this) {
14928             ProcessRecord proc;
14929             synchronized (mPidsSelfLocked) {
14930                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14931             }
14932             fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14933         }
14934     }
14935
14936     @Override
14937     public int getMemoryTrimLevel() {
14938         enforceNotIsolatedCaller("getMyMemoryState");
14939         synchronized (this) {
14940             return mLastMemoryLevel;
14941         }
14942     }
14943
14944     @Override
14945     public void onShellCommand(FileDescriptor in, FileDescriptor out,
14946             FileDescriptor err, String[] args, ShellCallback callback,
14947             ResultReceiver resultReceiver) {
14948         (new ActivityManagerShellCommand(this, false)).exec(
14949                 this, in, out, err, args, callback, resultReceiver);
14950     }
14951
14952     @Override
14953     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14954         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14955
14956         boolean dumpAll = false;
14957         boolean dumpClient = false;
14958         boolean dumpCheckin = false;
14959         boolean dumpCheckinFormat = false;
14960         boolean dumpVisibleStacksOnly = false;
14961         boolean dumpFocusedStackOnly = false;
14962         String dumpPackage = null;
14963
14964         int opti = 0;
14965         while (opti < args.length) {
14966             String opt = args[opti];
14967             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14968                 break;
14969             }
14970             opti++;
14971             if ("-a".equals(opt)) {
14972                 dumpAll = true;
14973             } else if ("-c".equals(opt)) {
14974                 dumpClient = true;
14975             } else if ("-v".equals(opt)) {
14976                 dumpVisibleStacksOnly = true;
14977             } else if ("-f".equals(opt)) {
14978                 dumpFocusedStackOnly = true;
14979             } else if ("-p".equals(opt)) {
14980                 if (opti < args.length) {
14981                     dumpPackage = args[opti];
14982                     opti++;
14983                 } else {
14984                     pw.println("Error: -p option requires package argument");
14985                     return;
14986                 }
14987                 dumpClient = true;
14988             } else if ("--checkin".equals(opt)) {
14989                 dumpCheckin = dumpCheckinFormat = true;
14990             } else if ("-C".equals(opt)) {
14991                 dumpCheckinFormat = true;
14992             } else if ("-h".equals(opt)) {
14993                 ActivityManagerShellCommand.dumpHelp(pw, true);
14994                 return;
14995             } else {
14996                 pw.println("Unknown argument: " + opt + "; use -h for help");
14997             }
14998         }
14999
15000         long origId = Binder.clearCallingIdentity();
15001         boolean more = false;
15002         // Is the caller requesting to dump a particular piece of data?
15003         if (opti < args.length) {
15004             String cmd = args[opti];
15005             opti++;
15006             if ("activities".equals(cmd) || "a".equals(cmd)) {
15007                 synchronized (this) {
15008                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15009                 }
15010             } else if ("lastanr".equals(cmd)) {
15011                 synchronized (this) {
15012                     dumpLastANRLocked(pw);
15013                 }
15014             } else if ("starter".equals(cmd)) {
15015                 synchronized (this) {
15016                     dumpActivityStarterLocked(pw);
15017                 }
15018             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15019                 synchronized (this) {
15020                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15021                 }
15022             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15023                 String[] newArgs;
15024                 String name;
15025                 if (opti >= args.length) {
15026                     name = null;
15027                     newArgs = EMPTY_STRING_ARRAY;
15028                 } else {
15029                     dumpPackage = args[opti];
15030                     opti++;
15031                     newArgs = new String[args.length - opti];
15032                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15033                             args.length - opti);
15034                 }
15035                 synchronized (this) {
15036                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15037                 }
15038             } else if ("broadcast-stats".equals(cmd)) {
15039                 String[] newArgs;
15040                 String name;
15041                 if (opti >= args.length) {
15042                     name = null;
15043                     newArgs = EMPTY_STRING_ARRAY;
15044                 } else {
15045                     dumpPackage = args[opti];
15046                     opti++;
15047                     newArgs = new String[args.length - opti];
15048                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15049                             args.length - opti);
15050                 }
15051                 synchronized (this) {
15052                     if (dumpCheckinFormat) {
15053                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15054                                 dumpPackage);
15055                     } else {
15056                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15057                     }
15058                 }
15059             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15060                 String[] newArgs;
15061                 String name;
15062                 if (opti >= args.length) {
15063                     name = null;
15064                     newArgs = EMPTY_STRING_ARRAY;
15065                 } else {
15066                     dumpPackage = args[opti];
15067                     opti++;
15068                     newArgs = new String[args.length - opti];
15069                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15070                             args.length - opti);
15071                 }
15072                 synchronized (this) {
15073                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15074                 }
15075             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15076                 String[] newArgs;
15077                 String name;
15078                 if (opti >= args.length) {
15079                     name = null;
15080                     newArgs = EMPTY_STRING_ARRAY;
15081                 } else {
15082                     dumpPackage = args[opti];
15083                     opti++;
15084                     newArgs = new String[args.length - opti];
15085                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15086                             args.length - opti);
15087                 }
15088                 synchronized (this) {
15089                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15090                 }
15091             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15092                 synchronized (this) {
15093                     dumpOomLocked(fd, pw, args, opti, true);
15094                 }
15095             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15096                 synchronized (this) {
15097                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
15098                 }
15099             } else if ("provider".equals(cmd)) {
15100                 String[] newArgs;
15101                 String name;
15102                 if (opti >= args.length) {
15103                     name = null;
15104                     newArgs = EMPTY_STRING_ARRAY;
15105                 } else {
15106                     name = args[opti];
15107                     opti++;
15108                     newArgs = new String[args.length - opti];
15109                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15110                 }
15111                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15112                     pw.println("No providers match: " + name);
15113                     pw.println("Use -h for help.");
15114                 }
15115             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15116                 synchronized (this) {
15117                     dumpProvidersLocked(fd, pw, args, opti, true, null);
15118                 }
15119             } else if ("service".equals(cmd)) {
15120                 String[] newArgs;
15121                 String name;
15122                 if (opti >= args.length) {
15123                     name = null;
15124                     newArgs = EMPTY_STRING_ARRAY;
15125                 } else {
15126                     name = args[opti];
15127                     opti++;
15128                     newArgs = new String[args.length - opti];
15129                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15130                             args.length - opti);
15131                 }
15132                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15133                     pw.println("No services match: " + name);
15134                     pw.println("Use -h for help.");
15135                 }
15136             } else if ("package".equals(cmd)) {
15137                 String[] newArgs;
15138                 if (opti >= args.length) {
15139                     pw.println("package: no package name specified");
15140                     pw.println("Use -h for help.");
15141                 } else {
15142                     dumpPackage = args[opti];
15143                     opti++;
15144                     newArgs = new String[args.length - opti];
15145                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15146                             args.length - opti);
15147                     args = newArgs;
15148                     opti = 0;
15149                     more = true;
15150                 }
15151             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15152                 synchronized (this) {
15153                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15154                 }
15155             } else if ("settings".equals(cmd)) {
15156                 synchronized (this) {
15157                     mConstants.dump(pw);
15158                 }
15159             } else if ("services".equals(cmd) || "s".equals(cmd)) {
15160                 if (dumpClient) {
15161                     ActiveServices.ServiceDumper dumper;
15162                     synchronized (this) {
15163                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15164                                 dumpPackage);
15165                     }
15166                     dumper.dumpWithClient();
15167                 } else {
15168                     synchronized (this) {
15169                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15170                                 dumpPackage).dumpLocked();
15171                     }
15172                 }
15173             } else if ("locks".equals(cmd)) {
15174                 LockGuard.dump(fd, pw, args);
15175             } else {
15176                 // Dumping a single activity?
15177                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15178                         dumpFocusedStackOnly)) {
15179                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15180                     int res = shell.exec(this, null, fd, null, args, null,
15181                             new ResultReceiver(null));
15182                     if (res < 0) {
15183                         pw.println("Bad activity command, or no activities match: " + cmd);
15184                         pw.println("Use -h for help.");
15185                     }
15186                 }
15187             }
15188             if (!more) {
15189                 Binder.restoreCallingIdentity(origId);
15190                 return;
15191             }
15192         }
15193
15194         // No piece of data specified, dump everything.
15195         if (dumpCheckinFormat) {
15196             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15197         } else if (dumpClient) {
15198             ActiveServices.ServiceDumper sdumper;
15199             synchronized (this) {
15200                 mConstants.dump(pw);
15201                 pw.println();
15202                 if (dumpAll) {
15203                     pw.println("-------------------------------------------------------------------------------");
15204                 }
15205                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15206                 pw.println();
15207                 if (dumpAll) {
15208                     pw.println("-------------------------------------------------------------------------------");
15209                 }
15210                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15211                 pw.println();
15212                 if (dumpAll) {
15213                     pw.println("-------------------------------------------------------------------------------");
15214                 }
15215                 if (dumpAll || dumpPackage != null) {
15216                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15217                     pw.println();
15218                     if (dumpAll) {
15219                         pw.println("-------------------------------------------------------------------------------");
15220                     }
15221                 }
15222                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15223                 pw.println();
15224                 if (dumpAll) {
15225                     pw.println("-------------------------------------------------------------------------------");
15226                 }
15227                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15228                 pw.println();
15229                 if (dumpAll) {
15230                     pw.println("-------------------------------------------------------------------------------");
15231                 }
15232                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15233                         dumpPackage);
15234             }
15235             sdumper.dumpWithClient();
15236             pw.println();
15237             synchronized (this) {
15238                 if (dumpAll) {
15239                     pw.println("-------------------------------------------------------------------------------");
15240                 }
15241                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15242                 pw.println();
15243                 if (dumpAll) {
15244                     pw.println("-------------------------------------------------------------------------------");
15245                 }
15246                 dumpLastANRLocked(pw);
15247                 pw.println();
15248                 if (dumpAll) {
15249                     pw.println("-------------------------------------------------------------------------------");
15250                 }
15251                 dumpActivityStarterLocked(pw);
15252                 pw.println();
15253                 if (dumpAll) {
15254                     pw.println("-------------------------------------------------------------------------------");
15255                 }
15256                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15257                 if (mAssociations.size() > 0) {
15258                     pw.println();
15259                     if (dumpAll) {
15260                         pw.println("-------------------------------------------------------------------------------");
15261                     }
15262                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15263                 }
15264                 pw.println();
15265                 if (dumpAll) {
15266                     pw.println("-------------------------------------------------------------------------------");
15267                 }
15268                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15269             }
15270
15271         } else {
15272             synchronized (this) {
15273                 mConstants.dump(pw);
15274                 pw.println();
15275                 if (dumpAll) {
15276                     pw.println("-------------------------------------------------------------------------------");
15277                 }
15278                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15279                 pw.println();
15280                 if (dumpAll) {
15281                     pw.println("-------------------------------------------------------------------------------");
15282                 }
15283                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15284                 pw.println();
15285                 if (dumpAll) {
15286                     pw.println("-------------------------------------------------------------------------------");
15287                 }
15288                 if (dumpAll || dumpPackage != null) {
15289                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15290                     pw.println();
15291                     if (dumpAll) {
15292                         pw.println("-------------------------------------------------------------------------------");
15293                     }
15294                 }
15295                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15296                 pw.println();
15297                 if (dumpAll) {
15298                     pw.println("-------------------------------------------------------------------------------");
15299                 }
15300                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15301                 pw.println();
15302                 if (dumpAll) {
15303                     pw.println("-------------------------------------------------------------------------------");
15304                 }
15305                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15306                         .dumpLocked();
15307                 pw.println();
15308                 if (dumpAll) {
15309                     pw.println("-------------------------------------------------------------------------------");
15310                 }
15311                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15312                 pw.println();
15313                 if (dumpAll) {
15314                     pw.println("-------------------------------------------------------------------------------");
15315                 }
15316                 dumpLastANRLocked(pw);
15317                 pw.println();
15318                 if (dumpAll) {
15319                     pw.println("-------------------------------------------------------------------------------");
15320                 }
15321                 dumpActivityStarterLocked(pw);
15322                 pw.println();
15323                 if (dumpAll) {
15324                     pw.println("-------------------------------------------------------------------------------");
15325                 }
15326                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15327                 if (mAssociations.size() > 0) {
15328                     pw.println();
15329                     if (dumpAll) {
15330                         pw.println("-------------------------------------------------------------------------------");
15331                     }
15332                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15333                 }
15334                 pw.println();
15335                 if (dumpAll) {
15336                     pw.println("-------------------------------------------------------------------------------");
15337                 }
15338                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15339             }
15340         }
15341         Binder.restoreCallingIdentity(origId);
15342     }
15343
15344     private void dumpLastANRLocked(PrintWriter pw) {
15345         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
15346         if (mLastANRState == null) {
15347             pw.println("  <no ANR has occurred since boot>");
15348         } else {
15349             pw.println(mLastANRState);
15350         }
15351     }
15352
15353     private void dumpActivityStarterLocked(PrintWriter pw) {
15354         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)");
15355         mActivityStarter.dump(pw, "");
15356     }
15357
15358     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15359             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15360         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15361                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15362     }
15363
15364     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15365             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15366         pw.println(header);
15367
15368         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15369                 dumpPackage);
15370         boolean needSep = printedAnything;
15371
15372         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15373                 mStackSupervisor.getResumedActivityLocked(),
15374                 dumpPackage, needSep, "  ResumedActivity: ");
15375         if (printed) {
15376             printedAnything = true;
15377             needSep = false;
15378         }
15379
15380         if (dumpPackage == null) {
15381             if (needSep) {
15382                 pw.println();
15383             }
15384             printedAnything = true;
15385             mStackSupervisor.dump(pw, "  ");
15386         }
15387
15388         if (!printedAnything) {
15389             pw.println("  (nothing)");
15390         }
15391     }
15392
15393     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15394             int opti, boolean dumpAll, String dumpPackage) {
15395         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15396
15397         boolean printedAnything = false;
15398
15399         if (mRecentTasks != null && mRecentTasks.size() > 0) {
15400             boolean printedHeader = false;
15401
15402             final int N = mRecentTasks.size();
15403             for (int i=0; i<N; i++) {
15404                 TaskRecord tr = mRecentTasks.get(i);
15405                 if (dumpPackage != null) {
15406                     if (tr.realActivity == null ||
15407                             !dumpPackage.equals(tr.realActivity.getPackageName())) {
15408                         continue;
15409                     }
15410                 }
15411                 if (!printedHeader) {
15412                     pw.println("  Recent tasks:");
15413                     printedHeader = true;
15414                     printedAnything = true;
15415                 }
15416                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15417                         pw.println(tr);
15418                 if (dumpAll) {
15419                     mRecentTasks.get(i).dump(pw, "    ");
15420                 }
15421             }
15422         }
15423
15424         if (!printedAnything) {
15425             pw.println("  (nothing)");
15426         }
15427     }
15428
15429     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15430             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15431         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15432
15433         int dumpUid = 0;
15434         if (dumpPackage != null) {
15435             IPackageManager pm = AppGlobals.getPackageManager();
15436             try {
15437                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15438             } catch (RemoteException e) {
15439             }
15440         }
15441
15442         boolean printedAnything = false;
15443
15444         final long now = SystemClock.uptimeMillis();
15445
15446         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15447             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15448                     = mAssociations.valueAt(i1);
15449             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15450                 SparseArray<ArrayMap<String, Association>> sourceUids
15451                         = targetComponents.valueAt(i2);
15452                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15453                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15454                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15455                         Association ass = sourceProcesses.valueAt(i4);
15456                         if (dumpPackage != null) {
15457                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15458                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15459                                 continue;
15460                             }
15461                         }
15462                         printedAnything = true;
15463                         pw.print("  ");
15464                         pw.print(ass.mTargetProcess);
15465                         pw.print("/");
15466                         UserHandle.formatUid(pw, ass.mTargetUid);
15467                         pw.print(" <- ");
15468                         pw.print(ass.mSourceProcess);
15469                         pw.print("/");
15470                         UserHandle.formatUid(pw, ass.mSourceUid);
15471                         pw.println();
15472                         pw.print("    via ");
15473                         pw.print(ass.mTargetComponent.flattenToShortString());
15474                         pw.println();
15475                         pw.print("    ");
15476                         long dur = ass.mTime;
15477                         if (ass.mNesting > 0) {
15478                             dur += now - ass.mStartTime;
15479                         }
15480                         TimeUtils.formatDuration(dur, pw);
15481                         pw.print(" (");
15482                         pw.print(ass.mCount);
15483                         pw.print(" times)");
15484                         pw.print("  ");
15485                         for (int i=0; i<ass.mStateTimes.length; i++) {
15486                             long amt = ass.mStateTimes[i];
15487                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15488                                 amt += now - ass.mLastStateUptime;
15489                             }
15490                             if (amt != 0) {
15491                                 pw.print(" ");
15492                                 pw.print(ProcessList.makeProcStateString(
15493                                             i + ActivityManager.MIN_PROCESS_STATE));
15494                                 pw.print("=");
15495                                 TimeUtils.formatDuration(amt, pw);
15496                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15497                                     pw.print("*");
15498                                 }
15499                             }
15500                         }
15501                         pw.println();
15502                         if (ass.mNesting > 0) {
15503                             pw.print("    Currently active: ");
15504                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
15505                             pw.println();
15506                         }
15507                     }
15508                 }
15509             }
15510
15511         }
15512
15513         if (!printedAnything) {
15514             pw.println("  (nothing)");
15515         }
15516     }
15517
15518     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15519             String header, boolean needSep) {
15520         boolean printed = false;
15521         int whichAppId = -1;
15522         if (dumpPackage != null) {
15523             try {
15524                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15525                         dumpPackage, 0);
15526                 whichAppId = UserHandle.getAppId(info.uid);
15527             } catch (NameNotFoundException e) {
15528                 e.printStackTrace();
15529             }
15530         }
15531         for (int i=0; i<uids.size(); i++) {
15532             UidRecord uidRec = uids.valueAt(i);
15533             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15534                 continue;
15535             }
15536             if (!printed) {
15537                 printed = true;
15538                 if (needSep) {
15539                     pw.println();
15540                 }
15541                 pw.print("  ");
15542                 pw.println(header);
15543                 needSep = true;
15544             }
15545             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15546             pw.print(": "); pw.println(uidRec);
15547         }
15548         return printed;
15549     }
15550
15551     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15552             int opti, boolean dumpAll, String dumpPackage) {
15553         boolean needSep = false;
15554         boolean printedAnything = false;
15555         int numPers = 0;
15556
15557         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15558
15559         if (dumpAll) {
15560             final int NP = mProcessNames.getMap().size();
15561             for (int ip=0; ip<NP; ip++) {
15562                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15563                 final int NA = procs.size();
15564                 for (int ia=0; ia<NA; ia++) {
15565                     ProcessRecord r = procs.valueAt(ia);
15566                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15567                         continue;
15568                     }
15569                     if (!needSep) {
15570                         pw.println("  All known processes:");
15571                         needSep = true;
15572                         printedAnything = true;
15573                     }
15574                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15575                         pw.print(" UID "); pw.print(procs.keyAt(ia));
15576                         pw.print(" "); pw.println(r);
15577                     r.dump(pw, "    ");
15578                     if (r.persistent) {
15579                         numPers++;
15580                     }
15581                 }
15582             }
15583         }
15584
15585         if (mIsolatedProcesses.size() > 0) {
15586             boolean printed = false;
15587             for (int i=0; i<mIsolatedProcesses.size(); i++) {
15588                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15589                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15590                     continue;
15591                 }
15592                 if (!printed) {
15593                     if (needSep) {
15594                         pw.println();
15595                     }
15596                     pw.println("  Isolated process list (sorted by uid):");
15597                     printedAnything = true;
15598                     printed = true;
15599                     needSep = true;
15600                 }
15601                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15602                 pw.println(r);
15603             }
15604         }
15605
15606         if (mActiveInstrumentation.size() > 0) {
15607             boolean printed = false;
15608             for (int i=0; i<mActiveInstrumentation.size(); i++) {
15609                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15610                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15611                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15612                     continue;
15613                 }
15614                 if (!printed) {
15615                     if (needSep) {
15616                         pw.println();
15617                     }
15618                     pw.println("  Active instrumentation:");
15619                     printedAnything = true;
15620                     printed = true;
15621                     needSep = true;
15622                 }
15623                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15624                 pw.println(ai);
15625                 ai.dump(pw, "      ");
15626             }
15627         }
15628
15629         if (mActiveUids.size() > 0) {
15630             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15631                 printedAnything = needSep = true;
15632             }
15633         }
15634         if (dumpAll) {
15635             if (mValidateUids.size() > 0) {
15636                 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15637                     printedAnything = needSep = true;
15638                 }
15639             }
15640         }
15641
15642         if (mLruProcesses.size() > 0) {
15643             if (needSep) {
15644                 pw.println();
15645             }
15646             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15647                     pw.print(" total, non-act at ");
15648                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15649                     pw.print(", non-svc at ");
15650                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15651                     pw.println("):");
15652             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15653             needSep = true;
15654             printedAnything = true;
15655         }
15656
15657         if (dumpAll || dumpPackage != null) {
15658             synchronized (mPidsSelfLocked) {
15659                 boolean printed = false;
15660                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15661                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
15662                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15663                         continue;
15664                     }
15665                     if (!printed) {
15666                         if (needSep) pw.println();
15667                         needSep = true;
15668                         pw.println("  PID mappings:");
15669                         printed = true;
15670                         printedAnything = true;
15671                     }
15672                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15673                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15674                 }
15675             }
15676         }
15677
15678         if (mImportantProcesses.size() > 0) {
15679             synchronized (mPidsSelfLocked) {
15680                 boolean printed = false;
15681                 for (int i = 0; i< mImportantProcesses.size(); i++) {
15682                     ProcessRecord r = mPidsSelfLocked.get(
15683                             mImportantProcesses.valueAt(i).pid);
15684                     if (dumpPackage != null && (r == null
15685                             || !r.pkgList.containsKey(dumpPackage))) {
15686                         continue;
15687                     }
15688                     if (!printed) {
15689                         if (needSep) pw.println();
15690                         needSep = true;
15691                         pw.println("  Foreground Processes:");
15692                         printed = true;
15693                         printedAnything = true;
15694                     }
15695                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15696                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15697                 }
15698             }
15699         }
15700
15701         if (mPersistentStartingProcesses.size() > 0) {
15702             if (needSep) pw.println();
15703             needSep = true;
15704             printedAnything = true;
15705             pw.println("  Persisent processes that are starting:");
15706             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15707                     "Starting Norm", "Restarting PERS", dumpPackage);
15708         }
15709
15710         if (mRemovedProcesses.size() > 0) {
15711             if (needSep) pw.println();
15712             needSep = true;
15713             printedAnything = true;
15714             pw.println("  Processes that are being removed:");
15715             dumpProcessList(pw, this, mRemovedProcesses, "    ",
15716                     "Removed Norm", "Removed PERS", dumpPackage);
15717         }
15718
15719         if (mProcessesOnHold.size() > 0) {
15720             if (needSep) pw.println();
15721             needSep = true;
15722             printedAnything = true;
15723             pw.println("  Processes that are on old until the system is ready:");
15724             dumpProcessList(pw, this, mProcessesOnHold, "    ",
15725                     "OnHold Norm", "OnHold PERS", dumpPackage);
15726         }
15727
15728         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15729
15730         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15731         if (needSep) {
15732             printedAnything = true;
15733         }
15734
15735         if (dumpPackage == null) {
15736             pw.println();
15737             needSep = false;
15738             mUserController.dump(pw, dumpAll);
15739         }
15740         if (mHomeProcess != null && (dumpPackage == null
15741                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15742             if (needSep) {
15743                 pw.println();
15744                 needSep = false;
15745             }
15746             pw.println("  mHomeProcess: " + mHomeProcess);
15747         }
15748         if (mPreviousProcess != null && (dumpPackage == null
15749                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15750             if (needSep) {
15751                 pw.println();
15752                 needSep = false;
15753             }
15754             pw.println("  mPreviousProcess: " + mPreviousProcess);
15755         }
15756         if (dumpAll) {
15757             StringBuilder sb = new StringBuilder(128);
15758             sb.append("  mPreviousProcessVisibleTime: ");
15759             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15760             pw.println(sb);
15761         }
15762         if (mHeavyWeightProcess != null && (dumpPackage == null
15763                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15764             if (needSep) {
15765                 pw.println();
15766                 needSep = false;
15767             }
15768             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15769         }
15770         if (dumpPackage == null) {
15771             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15772             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15773         }
15774         if (dumpAll) {
15775             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15776             if (mCompatModePackages.getPackages().size() > 0) {
15777                 boolean printed = false;
15778                 for (Map.Entry<String, Integer> entry
15779                         : mCompatModePackages.getPackages().entrySet()) {
15780                     String pkg = entry.getKey();
15781                     int mode = entry.getValue();
15782                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15783                         continue;
15784                     }
15785                     if (!printed) {
15786                         pw.println("  mScreenCompatPackages:");
15787                         printed = true;
15788                     }
15789                     pw.print("    "); pw.print(pkg); pw.print(": ");
15790                             pw.print(mode); pw.println();
15791                 }
15792             }
15793             final int NI = mUidObservers.getRegisteredCallbackCount();
15794             boolean printed = false;
15795             for (int i=0; i<NI; i++) {
15796                 final UidObserverRegistration reg = (UidObserverRegistration)
15797                         mUidObservers.getRegisteredCallbackCookie(i);
15798                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15799                     if (!printed) {
15800                         pw.println("  mUidObservers:");
15801                         printed = true;
15802                     }
15803                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15804                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
15805                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15806                         pw.print(" IDLE");
15807                     }
15808                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15809                         pw.print(" ACT" );
15810                     }
15811                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15812                         pw.print(" GONE");
15813                     }
15814                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15815                         pw.print(" STATE");
15816                         pw.print(" (cut="); pw.print(reg.cutpoint);
15817                         pw.print(")");
15818                     }
15819                     pw.println();
15820                     if (reg.lastProcStates != null) {
15821                         final int NJ = reg.lastProcStates.size();
15822                         for (int j=0; j<NJ; j++) {
15823                             pw.print("      Last ");
15824                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15825                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15826                         }
15827                     }
15828                 }
15829             }
15830             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15831             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15832             if (mPendingTempWhitelist.size() > 0) {
15833                 pw.println("  mPendingTempWhitelist:");
15834                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15835                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15836                     pw.print("    ");
15837                     UserHandle.formatUid(pw, ptw.targetUid);
15838                     pw.print(": ");
15839                     TimeUtils.formatDuration(ptw.duration, pw);
15840                     pw.print(" ");
15841                     pw.println(ptw.tag);
15842                 }
15843             }
15844         }
15845         if (dumpPackage == null) {
15846             pw.println("  mWakefulness="
15847                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
15848             pw.println("  mSleepTokens=" + mSleepTokens);
15849             pw.println("  mSleeping=" + mSleeping);
15850             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15851             if (mRunningVoice != null) {
15852                 pw.println("  mRunningVoice=" + mRunningVoice);
15853                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15854             }
15855         }
15856         pw.println("  mVrController=" + mVrController);
15857         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15858                 || mOrigWaitForDebugger) {
15859             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15860                     || dumpPackage.equals(mOrigDebugApp)) {
15861                 if (needSep) {
15862                     pw.println();
15863                     needSep = false;
15864                 }
15865                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15866                         + " mDebugTransient=" + mDebugTransient
15867                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15868             }
15869         }
15870         if (mCurAppTimeTracker != null) {
15871             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15872         }
15873         if (mMemWatchProcesses.getMap().size() > 0) {
15874             pw.println("  Mem watch processes:");
15875             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15876                     = mMemWatchProcesses.getMap();
15877             for (int i=0; i<procs.size(); i++) {
15878                 final String proc = procs.keyAt(i);
15879                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15880                 for (int j=0; j<uids.size(); j++) {
15881                     if (needSep) {
15882                         pw.println();
15883                         needSep = false;
15884                     }
15885                     StringBuilder sb = new StringBuilder();
15886                     sb.append("    ").append(proc).append('/');
15887                     UserHandle.formatUid(sb, uids.keyAt(j));
15888                     Pair<Long, String> val = uids.valueAt(j);
15889                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15890                     if (val.second != null) {
15891                         sb.append(", report to ").append(val.second);
15892                     }
15893                     pw.println(sb.toString());
15894                 }
15895             }
15896             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15897             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15898             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15899                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15900         }
15901         if (mTrackAllocationApp != null) {
15902             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15903                 if (needSep) {
15904                     pw.println();
15905                     needSep = false;
15906                 }
15907                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15908             }
15909         }
15910         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15911                 || mProfileFd != null) {
15912             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15913                 if (needSep) {
15914                     pw.println();
15915                     needSep = false;
15916                 }
15917                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15918                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15919                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15920                         + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15921                 pw.println("  mProfileType=" + mProfileType);
15922             }
15923         }
15924         if (mNativeDebuggingApp != null) {
15925             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15926                 if (needSep) {
15927                     pw.println();
15928                     needSep = false;
15929                 }
15930                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15931             }
15932         }
15933         if (dumpPackage == null) {
15934             if (mAlwaysFinishActivities) {
15935                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15936             }
15937             if (mController != null) {
15938                 pw.println("  mController=" + mController
15939                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15940             }
15941             if (dumpAll) {
15942                 pw.println("  Total persistent processes: " + numPers);
15943                 pw.println("  mProcessesReady=" + mProcessesReady
15944                         + " mSystemReady=" + mSystemReady
15945                         + " mBooted=" + mBooted
15946                         + " mFactoryTest=" + mFactoryTest);
15947                 pw.println("  mBooting=" + mBooting
15948                         + " mCallFinishBooting=" + mCallFinishBooting
15949                         + " mBootAnimationComplete=" + mBootAnimationComplete);
15950                 pw.print("  mLastPowerCheckRealtime=");
15951                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15952                         pw.println("");
15953                 pw.print("  mLastPowerCheckUptime=");
15954                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15955                         pw.println("");
15956                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15957                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15958                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15959                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15960                         + " (" + mLruProcesses.size() + " total)"
15961                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15962                         + " mNumServiceProcs=" + mNumServiceProcs
15963                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15964                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15965                         + " mLastMemoryLevel=" + mLastMemoryLevel
15966                         + " mLastNumProcesses=" + mLastNumProcesses);
15967                 long now = SystemClock.uptimeMillis();
15968                 pw.print("  mLastIdleTime=");
15969                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
15970                         pw.print(" mLowRamSinceLastIdle=");
15971                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15972                         pw.println();
15973             }
15974         }
15975
15976         if (!printedAnything) {
15977             pw.println("  (nothing)");
15978         }
15979     }
15980
15981     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15982             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15983         if (mProcessesToGc.size() > 0) {
15984             boolean printed = false;
15985             long now = SystemClock.uptimeMillis();
15986             for (int i=0; i<mProcessesToGc.size(); i++) {
15987                 ProcessRecord proc = mProcessesToGc.get(i);
15988                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15989                     continue;
15990                 }
15991                 if (!printed) {
15992                     if (needSep) pw.println();
15993                     needSep = true;
15994                     pw.println("  Processes that are waiting to GC:");
15995                     printed = true;
15996                 }
15997                 pw.print("    Process "); pw.println(proc);
15998                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15999                         pw.print(", last gced=");
16000                         pw.print(now-proc.lastRequestedGc);
16001                         pw.print(" ms ago, last lowMem=");
16002                         pw.print(now-proc.lastLowMemory);
16003                         pw.println(" ms ago");
16004
16005             }
16006         }
16007         return needSep;
16008     }
16009
16010     void printOomLevel(PrintWriter pw, String name, int adj) {
16011         pw.print("    ");
16012         if (adj >= 0) {
16013             pw.print(' ');
16014             if (adj < 10) pw.print(' ');
16015         } else {
16016             if (adj > -10) pw.print(' ');
16017         }
16018         pw.print(adj);
16019         pw.print(": ");
16020         pw.print(name);
16021         pw.print(" (");
16022         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16023         pw.println(")");
16024     }
16025
16026     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16027             int opti, boolean dumpAll) {
16028         boolean needSep = false;
16029
16030         if (mLruProcesses.size() > 0) {
16031             if (needSep) pw.println();
16032             needSep = true;
16033             pw.println("  OOM levels:");
16034             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16035             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16036             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16037             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16038             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16039             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16040             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16041             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16042             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16043             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16044             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16045             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16046             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16047             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16048
16049             if (needSep) pw.println();
16050             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16051                     pw.print(" total, non-act at ");
16052                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16053                     pw.print(", non-svc at ");
16054                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16055                     pw.println("):");
16056             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16057             needSep = true;
16058         }
16059
16060         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16061
16062         pw.println();
16063         pw.println("  mHomeProcess: " + mHomeProcess);
16064         pw.println("  mPreviousProcess: " + mPreviousProcess);
16065         if (mHeavyWeightProcess != null) {
16066             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16067         }
16068
16069         return true;
16070     }
16071
16072     /**
16073      * There are three ways to call this:
16074      *  - no provider specified: dump all the providers
16075      *  - a flattened component name that matched an existing provider was specified as the
16076      *    first arg: dump that one provider
16077      *  - the first arg isn't the flattened component name of an existing provider:
16078      *    dump all providers whose component contains the first arg as a substring
16079      */
16080     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16081             int opti, boolean dumpAll) {
16082         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16083     }
16084
16085     static class ItemMatcher {
16086         ArrayList<ComponentName> components;
16087         ArrayList<String> strings;
16088         ArrayList<Integer> objects;
16089         boolean all;
16090
16091         ItemMatcher() {
16092             all = true;
16093         }
16094
16095         void build(String name) {
16096             ComponentName componentName = ComponentName.unflattenFromString(name);
16097             if (componentName != null) {
16098                 if (components == null) {
16099                     components = new ArrayList<ComponentName>();
16100                 }
16101                 components.add(componentName);
16102                 all = false;
16103             } else {
16104                 int objectId = 0;
16105                 // Not a '/' separated full component name; maybe an object ID?
16106                 try {
16107                     objectId = Integer.parseInt(name, 16);
16108                     if (objects == null) {
16109                         objects = new ArrayList<Integer>();
16110                     }
16111                     objects.add(objectId);
16112                     all = false;
16113                 } catch (RuntimeException e) {
16114                     // Not an integer; just do string match.
16115                     if (strings == null) {
16116                         strings = new ArrayList<String>();
16117                     }
16118                     strings.add(name);
16119                     all = false;
16120                 }
16121             }
16122         }
16123
16124         int build(String[] args, int opti) {
16125             for (; opti<args.length; opti++) {
16126                 String name = args[opti];
16127                 if ("--".equals(name)) {
16128                     return opti+1;
16129                 }
16130                 build(name);
16131             }
16132             return opti;
16133         }
16134
16135         boolean match(Object object, ComponentName comp) {
16136             if (all) {
16137                 return true;
16138             }
16139             if (components != null) {
16140                 for (int i=0; i<components.size(); i++) {
16141                     if (components.get(i).equals(comp)) {
16142                         return true;
16143                     }
16144                 }
16145             }
16146             if (objects != null) {
16147                 for (int i=0; i<objects.size(); i++) {
16148                     if (System.identityHashCode(object) == objects.get(i)) {
16149                         return true;
16150                     }
16151                 }
16152             }
16153             if (strings != null) {
16154                 String flat = comp.flattenToString();
16155                 for (int i=0; i<strings.size(); i++) {
16156                     if (flat.contains(strings.get(i))) {
16157                         return true;
16158                     }
16159                 }
16160             }
16161             return false;
16162         }
16163     }
16164
16165     /**
16166      * There are three things that cmd can be:
16167      *  - a flattened component name that matches an existing activity
16168      *  - the cmd arg isn't the flattened component name of an existing activity:
16169      *    dump all activity whose component contains the cmd as a substring
16170      *  - A hex number of the ActivityRecord object instance.
16171      *
16172      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16173      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16174      */
16175     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16176             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16177         ArrayList<ActivityRecord> activities;
16178
16179         synchronized (this) {
16180             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16181                     dumpFocusedStackOnly);
16182         }
16183
16184         if (activities.size() <= 0) {
16185             return false;
16186         }
16187
16188         String[] newArgs = new String[args.length - opti];
16189         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16190
16191         TaskRecord lastTask = null;
16192         boolean needSep = false;
16193         for (int i=activities.size()-1; i>=0; i--) {
16194             ActivityRecord r = activities.get(i);
16195             if (needSep) {
16196                 pw.println();
16197             }
16198             needSep = true;
16199             synchronized (this) {
16200                 final TaskRecord task = r.getTask();
16201                 if (lastTask != task) {
16202                     lastTask = task;
16203                     pw.print("TASK "); pw.print(lastTask.affinity);
16204                             pw.print(" id="); pw.print(lastTask.taskId);
16205                             pw.print(" userId="); pw.println(lastTask.userId);
16206                     if (dumpAll) {
16207                         lastTask.dump(pw, "  ");
16208                     }
16209                 }
16210             }
16211             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16212         }
16213         return true;
16214     }
16215
16216     /**
16217      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16218      * there is a thread associated with the activity.
16219      */
16220     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16221             final ActivityRecord r, String[] args, boolean dumpAll) {
16222         String innerPrefix = prefix + "  ";
16223         synchronized (this) {
16224             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16225                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16226                     pw.print(" pid=");
16227                     if (r.app != null) pw.println(r.app.pid);
16228                     else pw.println("(not running)");
16229             if (dumpAll) {
16230                 r.dump(pw, innerPrefix);
16231             }
16232         }
16233         if (r.app != null && r.app.thread != null) {
16234             // flush anything that is already in the PrintWriter since the thread is going
16235             // to write to the file descriptor directly
16236             pw.flush();
16237             try {
16238                 TransferPipe tp = new TransferPipe();
16239                 try {
16240                     r.app.thread.dumpActivity(tp.getWriteFd(),
16241                             r.appToken, innerPrefix, args);
16242                     tp.go(fd);
16243                 } finally {
16244                     tp.kill();
16245                 }
16246             } catch (IOException e) {
16247                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16248             } catch (RemoteException e) {
16249                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16250             }
16251         }
16252     }
16253
16254     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16255             int opti, boolean dumpAll, String dumpPackage) {
16256         boolean needSep = false;
16257         boolean onlyHistory = false;
16258         boolean printedAnything = false;
16259
16260         if ("history".equals(dumpPackage)) {
16261             if (opti < args.length && "-s".equals(args[opti])) {
16262                 dumpAll = false;
16263             }
16264             onlyHistory = true;
16265             dumpPackage = null;
16266         }
16267
16268         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16269         if (!onlyHistory && dumpAll) {
16270             if (mRegisteredReceivers.size() > 0) {
16271                 boolean printed = false;
16272                 Iterator it = mRegisteredReceivers.values().iterator();
16273                 while (it.hasNext()) {
16274                     ReceiverList r = (ReceiverList)it.next();
16275                     if (dumpPackage != null && (r.app == null ||
16276                             !dumpPackage.equals(r.app.info.packageName))) {
16277                         continue;
16278                     }
16279                     if (!printed) {
16280                         pw.println("  Registered Receivers:");
16281                         needSep = true;
16282                         printed = true;
16283                         printedAnything = true;
16284                     }
16285                     pw.print("  * "); pw.println(r);
16286                     r.dump(pw, "    ");
16287                 }
16288             }
16289
16290             if (mReceiverResolver.dump(pw, needSep ?
16291                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16292                     "    ", dumpPackage, false, false)) {
16293                 needSep = true;
16294                 printedAnything = true;
16295             }
16296         }
16297
16298         for (BroadcastQueue q : mBroadcastQueues) {
16299             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16300             printedAnything |= needSep;
16301         }
16302
16303         needSep = true;
16304
16305         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16306             for (int user=0; user<mStickyBroadcasts.size(); user++) {
16307                 if (needSep) {
16308                     pw.println();
16309                 }
16310                 needSep = true;
16311                 printedAnything = true;
16312                 pw.print("  Sticky broadcasts for user ");
16313                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16314                 StringBuilder sb = new StringBuilder(128);
16315                 for (Map.Entry<String, ArrayList<Intent>> ent
16316                         : mStickyBroadcasts.valueAt(user).entrySet()) {
16317                     pw.print("  * Sticky action "); pw.print(ent.getKey());
16318                     if (dumpAll) {
16319                         pw.println(":");
16320                         ArrayList<Intent> intents = ent.getValue();
16321                         final int N = intents.size();
16322                         for (int i=0; i<N; i++) {
16323                             sb.setLength(0);
16324                             sb.append("    Intent: ");
16325                             intents.get(i).toShortString(sb, false, true, false, false);
16326                             pw.println(sb.toString());
16327                             Bundle bundle = intents.get(i).getExtras();
16328                             if (bundle != null) {
16329                                 pw.print("      ");
16330                                 pw.println(bundle.toString());
16331                             }
16332                         }
16333                     } else {
16334                         pw.println("");
16335                     }
16336                 }
16337             }
16338         }
16339
16340         if (!onlyHistory && dumpAll) {
16341             pw.println();
16342             for (BroadcastQueue queue : mBroadcastQueues) {
16343                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16344                         + queue.mBroadcastsScheduled);
16345             }
16346             pw.println("  mHandler:");
16347             mHandler.dump(new PrintWriterPrinter(pw), "    ");
16348             needSep = true;
16349             printedAnything = true;
16350         }
16351
16352         if (!printedAnything) {
16353             pw.println("  (nothing)");
16354         }
16355     }
16356
16357     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16358             int opti, boolean dumpAll, String dumpPackage) {
16359         if (mCurBroadcastStats == null) {
16360             return;
16361         }
16362
16363         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16364         final long now = SystemClock.elapsedRealtime();
16365         if (mLastBroadcastStats != null) {
16366             pw.print("  Last stats (from ");
16367             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16368             pw.print(" to ");
16369             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16370             pw.print(", ");
16371             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16372                     - mLastBroadcastStats.mStartUptime, pw);
16373             pw.println(" uptime):");
16374             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16375                 pw.println("    (nothing)");
16376             }
16377             pw.println();
16378         }
16379         pw.print("  Current stats (from ");
16380         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16381         pw.print(" to now, ");
16382         TimeUtils.formatDuration(SystemClock.uptimeMillis()
16383                 - mCurBroadcastStats.mStartUptime, pw);
16384         pw.println(" uptime):");
16385         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16386             pw.println("    (nothing)");
16387         }
16388     }
16389
16390     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16391             int opti, boolean fullCheckin, String dumpPackage) {
16392         if (mCurBroadcastStats == null) {
16393             return;
16394         }
16395
16396         if (mLastBroadcastStats != null) {
16397             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16398             if (fullCheckin) {
16399                 mLastBroadcastStats = null;
16400                 return;
16401             }
16402         }
16403         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16404         if (fullCheckin) {
16405             mCurBroadcastStats = null;
16406         }
16407     }
16408
16409     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16410             int opti, boolean dumpAll, String dumpPackage) {
16411         boolean needSep;
16412         boolean printedAnything = false;
16413
16414         ItemMatcher matcher = new ItemMatcher();
16415         matcher.build(args, opti);
16416
16417         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16418
16419         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16420         printedAnything |= needSep;
16421
16422         if (mLaunchingProviders.size() > 0) {
16423             boolean printed = false;
16424             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16425                 ContentProviderRecord r = mLaunchingProviders.get(i);
16426                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16427                     continue;
16428                 }
16429                 if (!printed) {
16430                     if (needSep) pw.println();
16431                     needSep = true;
16432                     pw.println("  Launching content providers:");
16433                     printed = true;
16434                     printedAnything = true;
16435                 }
16436                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
16437                         pw.println(r);
16438             }
16439         }
16440
16441         if (!printedAnything) {
16442             pw.println("  (nothing)");
16443         }
16444     }
16445
16446     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16447             int opti, boolean dumpAll, String dumpPackage) {
16448         boolean needSep = false;
16449         boolean printedAnything = false;
16450
16451         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16452
16453         if (mGrantedUriPermissions.size() > 0) {
16454             boolean printed = false;
16455             int dumpUid = -2;
16456             if (dumpPackage != null) {
16457                 try {
16458                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16459                             MATCH_ANY_USER, 0);
16460                 } catch (NameNotFoundException e) {
16461                     dumpUid = -1;
16462                 }
16463             }
16464             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16465                 int uid = mGrantedUriPermissions.keyAt(i);
16466                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16467                     continue;
16468                 }
16469                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16470                 if (!printed) {
16471                     if (needSep) pw.println();
16472                     needSep = true;
16473                     pw.println("  Granted Uri Permissions:");
16474                     printed = true;
16475                     printedAnything = true;
16476                 }
16477                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16478                 for (UriPermission perm : perms.values()) {
16479                     pw.print("    "); pw.println(perm);
16480                     if (dumpAll) {
16481                         perm.dump(pw, "      ");
16482                     }
16483                 }
16484             }
16485         }
16486
16487         if (!printedAnything) {
16488             pw.println("  (nothing)");
16489         }
16490     }
16491
16492     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16493             int opti, boolean dumpAll, String dumpPackage) {
16494         boolean printed = false;
16495
16496         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16497
16498         if (mIntentSenderRecords.size() > 0) {
16499             // Organize these by package name, so they are easier to read.
16500             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16501             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16502             final Iterator<WeakReference<PendingIntentRecord>> it
16503                     = mIntentSenderRecords.values().iterator();
16504             while (it.hasNext()) {
16505                 WeakReference<PendingIntentRecord> ref = it.next();
16506                 PendingIntentRecord rec = ref != null ? ref.get() : null;
16507                 if (rec == null) {
16508                     weakRefs.add(ref);
16509                     continue;
16510                 }
16511                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16512                     continue;
16513                 }
16514                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16515                 if (list == null) {
16516                     list = new ArrayList<>();
16517                     byPackage.put(rec.key.packageName, list);
16518                 }
16519                 list.add(rec);
16520             }
16521             for (int i = 0; i < byPackage.size(); i++) {
16522                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16523                 printed = true;
16524                 pw.print("  * "); pw.print(byPackage.keyAt(i));
16525                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16526                 for (int j = 0; j < intents.size(); j++) {
16527                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16528                     if (dumpAll) {
16529                         intents.get(j).dump(pw, "      ");
16530                     }
16531                 }
16532             }
16533             if (weakRefs.size() > 0) {
16534                 printed = true;
16535                 pw.println("  * WEAK REFS:");
16536                 for (int i = 0; i < weakRefs.size(); i++) {
16537                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16538                 }
16539             }
16540         }
16541
16542         if (!printed) {
16543             pw.println("  (nothing)");
16544         }
16545     }
16546
16547     private static final int dumpProcessList(PrintWriter pw,
16548             ActivityManagerService service, List list,
16549             String prefix, String normalLabel, String persistentLabel,
16550             String dumpPackage) {
16551         int numPers = 0;
16552         final int N = list.size()-1;
16553         for (int i=N; i>=0; i--) {
16554             ProcessRecord r = (ProcessRecord)list.get(i);
16555             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16556                 continue;
16557             }
16558             pw.println(String.format("%s%s #%2d: %s",
16559                     prefix, (r.persistent ? persistentLabel : normalLabel),
16560                     i, r.toString()));
16561             if (r.persistent) {
16562                 numPers++;
16563             }
16564         }
16565         return numPers;
16566     }
16567
16568     private static final boolean dumpProcessOomList(PrintWriter pw,
16569             ActivityManagerService service, List<ProcessRecord> origList,
16570             String prefix, String normalLabel, String persistentLabel,
16571             boolean inclDetails, String dumpPackage) {
16572
16573         ArrayList<Pair<ProcessRecord, Integer>> list
16574                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16575         for (int i=0; i<origList.size(); i++) {
16576             ProcessRecord r = origList.get(i);
16577             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16578                 continue;
16579             }
16580             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16581         }
16582
16583         if (list.size() <= 0) {
16584             return false;
16585         }
16586
16587         Comparator<Pair<ProcessRecord, Integer>> comparator
16588                 = new Comparator<Pair<ProcessRecord, Integer>>() {
16589             @Override
16590             public int compare(Pair<ProcessRecord, Integer> object1,
16591                     Pair<ProcessRecord, Integer> object2) {
16592                 if (object1.first.setAdj != object2.first.setAdj) {
16593                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16594                 }
16595                 if (object1.first.setProcState != object2.first.setProcState) {
16596                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16597                 }
16598                 if (object1.second.intValue() != object2.second.intValue()) {
16599                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16600                 }
16601                 return 0;
16602             }
16603         };
16604
16605         Collections.sort(list, comparator);
16606
16607         final long curRealtime = SystemClock.elapsedRealtime();
16608         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16609         final long curUptime = SystemClock.uptimeMillis();
16610         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16611
16612         for (int i=list.size()-1; i>=0; i--) {
16613             ProcessRecord r = list.get(i).first;
16614             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16615             char schedGroup;
16616             switch (r.setSchedGroup) {
16617                 case ProcessList.SCHED_GROUP_BACKGROUND:
16618                     schedGroup = 'B';
16619                     break;
16620                 case ProcessList.SCHED_GROUP_DEFAULT:
16621                     schedGroup = 'F';
16622                     break;
16623                 case ProcessList.SCHED_GROUP_TOP_APP:
16624                     schedGroup = 'T';
16625                     break;
16626                 default:
16627                     schedGroup = '?';
16628                     break;
16629             }
16630             char foreground;
16631             if (r.foregroundActivities) {
16632                 foreground = 'A';
16633             } else if (r.foregroundServices) {
16634                 foreground = 'S';
16635             } else {
16636                 foreground = ' ';
16637             }
16638             String procState = ProcessList.makeProcStateString(r.curProcState);
16639             pw.print(prefix);
16640             pw.print(r.persistent ? persistentLabel : normalLabel);
16641             pw.print(" #");
16642             int num = (origList.size()-1)-list.get(i).second;
16643             if (num < 10) pw.print(' ');
16644             pw.print(num);
16645             pw.print(": ");
16646             pw.print(oomAdj);
16647             pw.print(' ');
16648             pw.print(schedGroup);
16649             pw.print('/');
16650             pw.print(foreground);
16651             pw.print('/');
16652             pw.print(procState);
16653             pw.print(" trm:");
16654             if (r.trimMemoryLevel < 10) pw.print(' ');
16655             pw.print(r.trimMemoryLevel);
16656             pw.print(' ');
16657             pw.print(r.toShortString());
16658             pw.print(" (");
16659             pw.print(r.adjType);
16660             pw.println(')');
16661             if (r.adjSource != null || r.adjTarget != null) {
16662                 pw.print(prefix);
16663                 pw.print("    ");
16664                 if (r.adjTarget instanceof ComponentName) {
16665                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16666                 } else if (r.adjTarget != null) {
16667                     pw.print(r.adjTarget.toString());
16668                 } else {
16669                     pw.print("{null}");
16670                 }
16671                 pw.print("<=");
16672                 if (r.adjSource instanceof ProcessRecord) {
16673                     pw.print("Proc{");
16674                     pw.print(((ProcessRecord)r.adjSource).toShortString());
16675                     pw.println("}");
16676                 } else if (r.adjSource != null) {
16677                     pw.println(r.adjSource.toString());
16678                 } else {
16679                     pw.println("{null}");
16680                 }
16681             }
16682             if (inclDetails) {
16683                 pw.print(prefix);
16684                 pw.print("    ");
16685                 pw.print("oom: max="); pw.print(r.maxAdj);
16686                 pw.print(" curRaw="); pw.print(r.curRawAdj);
16687                 pw.print(" setRaw="); pw.print(r.setRawAdj);
16688                 pw.print(" cur="); pw.print(r.curAdj);
16689                 pw.print(" set="); pw.println(r.setAdj);
16690                 pw.print(prefix);
16691                 pw.print("    ");
16692                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16693                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16694                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16695                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16696                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16697                 pw.println();
16698                 pw.print(prefix);
16699                 pw.print("    ");
16700                 pw.print("cached="); pw.print(r.cached);
16701                 pw.print(" empty="); pw.print(r.empty);
16702                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16703
16704                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16705                     if (r.lastWakeTime != 0) {
16706                         long wtime;
16707                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16708                         synchronized (stats) {
16709                             wtime = stats.getProcessWakeTime(r.info.uid,
16710                                     r.pid, curRealtime);
16711                         }
16712                         long timeUsed = wtime - r.lastWakeTime;
16713                         pw.print(prefix);
16714                         pw.print("    ");
16715                         pw.print("keep awake over ");
16716                         TimeUtils.formatDuration(realtimeSince, pw);
16717                         pw.print(" used ");
16718                         TimeUtils.formatDuration(timeUsed, pw);
16719                         pw.print(" (");
16720                         pw.print((timeUsed*100)/realtimeSince);
16721                         pw.println("%)");
16722                     }
16723                     if (r.lastCpuTime != 0) {
16724                         long timeUsed = r.curCpuTime - r.lastCpuTime;
16725                         pw.print(prefix);
16726                         pw.print("    ");
16727                         pw.print("run cpu over ");
16728                         TimeUtils.formatDuration(uptimeSince, pw);
16729                         pw.print(" used ");
16730                         TimeUtils.formatDuration(timeUsed, pw);
16731                         pw.print(" (");
16732                         pw.print((timeUsed*100)/uptimeSince);
16733                         pw.println("%)");
16734                     }
16735                 }
16736             }
16737         }
16738         return true;
16739     }
16740
16741     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16742             String[] args) {
16743         ArrayList<ProcessRecord> procs;
16744         synchronized (this) {
16745             if (args != null && args.length > start
16746                     && args[start].charAt(0) != '-') {
16747                 procs = new ArrayList<ProcessRecord>();
16748                 int pid = -1;
16749                 try {
16750                     pid = Integer.parseInt(args[start]);
16751                 } catch (NumberFormatException e) {
16752                 }
16753                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16754                     ProcessRecord proc = mLruProcesses.get(i);
16755                     if (proc.pid == pid) {
16756                         procs.add(proc);
16757                     } else if (allPkgs && proc.pkgList != null
16758                             && proc.pkgList.containsKey(args[start])) {
16759                         procs.add(proc);
16760                     } else if (proc.processName.equals(args[start])) {
16761                         procs.add(proc);
16762                     }
16763                 }
16764                 if (procs.size() <= 0) {
16765                     return null;
16766                 }
16767             } else {
16768                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16769             }
16770         }
16771         return procs;
16772     }
16773
16774     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16775             PrintWriter pw, String[] args) {
16776         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16777         if (procs == null) {
16778             pw.println("No process found for: " + args[0]);
16779             return;
16780         }
16781
16782         long uptime = SystemClock.uptimeMillis();
16783         long realtime = SystemClock.elapsedRealtime();
16784         pw.println("Applications Graphics Acceleration Info:");
16785         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16786
16787         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16788             ProcessRecord r = procs.get(i);
16789             if (r.thread != null) {
16790                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16791                 pw.flush();
16792                 try {
16793                     TransferPipe tp = new TransferPipe();
16794                     try {
16795                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16796                         tp.go(fd);
16797                     } finally {
16798                         tp.kill();
16799                     }
16800                 } catch (IOException e) {
16801                     pw.println("Failure while dumping the app: " + r);
16802                     pw.flush();
16803                 } catch (RemoteException e) {
16804                     pw.println("Got a RemoteException while dumping the app " + r);
16805                     pw.flush();
16806                 }
16807             }
16808         }
16809     }
16810
16811     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16812         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16813         if (procs == null) {
16814             pw.println("No process found for: " + args[0]);
16815             return;
16816         }
16817
16818         pw.println("Applications Database Info:");
16819
16820         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16821             ProcessRecord r = procs.get(i);
16822             if (r.thread != null) {
16823                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16824                 pw.flush();
16825                 try {
16826                     TransferPipe tp = new TransferPipe();
16827                     try {
16828                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
16829                         tp.go(fd);
16830                     } finally {
16831                         tp.kill();
16832                     }
16833                 } catch (IOException e) {
16834                     pw.println("Failure while dumping the app: " + r);
16835                     pw.flush();
16836                 } catch (RemoteException e) {
16837                     pw.println("Got a RemoteException while dumping the app " + r);
16838                     pw.flush();
16839                 }
16840             }
16841         }
16842     }
16843
16844     final static class MemItem {
16845         final boolean isProc;
16846         final String label;
16847         final String shortLabel;
16848         final long pss;
16849         final long swapPss;
16850         final int id;
16851         final boolean hasActivities;
16852         ArrayList<MemItem> subitems;
16853
16854         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16855                 boolean _hasActivities) {
16856             isProc = true;
16857             label = _label;
16858             shortLabel = _shortLabel;
16859             pss = _pss;
16860             swapPss = _swapPss;
16861             id = _id;
16862             hasActivities = _hasActivities;
16863         }
16864
16865         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16866             isProc = false;
16867             label = _label;
16868             shortLabel = _shortLabel;
16869             pss = _pss;
16870             swapPss = _swapPss;
16871             id = _id;
16872             hasActivities = false;
16873         }
16874     }
16875
16876     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16877             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16878         if (sort && !isCompact) {
16879             Collections.sort(items, new Comparator<MemItem>() {
16880                 @Override
16881                 public int compare(MemItem lhs, MemItem rhs) {
16882                     if (lhs.pss < rhs.pss) {
16883                         return 1;
16884                     } else if (lhs.pss > rhs.pss) {
16885                         return -1;
16886                     }
16887                     return 0;
16888                 }
16889             });
16890         }
16891
16892         for (int i=0; i<items.size(); i++) {
16893             MemItem mi = items.get(i);
16894             if (!isCompact) {
16895                 if (dumpSwapPss) {
16896                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16897                             mi.label, stringifyKBSize(mi.swapPss));
16898                 } else {
16899                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16900                 }
16901             } else if (mi.isProc) {
16902                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16903                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16904                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16905                 pw.println(mi.hasActivities ? ",a" : ",e");
16906             } else {
16907                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16908                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16909             }
16910             if (mi.subitems != null) {
16911                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16912                         true, isCompact, dumpSwapPss);
16913             }
16914         }
16915     }
16916
16917     // These are in KB.
16918     static final long[] DUMP_MEM_BUCKETS = new long[] {
16919         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16920         120*1024, 160*1024, 200*1024,
16921         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16922         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16923     };
16924
16925     static final void appendMemBucket(StringBuilder out, long memKB, String label,
16926             boolean stackLike) {
16927         int start = label.lastIndexOf('.');
16928         if (start >= 0) start++;
16929         else start = 0;
16930         int end = label.length();
16931         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16932             if (DUMP_MEM_BUCKETS[i] >= memKB) {
16933                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16934                 out.append(bucket);
16935                 out.append(stackLike ? "MB." : "MB ");
16936                 out.append(label, start, end);
16937                 return;
16938             }
16939         }
16940         out.append(memKB/1024);
16941         out.append(stackLike ? "MB." : "MB ");
16942         out.append(label, start, end);
16943     }
16944
16945     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16946             ProcessList.NATIVE_ADJ,
16947             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16948             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16949             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16950             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16951             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16952             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16953     };
16954     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16955             "Native",
16956             "System", "Persistent", "Persistent Service", "Foreground",
16957             "Visible", "Perceptible",
16958             "Heavy Weight", "Backup",
16959             "A Services", "Home",
16960             "Previous", "B Services", "Cached"
16961     };
16962     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16963             "native",
16964             "sys", "pers", "persvc", "fore",
16965             "vis", "percept",
16966             "heavy", "backup",
16967             "servicea", "home",
16968             "prev", "serviceb", "cached"
16969     };
16970
16971     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16972             long realtime, boolean isCheckinRequest, boolean isCompact) {
16973         if (isCompact) {
16974             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16975         }
16976         if (isCheckinRequest || isCompact) {
16977             // short checkin version
16978             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16979         } else {
16980             pw.println("Applications Memory Usage (in Kilobytes):");
16981             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16982         }
16983     }
16984
16985     private static final int KSM_SHARED = 0;
16986     private static final int KSM_SHARING = 1;
16987     private static final int KSM_UNSHARED = 2;
16988     private static final int KSM_VOLATILE = 3;
16989
16990     private final long[] getKsmInfo() {
16991         long[] longOut = new long[4];
16992         final int[] SINGLE_LONG_FORMAT = new int[] {
16993             PROC_SPACE_TERM| PROC_OUT_LONG
16994         };
16995         long[] longTmp = new long[1];
16996         readProcFile("/sys/kernel/mm/ksm/pages_shared",
16997                 SINGLE_LONG_FORMAT, null, longTmp, null);
16998         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16999         longTmp[0] = 0;
17000         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17001                 SINGLE_LONG_FORMAT, null, longTmp, null);
17002         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17003         longTmp[0] = 0;
17004         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17005                 SINGLE_LONG_FORMAT, null, longTmp, null);
17006         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17007         longTmp[0] = 0;
17008         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17009                 SINGLE_LONG_FORMAT, null, longTmp, null);
17010         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17011         return longOut;
17012     }
17013
17014     private static String stringifySize(long size, int order) {
17015         Locale locale = Locale.US;
17016         switch (order) {
17017             case 1:
17018                 return String.format(locale, "%,13d", size);
17019             case 1024:
17020                 return String.format(locale, "%,9dK", size / 1024);
17021             case 1024 * 1024:
17022                 return String.format(locale, "%,5dM", size / 1024 / 1024);
17023             case 1024 * 1024 * 1024:
17024                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17025             default:
17026                 throw new IllegalArgumentException("Invalid size order");
17027         }
17028     }
17029
17030     private static String stringifyKBSize(long size) {
17031         return stringifySize(size * 1024, 1024);
17032     }
17033
17034     // Update this version number in case you change the 'compact' format
17035     private static final int MEMINFO_COMPACT_VERSION = 1;
17036
17037     final void dumpApplicationMemoryUsage(FileDescriptor fd,
17038             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17039         boolean dumpDetails = false;
17040         boolean dumpFullDetails = false;
17041         boolean dumpDalvik = false;
17042         boolean dumpSummaryOnly = false;
17043         boolean dumpUnreachable = false;
17044         boolean oomOnly = false;
17045         boolean isCompact = false;
17046         boolean localOnly = false;
17047         boolean packages = false;
17048         boolean isCheckinRequest = false;
17049         boolean dumpSwapPss = false;
17050
17051         int opti = 0;
17052         while (opti < args.length) {
17053             String opt = args[opti];
17054             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17055                 break;
17056             }
17057             opti++;
17058             if ("-a".equals(opt)) {
17059                 dumpDetails = true;
17060                 dumpFullDetails = true;
17061                 dumpDalvik = true;
17062                 dumpSwapPss = true;
17063             } else if ("-d".equals(opt)) {
17064                 dumpDalvik = true;
17065             } else if ("-c".equals(opt)) {
17066                 isCompact = true;
17067             } else if ("-s".equals(opt)) {
17068                 dumpDetails = true;
17069                 dumpSummaryOnly = true;
17070             } else if ("-S".equals(opt)) {
17071                 dumpSwapPss = true;
17072             } else if ("--unreachable".equals(opt)) {
17073                 dumpUnreachable = true;
17074             } else if ("--oom".equals(opt)) {
17075                 oomOnly = true;
17076             } else if ("--local".equals(opt)) {
17077                 localOnly = true;
17078             } else if ("--package".equals(opt)) {
17079                 packages = true;
17080             } else if ("--checkin".equals(opt)) {
17081                 isCheckinRequest = true;
17082
17083             } else if ("-h".equals(opt)) {
17084                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17085                 pw.println("  -a: include all available information for each process.");
17086                 pw.println("  -d: include dalvik details.");
17087                 pw.println("  -c: dump in a compact machine-parseable representation.");
17088                 pw.println("  -s: dump only summary of application memory usage.");
17089                 pw.println("  -S: dump also SwapPss.");
17090                 pw.println("  --oom: only show processes organized by oom adj.");
17091                 pw.println("  --local: only collect details locally, don't call process.");
17092                 pw.println("  --package: interpret process arg as package, dumping all");
17093                 pw.println("             processes that have loaded that package.");
17094                 pw.println("  --checkin: dump data for a checkin");
17095                 pw.println("If [process] is specified it can be the name or ");
17096                 pw.println("pid of a specific process to dump.");
17097                 return;
17098             } else {
17099                 pw.println("Unknown argument: " + opt + "; use -h for help");
17100             }
17101         }
17102
17103         long uptime = SystemClock.uptimeMillis();
17104         long realtime = SystemClock.elapsedRealtime();
17105         final long[] tmpLong = new long[1];
17106
17107         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17108         if (procs == null) {
17109             // No Java processes.  Maybe they want to print a native process.
17110             if (args != null && args.length > opti
17111                     && args[opti].charAt(0) != '-') {
17112                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17113                         = new ArrayList<ProcessCpuTracker.Stats>();
17114                 updateCpuStatsNow();
17115                 int findPid = -1;
17116                 try {
17117                     findPid = Integer.parseInt(args[opti]);
17118                 } catch (NumberFormatException e) {
17119                 }
17120                 synchronized (mProcessCpuTracker) {
17121                     final int N = mProcessCpuTracker.countStats();
17122                     for (int i=0; i<N; i++) {
17123                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17124                         if (st.pid == findPid || (st.baseName != null
17125                                 && st.baseName.equals(args[opti]))) {
17126                             nativeProcs.add(st);
17127                         }
17128                     }
17129                 }
17130                 if (nativeProcs.size() > 0) {
17131                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17132                             isCompact);
17133                     Debug.MemoryInfo mi = null;
17134                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17135                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17136                         final int pid = r.pid;
17137                         if (!isCheckinRequest && dumpDetails) {
17138                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17139                         }
17140                         if (mi == null) {
17141                             mi = new Debug.MemoryInfo();
17142                         }
17143                         if (dumpDetails || (!brief && !oomOnly)) {
17144                             Debug.getMemoryInfo(pid, mi);
17145                         } else {
17146                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17147                             mi.dalvikPrivateDirty = (int)tmpLong[0];
17148                         }
17149                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17150                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17151                         if (isCheckinRequest) {
17152                             pw.println();
17153                         }
17154                     }
17155                     return;
17156                 }
17157             }
17158             pw.println("No process found for: " + args[opti]);
17159             return;
17160         }
17161
17162         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17163             dumpDetails = true;
17164         }
17165
17166         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17167
17168         String[] innerArgs = new String[args.length-opti];
17169         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17170
17171         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17172         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17173         long nativePss = 0;
17174         long nativeSwapPss = 0;
17175         long dalvikPss = 0;
17176         long dalvikSwapPss = 0;
17177         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17178                 EmptyArray.LONG;
17179         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17180                 EmptyArray.LONG;
17181         long otherPss = 0;
17182         long otherSwapPss = 0;
17183         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17184         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17185
17186         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17187         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17188         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17189                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17190
17191         long totalPss = 0;
17192         long totalSwapPss = 0;
17193         long cachedPss = 0;
17194         long cachedSwapPss = 0;
17195         boolean hasSwapPss = false;
17196
17197         Debug.MemoryInfo mi = null;
17198         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17199             final ProcessRecord r = procs.get(i);
17200             final IApplicationThread thread;
17201             final int pid;
17202             final int oomAdj;
17203             final boolean hasActivities;
17204             synchronized (this) {
17205                 thread = r.thread;
17206                 pid = r.pid;
17207                 oomAdj = r.getSetAdjWithServices();
17208                 hasActivities = r.activities.size() > 0;
17209             }
17210             if (thread != null) {
17211                 if (!isCheckinRequest && dumpDetails) {
17212                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17213                 }
17214                 if (mi == null) {
17215                     mi = new Debug.MemoryInfo();
17216                 }
17217                 if (dumpDetails || (!brief && !oomOnly)) {
17218                     Debug.getMemoryInfo(pid, mi);
17219                     hasSwapPss = mi.hasSwappedOutPss;
17220                 } else {
17221                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17222                     mi.dalvikPrivateDirty = (int)tmpLong[0];
17223                 }
17224                 if (dumpDetails) {
17225                     if (localOnly) {
17226                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17227                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17228                         if (isCheckinRequest) {
17229                             pw.println();
17230                         }
17231                     } else {
17232                         pw.flush();
17233                         try {
17234                             TransferPipe tp = new TransferPipe();
17235                             try {
17236                                 thread.dumpMemInfo(tp.getWriteFd(),
17237                                         mi, isCheckinRequest, dumpFullDetails,
17238                                         dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17239                                 tp.go(fd);
17240                             } finally {
17241                                 tp.kill();
17242                             }
17243                         } catch (IOException e) {
17244                             if (!isCheckinRequest) {
17245                                 pw.println("Got IoException!");
17246                                 pw.flush();
17247                             }
17248                         } catch (RemoteException e) {
17249                             if (!isCheckinRequest) {
17250                                 pw.println("Got RemoteException!");
17251                                 pw.flush();
17252                             }
17253                         }
17254                     }
17255                 }
17256
17257                 final long myTotalPss = mi.getTotalPss();
17258                 final long myTotalUss = mi.getTotalUss();
17259                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17260
17261                 synchronized (this) {
17262                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17263                         // Record this for posterity if the process has been stable.
17264                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17265                     }
17266                 }
17267
17268                 if (!isCheckinRequest && mi != null) {
17269                     totalPss += myTotalPss;
17270                     totalSwapPss += myTotalSwapPss;
17271                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17272                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17273                             myTotalSwapPss, pid, hasActivities);
17274                     procMems.add(pssItem);
17275                     procMemsMap.put(pid, pssItem);
17276
17277                     nativePss += mi.nativePss;
17278                     nativeSwapPss += mi.nativeSwappedOutPss;
17279                     dalvikPss += mi.dalvikPss;
17280                     dalvikSwapPss += mi.dalvikSwappedOutPss;
17281                     for (int j=0; j<dalvikSubitemPss.length; j++) {
17282                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17283                         dalvikSubitemSwapPss[j] +=
17284                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17285                     }
17286                     otherPss += mi.otherPss;
17287                     otherSwapPss += mi.otherSwappedOutPss;
17288                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17289                         long mem = mi.getOtherPss(j);
17290                         miscPss[j] += mem;
17291                         otherPss -= mem;
17292                         mem = mi.getOtherSwappedOutPss(j);
17293                         miscSwapPss[j] += mem;
17294                         otherSwapPss -= mem;
17295                     }
17296
17297                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17298                         cachedPss += myTotalPss;
17299                         cachedSwapPss += myTotalSwapPss;
17300                     }
17301
17302                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17303                         if (oomIndex == (oomPss.length - 1)
17304                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17305                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17306                             oomPss[oomIndex] += myTotalPss;
17307                             oomSwapPss[oomIndex] += myTotalSwapPss;
17308                             if (oomProcs[oomIndex] == null) {
17309                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
17310                             }
17311                             oomProcs[oomIndex].add(pssItem);
17312                             break;
17313                         }
17314                     }
17315                 }
17316             }
17317         }
17318
17319         long nativeProcTotalPss = 0;
17320
17321         if (!isCheckinRequest && procs.size() > 1 && !packages) {
17322             // If we are showing aggregations, also look for native processes to
17323             // include so that our aggregations are more accurate.
17324             updateCpuStatsNow();
17325             mi = null;
17326             synchronized (mProcessCpuTracker) {
17327                 final int N = mProcessCpuTracker.countStats();
17328                 for (int i=0; i<N; i++) {
17329                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17330                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17331                         if (mi == null) {
17332                             mi = new Debug.MemoryInfo();
17333                         }
17334                         if (!brief && !oomOnly) {
17335                             Debug.getMemoryInfo(st.pid, mi);
17336                         } else {
17337                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17338                             mi.nativePrivateDirty = (int)tmpLong[0];
17339                         }
17340
17341                         final long myTotalPss = mi.getTotalPss();
17342                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17343                         totalPss += myTotalPss;
17344                         nativeProcTotalPss += myTotalPss;
17345
17346                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17347                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17348                         procMems.add(pssItem);
17349
17350                         nativePss += mi.nativePss;
17351                         nativeSwapPss += mi.nativeSwappedOutPss;
17352                         dalvikPss += mi.dalvikPss;
17353                         dalvikSwapPss += mi.dalvikSwappedOutPss;
17354                         for (int j=0; j<dalvikSubitemPss.length; j++) {
17355                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17356                             dalvikSubitemSwapPss[j] +=
17357                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17358                         }
17359                         otherPss += mi.otherPss;
17360                         otherSwapPss += mi.otherSwappedOutPss;
17361                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17362                             long mem = mi.getOtherPss(j);
17363                             miscPss[j] += mem;
17364                             otherPss -= mem;
17365                             mem = mi.getOtherSwappedOutPss(j);
17366                             miscSwapPss[j] += mem;
17367                             otherSwapPss -= mem;
17368                         }
17369                         oomPss[0] += myTotalPss;
17370                         oomSwapPss[0] += myTotalSwapPss;
17371                         if (oomProcs[0] == null) {
17372                             oomProcs[0] = new ArrayList<MemItem>();
17373                         }
17374                         oomProcs[0].add(pssItem);
17375                     }
17376                 }
17377             }
17378
17379             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17380
17381             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17382             final MemItem dalvikItem =
17383                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17384             if (dalvikSubitemPss.length > 0) {
17385                 dalvikItem.subitems = new ArrayList<MemItem>();
17386                 for (int j=0; j<dalvikSubitemPss.length; j++) {
17387                     final String name = Debug.MemoryInfo.getOtherLabel(
17388                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
17389                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17390                                     dalvikSubitemSwapPss[j], j));
17391                 }
17392             }
17393             catMems.add(dalvikItem);
17394             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17395             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17396                 String label = Debug.MemoryInfo.getOtherLabel(j);
17397                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17398             }
17399
17400             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17401             for (int j=0; j<oomPss.length; j++) {
17402                 if (oomPss[j] != 0) {
17403                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17404                             : DUMP_MEM_OOM_LABEL[j];
17405                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17406                             DUMP_MEM_OOM_ADJ[j]);
17407                     item.subitems = oomProcs[j];
17408                     oomMems.add(item);
17409                 }
17410             }
17411
17412             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17413             if (!brief && !oomOnly && !isCompact) {
17414                 pw.println();
17415                 pw.println("Total PSS by process:");
17416                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17417                 pw.println();
17418             }
17419             if (!isCompact) {
17420                 pw.println("Total PSS by OOM adjustment:");
17421             }
17422             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17423             if (!brief && !oomOnly) {
17424                 PrintWriter out = categoryPw != null ? categoryPw : pw;
17425                 if (!isCompact) {
17426                     out.println();
17427                     out.println("Total PSS by category:");
17428                 }
17429                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17430             }
17431             if (!isCompact) {
17432                 pw.println();
17433             }
17434             MemInfoReader memInfo = new MemInfoReader();
17435             memInfo.readMemInfo();
17436             if (nativeProcTotalPss > 0) {
17437                 synchronized (this) {
17438                     final long cachedKb = memInfo.getCachedSizeKb();
17439                     final long freeKb = memInfo.getFreeSizeKb();
17440                     final long zramKb = memInfo.getZramTotalSizeKb();
17441                     final long kernelKb = memInfo.getKernelUsedSizeKb();
17442                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17443                             kernelKb*1024, nativeProcTotalPss*1024);
17444                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17445                             nativeProcTotalPss);
17446                 }
17447             }
17448             if (!brief) {
17449                 if (!isCompact) {
17450                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17451                     pw.print(" (status ");
17452                     switch (mLastMemoryLevel) {
17453                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17454                             pw.println("normal)");
17455                             break;
17456                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17457                             pw.println("moderate)");
17458                             break;
17459                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
17460                             pw.println("low)");
17461                             break;
17462                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17463                             pw.println("critical)");
17464                             break;
17465                         default:
17466                             pw.print(mLastMemoryLevel);
17467                             pw.println(")");
17468                             break;
17469                     }
17470                     pw.print(" Free RAM: ");
17471                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17472                             + memInfo.getFreeSizeKb()));
17473                     pw.print(" (");
17474                     pw.print(stringifyKBSize(cachedPss));
17475                     pw.print(" cached pss + ");
17476                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17477                     pw.print(" cached kernel + ");
17478                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17479                     pw.println(" free)");
17480                 } else {
17481                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17482                     pw.print(cachedPss + memInfo.getCachedSizeKb()
17483                             + memInfo.getFreeSizeKb()); pw.print(",");
17484                     pw.println(totalPss - cachedPss);
17485                 }
17486             }
17487             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17488                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17489                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17490             if (!isCompact) {
17491                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17492                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17493                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17494                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17495                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17496             } else {
17497                 pw.print("lostram,"); pw.println(lostRAM);
17498             }
17499             if (!brief) {
17500                 if (memInfo.getZramTotalSizeKb() != 0) {
17501                     if (!isCompact) {
17502                         pw.print("     ZRAM: ");
17503                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17504                                 pw.print(" physical used for ");
17505                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17506                                         - memInfo.getSwapFreeSizeKb()));
17507                                 pw.print(" in swap (");
17508                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17509                                 pw.println(" total swap)");
17510                     } else {
17511                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17512                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17513                                 pw.println(memInfo.getSwapFreeSizeKb());
17514                     }
17515                 }
17516                 final long[] ksm = getKsmInfo();
17517                 if (!isCompact) {
17518                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17519                             || ksm[KSM_VOLATILE] != 0) {
17520                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17521                                 pw.print(" saved from shared ");
17522                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17523                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17524                                 pw.print(" unshared; ");
17525                                 pw.print(stringifyKBSize(
17526                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
17527                     }
17528                     pw.print("   Tuning: ");
17529                     pw.print(ActivityManager.staticGetMemoryClass());
17530                     pw.print(" (large ");
17531                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17532                     pw.print("), oom ");
17533                     pw.print(stringifySize(
17534                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17535                     pw.print(", restore limit ");
17536                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17537                     if (ActivityManager.isLowRamDeviceStatic()) {
17538                         pw.print(" (low-ram)");
17539                     }
17540                     if (ActivityManager.isHighEndGfx()) {
17541                         pw.print(" (high-end-gfx)");
17542                     }
17543                     pw.println();
17544                 } else {
17545                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17546                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17547                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17548                     pw.print("tuning,");
17549                     pw.print(ActivityManager.staticGetMemoryClass());
17550                     pw.print(',');
17551                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17552                     pw.print(',');
17553                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17554                     if (ActivityManager.isLowRamDeviceStatic()) {
17555                         pw.print(",low-ram");
17556                     }
17557                     if (ActivityManager.isHighEndGfx()) {
17558                         pw.print(",high-end-gfx");
17559                     }
17560                     pw.println();
17561                 }
17562             }
17563         }
17564     }
17565
17566     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17567             long memtrack, String name) {
17568         sb.append("  ");
17569         sb.append(ProcessList.makeOomAdjString(oomAdj));
17570         sb.append(' ');
17571         sb.append(ProcessList.makeProcStateString(procState));
17572         sb.append(' ');
17573         ProcessList.appendRamKb(sb, pss);
17574         sb.append(": ");
17575         sb.append(name);
17576         if (memtrack > 0) {
17577             sb.append(" (");
17578             sb.append(stringifyKBSize(memtrack));
17579             sb.append(" memtrack)");
17580         }
17581     }
17582
17583     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17584         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17585         sb.append(" (pid ");
17586         sb.append(mi.pid);
17587         sb.append(") ");
17588         sb.append(mi.adjType);
17589         sb.append('\n');
17590         if (mi.adjReason != null) {
17591             sb.append("                      ");
17592             sb.append(mi.adjReason);
17593             sb.append('\n');
17594         }
17595     }
17596
17597     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17598         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17599         for (int i=0, N=memInfos.size(); i<N; i++) {
17600             ProcessMemInfo mi = memInfos.get(i);
17601             infoMap.put(mi.pid, mi);
17602         }
17603         updateCpuStatsNow();
17604         long[] memtrackTmp = new long[1];
17605         final List<ProcessCpuTracker.Stats> stats;
17606         // Get a list of Stats that have vsize > 0
17607         synchronized (mProcessCpuTracker) {
17608             stats = mProcessCpuTracker.getStats((st) -> {
17609                 return st.vsize > 0;
17610             });
17611         }
17612         final int statsCount = stats.size();
17613         for (int i = 0; i < statsCount; i++) {
17614             ProcessCpuTracker.Stats st = stats.get(i);
17615             long pss = Debug.getPss(st.pid, null, memtrackTmp);
17616             if (pss > 0) {
17617                 if (infoMap.indexOfKey(st.pid) < 0) {
17618                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17619                             ProcessList.NATIVE_ADJ, -1, "native", null);
17620                     mi.pss = pss;
17621                     mi.memtrack = memtrackTmp[0];
17622                     memInfos.add(mi);
17623                 }
17624             }
17625         }
17626
17627         long totalPss = 0;
17628         long totalMemtrack = 0;
17629         for (int i=0, N=memInfos.size(); i<N; i++) {
17630             ProcessMemInfo mi = memInfos.get(i);
17631             if (mi.pss == 0) {
17632                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17633                 mi.memtrack = memtrackTmp[0];
17634             }
17635             totalPss += mi.pss;
17636             totalMemtrack += mi.memtrack;
17637         }
17638         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17639             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17640                 if (lhs.oomAdj != rhs.oomAdj) {
17641                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17642                 }
17643                 if (lhs.pss != rhs.pss) {
17644                     return lhs.pss < rhs.pss ? 1 : -1;
17645                 }
17646                 return 0;
17647             }
17648         });
17649
17650         StringBuilder tag = new StringBuilder(128);
17651         StringBuilder stack = new StringBuilder(128);
17652         tag.append("Low on memory -- ");
17653         appendMemBucket(tag, totalPss, "total", false);
17654         appendMemBucket(stack, totalPss, "total", true);
17655
17656         StringBuilder fullNativeBuilder = new StringBuilder(1024);
17657         StringBuilder shortNativeBuilder = new StringBuilder(1024);
17658         StringBuilder fullJavaBuilder = new StringBuilder(1024);
17659
17660         boolean firstLine = true;
17661         int lastOomAdj = Integer.MIN_VALUE;
17662         long extraNativeRam = 0;
17663         long extraNativeMemtrack = 0;
17664         long cachedPss = 0;
17665         for (int i=0, N=memInfos.size(); i<N; i++) {
17666             ProcessMemInfo mi = memInfos.get(i);
17667
17668             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17669                 cachedPss += mi.pss;
17670             }
17671
17672             if (mi.oomAdj != ProcessList.NATIVE_ADJ
17673                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
17674                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
17675                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17676                 if (lastOomAdj != mi.oomAdj) {
17677                     lastOomAdj = mi.oomAdj;
17678                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17679                         tag.append(" / ");
17680                     }
17681                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17682                         if (firstLine) {
17683                             stack.append(":");
17684                             firstLine = false;
17685                         }
17686                         stack.append("\n\t at ");
17687                     } else {
17688                         stack.append("$");
17689                     }
17690                 } else {
17691                     tag.append(" ");
17692                     stack.append("$");
17693                 }
17694                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17695                     appendMemBucket(tag, mi.pss, mi.name, false);
17696                 }
17697                 appendMemBucket(stack, mi.pss, mi.name, true);
17698                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17699                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17700                     stack.append("(");
17701                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17702                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17703                             stack.append(DUMP_MEM_OOM_LABEL[k]);
17704                             stack.append(":");
17705                             stack.append(DUMP_MEM_OOM_ADJ[k]);
17706                         }
17707                     }
17708                     stack.append(")");
17709                 }
17710             }
17711
17712             appendMemInfo(fullNativeBuilder, mi);
17713             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17714                 // The short form only has native processes that are >= 512K.
17715                 if (mi.pss >= 512) {
17716                     appendMemInfo(shortNativeBuilder, mi);
17717                 } else {
17718                     extraNativeRam += mi.pss;
17719                     extraNativeMemtrack += mi.memtrack;
17720                 }
17721             } else {
17722                 // Short form has all other details, but if we have collected RAM
17723                 // from smaller native processes let's dump a summary of that.
17724                 if (extraNativeRam > 0) {
17725                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17726                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17727                     shortNativeBuilder.append('\n');
17728                     extraNativeRam = 0;
17729                 }
17730                 appendMemInfo(fullJavaBuilder, mi);
17731             }
17732         }
17733
17734         fullJavaBuilder.append("           ");
17735         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17736         fullJavaBuilder.append(": TOTAL");
17737         if (totalMemtrack > 0) {
17738             fullJavaBuilder.append(" (");
17739             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17740             fullJavaBuilder.append(" memtrack)");
17741         } else {
17742         }
17743         fullJavaBuilder.append("\n");
17744
17745         MemInfoReader memInfo = new MemInfoReader();
17746         memInfo.readMemInfo();
17747         final long[] infos = memInfo.getRawInfo();
17748
17749         StringBuilder memInfoBuilder = new StringBuilder(1024);
17750         Debug.getMemInfo(infos);
17751         memInfoBuilder.append("  MemInfo: ");
17752         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17753         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17754         memInfoBuilder.append(stringifyKBSize(
17755                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17756         memInfoBuilder.append(stringifyKBSize(
17757                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17758         memInfoBuilder.append(stringifyKBSize(
17759                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17760         memInfoBuilder.append("           ");
17761         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17762         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17763         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17764         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17765         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17766             memInfoBuilder.append("  ZRAM: ");
17767             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17768             memInfoBuilder.append(" RAM, ");
17769             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17770             memInfoBuilder.append(" swap total, ");
17771             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17772             memInfoBuilder.append(" swap free\n");
17773         }
17774         final long[] ksm = getKsmInfo();
17775         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17776                 || ksm[KSM_VOLATILE] != 0) {
17777             memInfoBuilder.append("  KSM: ");
17778             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17779             memInfoBuilder.append(" saved from shared ");
17780             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17781             memInfoBuilder.append("\n       ");
17782             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17783             memInfoBuilder.append(" unshared; ");
17784             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17785             memInfoBuilder.append(" volatile\n");
17786         }
17787         memInfoBuilder.append("  Free RAM: ");
17788         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17789                 + memInfo.getFreeSizeKb()));
17790         memInfoBuilder.append("\n");
17791         memInfoBuilder.append("  Used RAM: ");
17792         memInfoBuilder.append(stringifyKBSize(
17793                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17794         memInfoBuilder.append("\n");
17795         memInfoBuilder.append("  Lost RAM: ");
17796         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17797                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17798                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17799         memInfoBuilder.append("\n");
17800         Slog.i(TAG, "Low on memory:");
17801         Slog.i(TAG, shortNativeBuilder.toString());
17802         Slog.i(TAG, fullJavaBuilder.toString());
17803         Slog.i(TAG, memInfoBuilder.toString());
17804
17805         StringBuilder dropBuilder = new StringBuilder(1024);
17806         /*
17807         StringWriter oomSw = new StringWriter();
17808         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17809         StringWriter catSw = new StringWriter();
17810         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17811         String[] emptyArgs = new String[] { };
17812         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17813         oomPw.flush();
17814         String oomString = oomSw.toString();
17815         */
17816         dropBuilder.append("Low on memory:");
17817         dropBuilder.append(stack);
17818         dropBuilder.append('\n');
17819         dropBuilder.append(fullNativeBuilder);
17820         dropBuilder.append(fullJavaBuilder);
17821         dropBuilder.append('\n');
17822         dropBuilder.append(memInfoBuilder);
17823         dropBuilder.append('\n');
17824         /*
17825         dropBuilder.append(oomString);
17826         dropBuilder.append('\n');
17827         */
17828         StringWriter catSw = new StringWriter();
17829         synchronized (ActivityManagerService.this) {
17830             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17831             String[] emptyArgs = new String[] { };
17832             catPw.println();
17833             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17834             catPw.println();
17835             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17836                     false, null).dumpLocked();
17837             catPw.println();
17838             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17839             catPw.flush();
17840         }
17841         dropBuilder.append(catSw.toString());
17842         addErrorToDropBox("lowmem", null, "system_server", null,
17843                 null, tag.toString(), dropBuilder.toString(), null, null);
17844         //Slog.i(TAG, "Sent to dropbox:");
17845         //Slog.i(TAG, dropBuilder.toString());
17846         synchronized (ActivityManagerService.this) {
17847             long now = SystemClock.uptimeMillis();
17848             if (mLastMemUsageReportTime < now) {
17849                 mLastMemUsageReportTime = now;
17850             }
17851         }
17852     }
17853
17854     /**
17855      * Searches array of arguments for the specified string
17856      * @param args array of argument strings
17857      * @param value value to search for
17858      * @return true if the value is contained in the array
17859      */
17860     private static boolean scanArgs(String[] args, String value) {
17861         if (args != null) {
17862             for (String arg : args) {
17863                 if (value.equals(arg)) {
17864                     return true;
17865                 }
17866             }
17867         }
17868         return false;
17869     }
17870
17871     private final boolean removeDyingProviderLocked(ProcessRecord proc,
17872             ContentProviderRecord cpr, boolean always) {
17873         final boolean inLaunching = mLaunchingProviders.contains(cpr);
17874
17875         if (!inLaunching || always) {
17876             synchronized (cpr) {
17877                 cpr.launchingApp = null;
17878                 cpr.notifyAll();
17879             }
17880             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17881             String names[] = cpr.info.authority.split(";");
17882             for (int j = 0; j < names.length; j++) {
17883                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17884             }
17885         }
17886
17887         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17888             ContentProviderConnection conn = cpr.connections.get(i);
17889             if (conn.waiting) {
17890                 // If this connection is waiting for the provider, then we don't
17891                 // need to mess with its process unless we are always removing
17892                 // or for some reason the provider is not currently launching.
17893                 if (inLaunching && !always) {
17894                     continue;
17895                 }
17896             }
17897             ProcessRecord capp = conn.client;
17898             conn.dead = true;
17899             if (conn.stableCount > 0) {
17900                 if (!capp.persistent && capp.thread != null
17901                         && capp.pid != 0
17902                         && capp.pid != MY_PID) {
17903                     capp.kill("depends on provider "
17904                             + cpr.name.flattenToShortString()
17905                             + " in dying proc " + (proc != null ? proc.processName : "??")
17906                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17907                 }
17908             } else if (capp.thread != null && conn.provider.provider != null) {
17909                 try {
17910                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17911                 } catch (RemoteException e) {
17912                 }
17913                 // In the protocol here, we don't expect the client to correctly
17914                 // clean up this connection, we'll just remove it.
17915                 cpr.connections.remove(i);
17916                 if (conn.client.conProviders.remove(conn)) {
17917                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17918                 }
17919             }
17920         }
17921
17922         if (inLaunching && always) {
17923             mLaunchingProviders.remove(cpr);
17924         }
17925         return inLaunching;
17926     }
17927
17928     /**
17929      * Main code for cleaning up a process when it has gone away.  This is
17930      * called both as a result of the process dying, or directly when stopping
17931      * a process when running in single process mode.
17932      *
17933      * @return Returns true if the given process has been restarted, so the
17934      * app that was passed in must remain on the process lists.
17935      */
17936     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17937             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17938         if (index >= 0) {
17939             removeLruProcessLocked(app);
17940             ProcessList.remove(app.pid);
17941         }
17942
17943         mProcessesToGc.remove(app);
17944         mPendingPssProcesses.remove(app);
17945
17946         // Dismiss any open dialogs.
17947         if (app.crashDialog != null && !app.forceCrashReport) {
17948             app.crashDialog.dismiss();
17949             app.crashDialog = null;
17950         }
17951         if (app.anrDialog != null) {
17952             app.anrDialog.dismiss();
17953             app.anrDialog = null;
17954         }
17955         if (app.waitDialog != null) {
17956             app.waitDialog.dismiss();
17957             app.waitDialog = null;
17958         }
17959
17960         app.crashing = false;
17961         app.notResponding = false;
17962
17963         app.resetPackageList(mProcessStats);
17964         app.unlinkDeathRecipient();
17965         app.makeInactive(mProcessStats);
17966         app.waitingToKill = null;
17967         app.forcingToImportant = null;
17968         updateProcessForegroundLocked(app, false, false);
17969         app.foregroundActivities = false;
17970         app.hasShownUi = false;
17971         app.treatLikeActivity = false;
17972         app.hasAboveClient = false;
17973         app.hasClientActivities = false;
17974
17975         mServices.killServicesLocked(app, allowRestart);
17976
17977         boolean restart = false;
17978
17979         // Remove published content providers.
17980         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17981             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17982             final boolean always = app.bad || !allowRestart;
17983             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17984             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17985                 // We left the provider in the launching list, need to
17986                 // restart it.
17987                 restart = true;
17988             }
17989
17990             cpr.provider = null;
17991             cpr.proc = null;
17992         }
17993         app.pubProviders.clear();
17994
17995         // Take care of any launching providers waiting for this process.
17996         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17997             restart = true;
17998         }
17999
18000         // Unregister from connected content providers.
18001         if (!app.conProviders.isEmpty()) {
18002             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18003                 ContentProviderConnection conn = app.conProviders.get(i);
18004                 conn.provider.connections.remove(conn);
18005                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18006                         conn.provider.name);
18007             }
18008             app.conProviders.clear();
18009         }
18010
18011         // At this point there may be remaining entries in mLaunchingProviders
18012         // where we were the only one waiting, so they are no longer of use.
18013         // Look for these and clean up if found.
18014         // XXX Commented out for now.  Trying to figure out a way to reproduce
18015         // the actual situation to identify what is actually going on.
18016         if (false) {
18017             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18018                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18019                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18020                     synchronized (cpr) {
18021                         cpr.launchingApp = null;
18022                         cpr.notifyAll();
18023                     }
18024                 }
18025             }
18026         }
18027
18028         skipCurrentReceiverLocked(app);
18029
18030         // Unregister any receivers.
18031         for (int i = app.receivers.size() - 1; i >= 0; i--) {
18032             removeReceiverLocked(app.receivers.valueAt(i));
18033         }
18034         app.receivers.clear();
18035
18036         // If the app is undergoing backup, tell the backup manager about it
18037         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18038             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18039                     + mBackupTarget.appInfo + " died during backup");
18040             mHandler.post(new Runnable() {
18041                 @Override
18042                 public void run(){
18043                     try {
18044                         IBackupManager bm = IBackupManager.Stub.asInterface(
18045                                 ServiceManager.getService(Context.BACKUP_SERVICE));
18046                         bm.agentDisconnected(app.info.packageName);
18047                     } catch (RemoteException e) {
18048                         // can't happen; backup manager is local
18049                     }
18050                 }
18051             });
18052         }
18053
18054         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18055             ProcessChangeItem item = mPendingProcessChanges.get(i);
18056             if (item.pid == app.pid) {
18057                 mPendingProcessChanges.remove(i);
18058                 mAvailProcessChanges.add(item);
18059             }
18060         }
18061         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18062                 null).sendToTarget();
18063
18064         // If the caller is restarting this app, then leave it in its
18065         // current lists and let the caller take care of it.
18066         if (restarting) {
18067             return false;
18068         }
18069
18070         if (!app.persistent || app.isolated) {
18071             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18072                     "Removing non-persistent process during cleanup: " + app);
18073             if (!replacingPid) {
18074                 removeProcessNameLocked(app.processName, app.uid, app);
18075             }
18076             if (mHeavyWeightProcess == app) {
18077                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18078                         mHeavyWeightProcess.userId, 0));
18079                 mHeavyWeightProcess = null;
18080             }
18081         } else if (!app.removed) {
18082             // This app is persistent, so we need to keep its record around.
18083             // If it is not already on the pending app list, add it there
18084             // and start a new process for it.
18085             if (mPersistentStartingProcesses.indexOf(app) < 0) {
18086                 mPersistentStartingProcesses.add(app);
18087                 restart = true;
18088             }
18089         }
18090         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18091                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18092         mProcessesOnHold.remove(app);
18093
18094         if (app == mHomeProcess) {
18095             mHomeProcess = null;
18096         }
18097         if (app == mPreviousProcess) {
18098             mPreviousProcess = null;
18099         }
18100
18101         if (restart && !app.isolated) {
18102             // We have components that still need to be running in the
18103             // process, so re-launch it.
18104             if (index < 0) {
18105                 ProcessList.remove(app.pid);
18106             }
18107             addProcessNameLocked(app);
18108             startProcessLocked(app, "restart", app.processName);
18109             return true;
18110         } else if (app.pid > 0 && app.pid != MY_PID) {
18111             // Goodbye!
18112             boolean removed;
18113             synchronized (mPidsSelfLocked) {
18114                 mPidsSelfLocked.remove(app.pid);
18115                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18116             }
18117             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18118             if (app.isolated) {
18119                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18120             }
18121             app.setPid(0);
18122         }
18123         return false;
18124     }
18125
18126     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18127         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18128             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18129             if (cpr.launchingApp == app) {
18130                 return true;
18131             }
18132         }
18133         return false;
18134     }
18135
18136     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18137         // Look through the content providers we are waiting to have launched,
18138         // and if any run in this process then either schedule a restart of
18139         // the process or kill the client waiting for it if this process has
18140         // gone bad.
18141         boolean restart = false;
18142         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18143             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18144             if (cpr.launchingApp == app) {
18145                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18146                     restart = true;
18147                 } else {
18148                     removeDyingProviderLocked(app, cpr, true);
18149                 }
18150             }
18151         }
18152         return restart;
18153     }
18154
18155     // =========================================================
18156     // SERVICES
18157     // =========================================================
18158
18159     @Override
18160     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18161             int flags) {
18162         enforceNotIsolatedCaller("getServices");
18163
18164         final int callingUid = Binder.getCallingUid();
18165         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18166             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18167         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18168             callingUid);
18169         synchronized (this) {
18170             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18171                 allowed, canInteractAcrossUsers);
18172         }
18173     }
18174
18175     @Override
18176     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18177         enforceNotIsolatedCaller("getRunningServiceControlPanel");
18178         synchronized (this) {
18179             return mServices.getRunningServiceControlPanelLocked(name);
18180         }
18181     }
18182
18183     @Override
18184     public ComponentName startService(IApplicationThread caller, Intent service,
18185             String resolvedType, boolean requireForeground, String callingPackage, int userId)
18186             throws TransactionTooLargeException {
18187         enforceNotIsolatedCaller("startService");
18188         // Refuse possible leaked file descriptors
18189         if (service != null && service.hasFileDescriptors() == true) {
18190             throw new IllegalArgumentException("File descriptors passed in Intent");
18191         }
18192
18193         if (callingPackage == null) {
18194             throw new IllegalArgumentException("callingPackage cannot be null");
18195         }
18196
18197         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18198                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18199         synchronized(this) {
18200             final int callingPid = Binder.getCallingPid();
18201             final int callingUid = Binder.getCallingUid();
18202             final long origId = Binder.clearCallingIdentity();
18203             ComponentName res;
18204             try {
18205                 res = mServices.startServiceLocked(caller, service,
18206                         resolvedType, callingPid, callingUid,
18207                         requireForeground, callingPackage, userId);
18208             } finally {
18209                 Binder.restoreCallingIdentity(origId);
18210             }
18211             return res;
18212         }
18213     }
18214
18215     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18216             boolean fgRequired, String callingPackage, int userId)
18217             throws TransactionTooLargeException {
18218         synchronized(this) {
18219             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18220                     "startServiceInPackage: " + service + " type=" + resolvedType);
18221             final long origId = Binder.clearCallingIdentity();
18222             ComponentName res;
18223             try {
18224                 res = mServices.startServiceLocked(null, service,
18225                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
18226             } finally {
18227                 Binder.restoreCallingIdentity(origId);
18228             }
18229             return res;
18230         }
18231     }
18232
18233     @Override
18234     public int stopService(IApplicationThread caller, Intent service,
18235             String resolvedType, int userId) {
18236         enforceNotIsolatedCaller("stopService");
18237         // Refuse possible leaked file descriptors
18238         if (service != null && service.hasFileDescriptors() == true) {
18239             throw new IllegalArgumentException("File descriptors passed in Intent");
18240         }
18241
18242         synchronized(this) {
18243             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18244         }
18245     }
18246
18247     @Override
18248     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18249         enforceNotIsolatedCaller("peekService");
18250         // Refuse possible leaked file descriptors
18251         if (service != null && service.hasFileDescriptors() == true) {
18252             throw new IllegalArgumentException("File descriptors passed in Intent");
18253         }
18254
18255         if (callingPackage == null) {
18256             throw new IllegalArgumentException("callingPackage cannot be null");
18257         }
18258
18259         synchronized(this) {
18260             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18261         }
18262     }
18263
18264     @Override
18265     public boolean stopServiceToken(ComponentName className, IBinder token,
18266             int startId) {
18267         synchronized(this) {
18268             return mServices.stopServiceTokenLocked(className, token, startId);
18269         }
18270     }
18271
18272     @Override
18273     public void setServiceForeground(ComponentName className, IBinder token,
18274             int id, Notification notification, int flags) {
18275         synchronized(this) {
18276             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18277         }
18278     }
18279
18280     @Override
18281     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18282             boolean requireFull, String name, String callerPackage) {
18283         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18284                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18285     }
18286
18287     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18288             String className, int flags) {
18289         boolean result = false;
18290         // For apps that don't have pre-defined UIDs, check for permission
18291         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18292             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18293                 if (ActivityManager.checkUidPermission(
18294                         INTERACT_ACROSS_USERS,
18295                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18296                     ComponentName comp = new ComponentName(aInfo.packageName, className);
18297                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
18298                             + " requests FLAG_SINGLE_USER, but app does not hold "
18299                             + INTERACT_ACROSS_USERS;
18300                     Slog.w(TAG, msg);
18301                     throw new SecurityException(msg);
18302                 }
18303                 // Permission passed
18304                 result = true;
18305             }
18306         } else if ("system".equals(componentProcessName)) {
18307             result = true;
18308         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18309             // Phone app and persistent apps are allowed to export singleuser providers.
18310             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18311                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18312         }
18313         if (DEBUG_MU) Slog.v(TAG_MU,
18314                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18315                 + Integer.toHexString(flags) + ") = " + result);
18316         return result;
18317     }
18318
18319     /**
18320      * Checks to see if the caller is in the same app as the singleton
18321      * component, or the component is in a special app. It allows special apps
18322      * to export singleton components but prevents exporting singleton
18323      * components for regular apps.
18324      */
18325     boolean isValidSingletonCall(int callingUid, int componentUid) {
18326         int componentAppId = UserHandle.getAppId(componentUid);
18327         return UserHandle.isSameApp(callingUid, componentUid)
18328                 || componentAppId == SYSTEM_UID
18329                 || componentAppId == PHONE_UID
18330                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18331                         == PackageManager.PERMISSION_GRANTED;
18332     }
18333
18334     public int bindService(IApplicationThread caller, IBinder token, Intent service,
18335             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18336             int userId) throws TransactionTooLargeException {
18337         enforceNotIsolatedCaller("bindService");
18338
18339         // Refuse possible leaked file descriptors
18340         if (service != null && service.hasFileDescriptors() == true) {
18341             throw new IllegalArgumentException("File descriptors passed in Intent");
18342         }
18343
18344         if (callingPackage == null) {
18345             throw new IllegalArgumentException("callingPackage cannot be null");
18346         }
18347
18348         synchronized(this) {
18349             return mServices.bindServiceLocked(caller, token, service,
18350                     resolvedType, connection, flags, callingPackage, userId);
18351         }
18352     }
18353
18354     public boolean unbindService(IServiceConnection connection) {
18355         synchronized (this) {
18356             return mServices.unbindServiceLocked(connection);
18357         }
18358     }
18359
18360     public void publishService(IBinder token, Intent intent, IBinder service) {
18361         // Refuse possible leaked file descriptors
18362         if (intent != null && intent.hasFileDescriptors() == true) {
18363             throw new IllegalArgumentException("File descriptors passed in Intent");
18364         }
18365
18366         synchronized(this) {
18367             if (!(token instanceof ServiceRecord)) {
18368                 throw new IllegalArgumentException("Invalid service token");
18369             }
18370             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18371         }
18372     }
18373
18374     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18375         // Refuse possible leaked file descriptors
18376         if (intent != null && intent.hasFileDescriptors() == true) {
18377             throw new IllegalArgumentException("File descriptors passed in Intent");
18378         }
18379
18380         synchronized(this) {
18381             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18382         }
18383     }
18384
18385     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18386         synchronized(this) {
18387             if (!(token instanceof ServiceRecord)) {
18388                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18389                 throw new IllegalArgumentException("Invalid service token");
18390             }
18391             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18392         }
18393     }
18394
18395     // =========================================================
18396     // BACKUP AND RESTORE
18397     // =========================================================
18398
18399     // Cause the target app to be launched if necessary and its backup agent
18400     // instantiated.  The backup agent will invoke backupAgentCreated() on the
18401     // activity manager to announce its creation.
18402     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18403         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18404         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18405
18406         IPackageManager pm = AppGlobals.getPackageManager();
18407         ApplicationInfo app = null;
18408         try {
18409             app = pm.getApplicationInfo(packageName, 0, userId);
18410         } catch (RemoteException e) {
18411             // can't happen; package manager is process-local
18412         }
18413         if (app == null) {
18414             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18415             return false;
18416         }
18417
18418         int oldBackupUid;
18419         int newBackupUid;
18420
18421         synchronized(this) {
18422             // !!! TODO: currently no check here that we're already bound
18423             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18424             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18425             synchronized (stats) {
18426                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18427             }
18428
18429             // Backup agent is now in use, its package can't be stopped.
18430             try {
18431                 AppGlobals.getPackageManager().setPackageStoppedState(
18432                         app.packageName, false, UserHandle.getUserId(app.uid));
18433             } catch (RemoteException e) {
18434             } catch (IllegalArgumentException e) {
18435                 Slog.w(TAG, "Failed trying to unstop package "
18436                         + app.packageName + ": " + e);
18437             }
18438
18439             BackupRecord r = new BackupRecord(ss, app, backupMode);
18440             ComponentName hostingName =
18441                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18442                             ? new ComponentName(app.packageName, app.backupAgentName)
18443                             : new ComponentName("android", "FullBackupAgent");
18444             // startProcessLocked() returns existing proc's record if it's already running
18445             ProcessRecord proc = startProcessLocked(app.processName, app,
18446                     false, 0, "backup", hostingName, false, false, false);
18447             if (proc == null) {
18448                 Slog.e(TAG, "Unable to start backup agent process " + r);
18449                 return false;
18450             }
18451
18452             // If the app is a regular app (uid >= 10000) and not the system server or phone
18453             // process, etc, then mark it as being in full backup so that certain calls to the
18454             // process can be blocked. This is not reset to false anywhere because we kill the
18455             // process after the full backup is done and the ProcessRecord will vaporize anyway.
18456             if (UserHandle.isApp(app.uid) &&
18457                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18458                 proc.inFullBackup = true;
18459             }
18460             r.app = proc;
18461             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18462             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18463             mBackupTarget = r;
18464             mBackupAppName = app.packageName;
18465
18466             // Try not to kill the process during backup
18467             updateOomAdjLocked(proc, true);
18468
18469             // If the process is already attached, schedule the creation of the backup agent now.
18470             // If it is not yet live, this will be done when it attaches to the framework.
18471             if (proc.thread != null) {
18472                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18473                 try {
18474                     proc.thread.scheduleCreateBackupAgent(app,
18475                             compatibilityInfoForPackageLocked(app), backupMode);
18476                 } catch (RemoteException e) {
18477                     // Will time out on the backup manager side
18478                 }
18479             } else {
18480                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18481             }
18482             // Invariants: at this point, the target app process exists and the application
18483             // is either already running or in the process of coming up.  mBackupTarget and
18484             // mBackupAppName describe the app, so that when it binds back to the AM we
18485             // know that it's scheduled for a backup-agent operation.
18486         }
18487
18488         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18489         if (oldBackupUid != -1) {
18490             js.removeBackingUpUid(oldBackupUid);
18491         }
18492         if (newBackupUid != -1) {
18493             js.addBackingUpUid(newBackupUid);
18494         }
18495
18496         return true;
18497     }
18498
18499     @Override
18500     public void clearPendingBackup() {
18501         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18502         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18503
18504         synchronized (this) {
18505             mBackupTarget = null;
18506             mBackupAppName = null;
18507         }
18508
18509         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18510         js.clearAllBackingUpUids();
18511     }
18512
18513     // A backup agent has just come up
18514     public void backupAgentCreated(String agentPackageName, IBinder agent) {
18515         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18516                 + " = " + agent);
18517
18518         synchronized(this) {
18519             if (!agentPackageName.equals(mBackupAppName)) {
18520                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18521                 return;
18522             }
18523         }
18524
18525         long oldIdent = Binder.clearCallingIdentity();
18526         try {
18527             IBackupManager bm = IBackupManager.Stub.asInterface(
18528                     ServiceManager.getService(Context.BACKUP_SERVICE));
18529             bm.agentConnected(agentPackageName, agent);
18530         } catch (RemoteException e) {
18531             // can't happen; the backup manager service is local
18532         } catch (Exception e) {
18533             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18534             e.printStackTrace();
18535         } finally {
18536             Binder.restoreCallingIdentity(oldIdent);
18537         }
18538     }
18539
18540     // done with this agent
18541     public void unbindBackupAgent(ApplicationInfo appInfo) {
18542         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18543         if (appInfo == null) {
18544             Slog.w(TAG, "unbind backup agent for null app");
18545             return;
18546         }
18547
18548         int oldBackupUid;
18549
18550         synchronized(this) {
18551             try {
18552                 if (mBackupAppName == null) {
18553                     Slog.w(TAG, "Unbinding backup agent with no active backup");
18554                     return;
18555                 }
18556
18557                 if (!mBackupAppName.equals(appInfo.packageName)) {
18558                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18559                     return;
18560                 }
18561
18562                 // Not backing this app up any more; reset its OOM adjustment
18563                 final ProcessRecord proc = mBackupTarget.app;
18564                 updateOomAdjLocked(proc, true);
18565                 proc.inFullBackup = false;
18566
18567                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18568
18569                 // If the app crashed during backup, 'thread' will be null here
18570                 if (proc.thread != null) {
18571                     try {
18572                         proc.thread.scheduleDestroyBackupAgent(appInfo,
18573                                 compatibilityInfoForPackageLocked(appInfo));
18574                     } catch (Exception e) {
18575                         Slog.e(TAG, "Exception when unbinding backup agent:");
18576                         e.printStackTrace();
18577                     }
18578                 }
18579             } finally {
18580                 mBackupTarget = null;
18581                 mBackupAppName = null;
18582             }
18583         }
18584
18585         if (oldBackupUid != -1) {
18586             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18587             js.removeBackingUpUid(oldBackupUid);
18588         }
18589     }
18590
18591     // =========================================================
18592     // BROADCASTS
18593     // =========================================================
18594
18595     private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18596         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18597             return false;
18598         }
18599         // Easy case -- we have the app's ProcessRecord.
18600         if (record != null) {
18601             return record.info.isInstantApp();
18602         }
18603         // Otherwise check with PackageManager.
18604         if (callerPackage == null) {
18605             Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18606             throw new IllegalArgumentException("Calling application did not provide package name");
18607         }
18608         mAppOpsService.checkPackage(uid, callerPackage);
18609         try {
18610             IPackageManager pm = AppGlobals.getPackageManager();
18611             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18612         } catch (RemoteException e) {
18613             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18614             return true;
18615         }
18616     }
18617
18618     boolean isPendingBroadcastProcessLocked(int pid) {
18619         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18620                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18621     }
18622
18623     void skipPendingBroadcastLocked(int pid) {
18624             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18625             for (BroadcastQueue queue : mBroadcastQueues) {
18626                 queue.skipPendingBroadcastLocked(pid);
18627             }
18628     }
18629
18630     // The app just attached; send any pending broadcasts that it should receive
18631     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18632         boolean didSomething = false;
18633         for (BroadcastQueue queue : mBroadcastQueues) {
18634             didSomething |= queue.sendPendingBroadcastsLocked(app);
18635         }
18636         return didSomething;
18637     }
18638
18639     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18640             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18641             int flags) {
18642         enforceNotIsolatedCaller("registerReceiver");
18643         ArrayList<Intent> stickyIntents = null;
18644         ProcessRecord callerApp = null;
18645         final boolean visibleToInstantApps
18646                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18647         int callingUid;
18648         int callingPid;
18649         boolean instantApp;
18650         synchronized(this) {
18651             if (caller != null) {
18652                 callerApp = getRecordForAppLocked(caller);
18653                 if (callerApp == null) {
18654                     throw new SecurityException(
18655                             "Unable to find app for caller " + caller
18656                             + " (pid=" + Binder.getCallingPid()
18657                             + ") when registering receiver " + receiver);
18658                 }
18659                 if (callerApp.info.uid != SYSTEM_UID &&
18660                         !callerApp.pkgList.containsKey(callerPackage) &&
18661                         !"android".equals(callerPackage)) {
18662                     throw new SecurityException("Given caller package " + callerPackage
18663                             + " is not running in process " + callerApp);
18664                 }
18665                 callingUid = callerApp.info.uid;
18666                 callingPid = callerApp.pid;
18667             } else {
18668                 callerPackage = null;
18669                 callingUid = Binder.getCallingUid();
18670                 callingPid = Binder.getCallingPid();
18671             }
18672
18673             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18674             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18675                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18676
18677             Iterator<String> actions = filter.actionsIterator();
18678             if (actions == null) {
18679                 ArrayList<String> noAction = new ArrayList<String>(1);
18680                 noAction.add(null);
18681                 actions = noAction.iterator();
18682             }
18683
18684             // Collect stickies of users
18685             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18686             while (actions.hasNext()) {
18687                 String action = actions.next();
18688                 for (int id : userIds) {
18689                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18690                     if (stickies != null) {
18691                         ArrayList<Intent> intents = stickies.get(action);
18692                         if (intents != null) {
18693                             if (stickyIntents == null) {
18694                                 stickyIntents = new ArrayList<Intent>();
18695                             }
18696                             stickyIntents.addAll(intents);
18697                         }
18698                     }
18699                 }
18700             }
18701         }
18702
18703         ArrayList<Intent> allSticky = null;
18704         if (stickyIntents != null) {
18705             final ContentResolver resolver = mContext.getContentResolver();
18706             // Look for any matching sticky broadcasts...
18707             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18708                 Intent intent = stickyIntents.get(i);
18709                 // Don't provided intents that aren't available to instant apps.
18710                 if (instantApp &&
18711                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18712                     continue;
18713                 }
18714                 // If intent has scheme "content", it will need to acccess
18715                 // provider that needs to lock mProviderMap in ActivityThread
18716                 // and also it may need to wait application response, so we
18717                 // cannot lock ActivityManagerService here.
18718                 if (filter.match(resolver, intent, true, TAG) >= 0) {
18719                     if (allSticky == null) {
18720                         allSticky = new ArrayList<Intent>();
18721                     }
18722                     allSticky.add(intent);
18723                 }
18724             }
18725         }
18726
18727         // The first sticky in the list is returned directly back to the client.
18728         Intent sticky = allSticky != null ? allSticky.get(0) : null;
18729         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18730         if (receiver == null) {
18731             return sticky;
18732         }
18733
18734         synchronized (this) {
18735             if (callerApp != null && (callerApp.thread == null
18736                     || callerApp.thread.asBinder() != caller.asBinder())) {
18737                 // Original caller already died
18738                 return null;
18739             }
18740             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18741             if (rl == null) {
18742                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18743                         userId, receiver);
18744                 if (rl.app != null) {
18745                     rl.app.receivers.add(rl);
18746                 } else {
18747                     try {
18748                         receiver.asBinder().linkToDeath(rl, 0);
18749                     } catch (RemoteException e) {
18750                         return sticky;
18751                     }
18752                     rl.linkedToDeath = true;
18753                 }
18754                 mRegisteredReceivers.put(receiver.asBinder(), rl);
18755             } else if (rl.uid != callingUid) {
18756                 throw new IllegalArgumentException(
18757                         "Receiver requested to register for uid " + callingUid
18758                         + " was previously registered for uid " + rl.uid
18759                         + " callerPackage is " + callerPackage);
18760             } else if (rl.pid != callingPid) {
18761                 throw new IllegalArgumentException(
18762                         "Receiver requested to register for pid " + callingPid
18763                         + " was previously registered for pid " + rl.pid
18764                         + " callerPackage is " + callerPackage);
18765             } else if (rl.userId != userId) {
18766                 throw new IllegalArgumentException(
18767                         "Receiver requested to register for user " + userId
18768                         + " was previously registered for user " + rl.userId
18769                         + " callerPackage is " + callerPackage);
18770             }
18771             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18772                     permission, callingUid, userId, instantApp, visibleToInstantApps);
18773             rl.add(bf);
18774             if (!bf.debugCheck()) {
18775                 Slog.w(TAG, "==> For Dynamic broadcast");
18776             }
18777             mReceiverResolver.addFilter(bf);
18778
18779             // Enqueue broadcasts for all existing stickies that match
18780             // this filter.
18781             if (allSticky != null) {
18782                 ArrayList receivers = new ArrayList();
18783                 receivers.add(bf);
18784
18785                 final int stickyCount = allSticky.size();
18786                 for (int i = 0; i < stickyCount; i++) {
18787                     Intent intent = allSticky.get(i);
18788                     BroadcastQueue queue = broadcastQueueForIntent(intent);
18789                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18790                             null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18791                             null, 0, null, null, false, true, true, -1);
18792                     queue.enqueueParallelBroadcastLocked(r);
18793                     queue.scheduleBroadcastsLocked();
18794                 }
18795             }
18796
18797             return sticky;
18798         }
18799     }
18800
18801     public void unregisterReceiver(IIntentReceiver receiver) {
18802         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18803
18804         final long origId = Binder.clearCallingIdentity();
18805         try {
18806             boolean doTrim = false;
18807
18808             synchronized(this) {
18809                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18810                 if (rl != null) {
18811                     final BroadcastRecord r = rl.curBroadcast;
18812                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18813                         final boolean doNext = r.queue.finishReceiverLocked(
18814                                 r, r.resultCode, r.resultData, r.resultExtras,
18815                                 r.resultAbort, false);
18816                         if (doNext) {
18817                             doTrim = true;
18818                             r.queue.processNextBroadcast(false);
18819                         }
18820                     }
18821
18822                     if (rl.app != null) {
18823                         rl.app.receivers.remove(rl);
18824                     }
18825                     removeReceiverLocked(rl);
18826                     if (rl.linkedToDeath) {
18827                         rl.linkedToDeath = false;
18828                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
18829                     }
18830                 }
18831             }
18832
18833             // If we actually concluded any broadcasts, we might now be able
18834             // to trim the recipients' apps from our working set
18835             if (doTrim) {
18836                 trimApplications();
18837                 return;
18838             }
18839
18840         } finally {
18841             Binder.restoreCallingIdentity(origId);
18842         }
18843     }
18844
18845     void removeReceiverLocked(ReceiverList rl) {
18846         mRegisteredReceivers.remove(rl.receiver.asBinder());
18847         for (int i = rl.size() - 1; i >= 0; i--) {
18848             mReceiverResolver.removeFilter(rl.get(i));
18849         }
18850     }
18851
18852     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18853         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18854             ProcessRecord r = mLruProcesses.get(i);
18855             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18856                 try {
18857                     r.thread.dispatchPackageBroadcast(cmd, packages);
18858                 } catch (RemoteException ex) {
18859                 }
18860             }
18861         }
18862     }
18863
18864     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18865             int callingUid, int[] users) {
18866         // TODO: come back and remove this assumption to triage all broadcasts
18867         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18868
18869         List<ResolveInfo> receivers = null;
18870         try {
18871             HashSet<ComponentName> singleUserReceivers = null;
18872             boolean scannedFirstReceivers = false;
18873             for (int user : users) {
18874                 // Skip users that have Shell restrictions, with exception of always permitted
18875                 // Shell broadcasts
18876                 if (callingUid == SHELL_UID
18877                         && mUserController.hasUserRestriction(
18878                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18879                         && !isPermittedShellBroadcast(intent)) {
18880                     continue;
18881                 }
18882                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18883                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18884                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18885                     // If this is not the system user, we need to check for
18886                     // any receivers that should be filtered out.
18887                     for (int i=0; i<newReceivers.size(); i++) {
18888                         ResolveInfo ri = newReceivers.get(i);
18889                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18890                             newReceivers.remove(i);
18891                             i--;
18892                         }
18893                     }
18894                 }
18895                 if (newReceivers != null && newReceivers.size() == 0) {
18896                     newReceivers = null;
18897                 }
18898                 if (receivers == null) {
18899                     receivers = newReceivers;
18900                 } else if (newReceivers != null) {
18901                     // We need to concatenate the additional receivers
18902                     // found with what we have do far.  This would be easy,
18903                     // but we also need to de-dup any receivers that are
18904                     // singleUser.
18905                     if (!scannedFirstReceivers) {
18906                         // Collect any single user receivers we had already retrieved.
18907                         scannedFirstReceivers = true;
18908                         for (int i=0; i<receivers.size(); i++) {
18909                             ResolveInfo ri = receivers.get(i);
18910                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18911                                 ComponentName cn = new ComponentName(
18912                                         ri.activityInfo.packageName, ri.activityInfo.name);
18913                                 if (singleUserReceivers == null) {
18914                                     singleUserReceivers = new HashSet<ComponentName>();
18915                                 }
18916                                 singleUserReceivers.add(cn);
18917                             }
18918                         }
18919                     }
18920                     // Add the new results to the existing results, tracking
18921                     // and de-dupping single user receivers.
18922                     for (int i=0; i<newReceivers.size(); i++) {
18923                         ResolveInfo ri = newReceivers.get(i);
18924                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18925                             ComponentName cn = new ComponentName(
18926                                     ri.activityInfo.packageName, ri.activityInfo.name);
18927                             if (singleUserReceivers == null) {
18928                                 singleUserReceivers = new HashSet<ComponentName>();
18929                             }
18930                             if (!singleUserReceivers.contains(cn)) {
18931                                 singleUserReceivers.add(cn);
18932                                 receivers.add(ri);
18933                             }
18934                         } else {
18935                             receivers.add(ri);
18936                         }
18937                     }
18938                 }
18939             }
18940         } catch (RemoteException ex) {
18941             // pm is in same process, this will never happen.
18942         }
18943         return receivers;
18944     }
18945
18946     private boolean isPermittedShellBroadcast(Intent intent) {
18947         // remote bugreport should always be allowed to be taken
18948         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18949     }
18950
18951     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18952             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18953         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18954             // Don't yell about broadcasts sent via shell
18955             return;
18956         }
18957
18958         final String action = intent.getAction();
18959         if (isProtectedBroadcast
18960                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18961                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18962                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
18963                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18964                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18965                 || Intent.ACTION_MASTER_CLEAR.equals(action)
18966                 || Intent.ACTION_FACTORY_RESET.equals(action)
18967                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18968                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18969                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18970                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18971                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18972                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18973                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18974             // Broadcast is either protected, or it's a public action that
18975             // we've relaxed, so it's fine for system internals to send.
18976             return;
18977         }
18978
18979         // This broadcast may be a problem...  but there are often system components that
18980         // want to send an internal broadcast to themselves, which is annoying to have to
18981         // explicitly list each action as a protected broadcast, so we will check for that
18982         // one safe case and allow it: an explicit broadcast, only being received by something
18983         // that has protected itself.
18984         if (receivers != null && receivers.size() > 0
18985                 && (intent.getPackage() != null || intent.getComponent() != null)) {
18986             boolean allProtected = true;
18987             for (int i = receivers.size()-1; i >= 0; i--) {
18988                 Object target = receivers.get(i);
18989                 if (target instanceof ResolveInfo) {
18990                     ResolveInfo ri = (ResolveInfo)target;
18991                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18992                         allProtected = false;
18993                         break;
18994                     }
18995                 } else {
18996                     BroadcastFilter bf = (BroadcastFilter)target;
18997                     if (bf.requiredPermission == null) {
18998                         allProtected = false;
18999                         break;
19000                     }
19001                 }
19002             }
19003             if (allProtected) {
19004                 // All safe!
19005                 return;
19006             }
19007         }
19008
19009         // The vast majority of broadcasts sent from system internals
19010         // should be protected to avoid security holes, so yell loudly
19011         // to ensure we examine these cases.
19012         if (callerApp != null) {
19013             Log.wtf(TAG, "Sending non-protected broadcast " + action
19014                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19015                     new Throwable());
19016         } else {
19017             Log.wtf(TAG, "Sending non-protected broadcast " + action
19018                             + " from system uid " + UserHandle.formatUid(callingUid)
19019                             + " pkg " + callerPackage,
19020                     new Throwable());
19021         }
19022     }
19023
19024     final int broadcastIntentLocked(ProcessRecord callerApp,
19025             String callerPackage, Intent intent, String resolvedType,
19026             IIntentReceiver resultTo, int resultCode, String resultData,
19027             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19028             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19029         intent = new Intent(intent);
19030
19031         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19032         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19033         if (callerInstantApp) {
19034             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19035         }
19036
19037         // By default broadcasts do not go to stopped apps.
19038         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19039
19040         // If we have not finished booting, don't allow this to launch new processes.
19041         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19042             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19043         }
19044
19045         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19046                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19047                 + " ordered=" + ordered + " userid=" + userId);
19048         if ((resultTo != null) && !ordered) {
19049             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19050         }
19051
19052         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19053                 ALLOW_NON_FULL, "broadcast", callerPackage);
19054
19055         // Make sure that the user who is receiving this broadcast is running.
19056         // If not, we will just skip it. Make an exception for shutdown broadcasts
19057         // and upgrade steps.
19058
19059         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19060             if ((callingUid != SYSTEM_UID
19061                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19062                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19063                 Slog.w(TAG, "Skipping broadcast of " + intent
19064                         + ": user " + userId + " is stopped");
19065                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19066             }
19067         }
19068
19069         BroadcastOptions brOptions = null;
19070         if (bOptions != null) {
19071             brOptions = new BroadcastOptions(bOptions);
19072             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19073                 // See if the caller is allowed to do this.  Note we are checking against
19074                 // the actual real caller (not whoever provided the operation as say a
19075                 // PendingIntent), because that who is actually supplied the arguments.
19076                 if (checkComponentPermission(
19077                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19078                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19079                         != PackageManager.PERMISSION_GRANTED) {
19080                     String msg = "Permission Denial: " + intent.getAction()
19081                             + " broadcast from " + callerPackage + " (pid=" + callingPid
19082                             + ", uid=" + callingUid + ")"
19083                             + " requires "
19084                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19085                     Slog.w(TAG, msg);
19086                     throw new SecurityException(msg);
19087                 }
19088             }
19089         }
19090
19091         // Verify that protected broadcasts are only being sent by system code,
19092         // and that system code is only sending protected broadcasts.
19093         final String action = intent.getAction();
19094         final boolean isProtectedBroadcast;
19095         try {
19096             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19097         } catch (RemoteException e) {
19098             Slog.w(TAG, "Remote exception", e);
19099             return ActivityManager.BROADCAST_SUCCESS;
19100         }
19101
19102         final boolean isCallerSystem;
19103         switch (UserHandle.getAppId(callingUid)) {
19104             case ROOT_UID:
19105             case SYSTEM_UID:
19106             case PHONE_UID:
19107             case BLUETOOTH_UID:
19108             case NFC_UID:
19109                 isCallerSystem = true;
19110                 break;
19111             default:
19112                 isCallerSystem = (callerApp != null) && callerApp.persistent;
19113                 break;
19114         }
19115
19116         // First line security check before anything else: stop non-system apps from
19117         // sending protected broadcasts.
19118         if (!isCallerSystem) {
19119             if (isProtectedBroadcast) {
19120                 String msg = "Permission Denial: not allowed to send broadcast "
19121                         + action + " from pid="
19122                         + callingPid + ", uid=" + callingUid;
19123                 Slog.w(TAG, msg);
19124                 throw new SecurityException(msg);
19125
19126             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19127                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19128                 // Special case for compatibility: we don't want apps to send this,
19129                 // but historically it has not been protected and apps may be using it
19130                 // to poke their own app widget.  So, instead of making it protected,
19131                 // just limit it to the caller.
19132                 if (callerPackage == null) {
19133                     String msg = "Permission Denial: not allowed to send broadcast "
19134                             + action + " from unknown caller.";
19135                     Slog.w(TAG, msg);
19136                     throw new SecurityException(msg);
19137                 } else if (intent.getComponent() != null) {
19138                     // They are good enough to send to an explicit component...  verify
19139                     // it is being sent to the calling app.
19140                     if (!intent.getComponent().getPackageName().equals(
19141                             callerPackage)) {
19142                         String msg = "Permission Denial: not allowed to send broadcast "
19143                                 + action + " to "
19144                                 + intent.getComponent().getPackageName() + " from "
19145                                 + callerPackage;
19146                         Slog.w(TAG, msg);
19147                         throw new SecurityException(msg);
19148                     }
19149                 } else {
19150                     // Limit broadcast to their own package.
19151                     intent.setPackage(callerPackage);
19152                 }
19153             }
19154         }
19155
19156         if (action != null) {
19157             if (getBackgroundLaunchBroadcasts().contains(action)) {
19158                 if (DEBUG_BACKGROUND_CHECK) {
19159                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19160                 }
19161                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19162             }
19163
19164             switch (action) {
19165                 case Intent.ACTION_UID_REMOVED:
19166                 case Intent.ACTION_PACKAGE_REMOVED:
19167                 case Intent.ACTION_PACKAGE_CHANGED:
19168                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19169                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19170                 case Intent.ACTION_PACKAGES_SUSPENDED:
19171                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19172                     // Handle special intents: if this broadcast is from the package
19173                     // manager about a package being removed, we need to remove all of
19174                     // its activities from the history stack.
19175                     if (checkComponentPermission(
19176                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19177                             callingPid, callingUid, -1, true)
19178                             != PackageManager.PERMISSION_GRANTED) {
19179                         String msg = "Permission Denial: " + intent.getAction()
19180                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
19181                                 + ", uid=" + callingUid + ")"
19182                                 + " requires "
19183                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19184                         Slog.w(TAG, msg);
19185                         throw new SecurityException(msg);
19186                     }
19187                     switch (action) {
19188                         case Intent.ACTION_UID_REMOVED:
19189                             final int uid = getUidFromIntent(intent);
19190                             if (uid >= 0) {
19191                                 mBatteryStatsService.removeUid(uid);
19192                                 mAppOpsService.uidRemoved(uid);
19193                             }
19194                             break;
19195                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19196                             // If resources are unavailable just force stop all those packages
19197                             // and flush the attribute cache as well.
19198                             String list[] =
19199                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19200                             if (list != null && list.length > 0) {
19201                                 for (int i = 0; i < list.length; i++) {
19202                                     forceStopPackageLocked(list[i], -1, false, true, true,
19203                                             false, false, userId, "storage unmount");
19204                                 }
19205                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19206                                 sendPackageBroadcastLocked(
19207                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19208                                         list, userId);
19209                             }
19210                             break;
19211                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19212                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19213                             break;
19214                         case Intent.ACTION_PACKAGE_REMOVED:
19215                         case Intent.ACTION_PACKAGE_CHANGED:
19216                             Uri data = intent.getData();
19217                             String ssp;
19218                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19219                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19220                                 final boolean replacing =
19221                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19222                                 final boolean killProcess =
19223                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19224                                 final boolean fullUninstall = removed && !replacing;
19225                                 if (removed) {
19226                                     if (killProcess) {
19227                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
19228                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19229                                                 false, true, true, false, fullUninstall, userId,
19230                                                 removed ? "pkg removed" : "pkg changed");
19231                                     }
19232                                     final int cmd = killProcess
19233                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
19234                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19235                                     sendPackageBroadcastLocked(cmd,
19236                                             new String[] {ssp}, userId);
19237                                     if (fullUninstall) {
19238                                         mAppOpsService.packageRemoved(
19239                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19240
19241                                         // Remove all permissions granted from/to this package
19242                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
19243
19244                                         removeTasksByPackageNameLocked(ssp, userId);
19245
19246                                         mServices.forceStopPackageLocked(ssp, userId);
19247
19248                                         // Hide the "unsupported display" dialog if necessary.
19249                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19250                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19251                                             mUnsupportedDisplaySizeDialog.dismiss();
19252                                             mUnsupportedDisplaySizeDialog = null;
19253                                         }
19254                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
19255                                         mBatteryStatsService.notePackageUninstalled(ssp);
19256                                     }
19257                                 } else {
19258                                     if (killProcess) {
19259                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
19260                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19261                                                 userId, ProcessList.INVALID_ADJ,
19262                                                 false, true, true, false, "change " + ssp);
19263                                     }
19264                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19265                                             intent.getStringArrayExtra(
19266                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19267                                 }
19268                             }
19269                             break;
19270                         case Intent.ACTION_PACKAGES_SUSPENDED:
19271                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
19272                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19273                                     intent.getAction());
19274                             final String[] packageNames = intent.getStringArrayExtra(
19275                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
19276                             final int userHandle = intent.getIntExtra(
19277                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19278
19279                             synchronized(ActivityManagerService.this) {
19280                                 mRecentTasks.onPackagesSuspendedChanged(
19281                                         packageNames, suspended, userHandle);
19282                             }
19283                             break;
19284                     }
19285                     break;
19286                 case Intent.ACTION_PACKAGE_REPLACED:
19287                 {
19288                     final Uri data = intent.getData();
19289                     final String ssp;
19290                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19291                         ApplicationInfo aInfo = null;
19292                         try {
19293                             aInfo = AppGlobals.getPackageManager()
19294                                     .getApplicationInfo(ssp, 0 /*flags*/, userId);
19295                         } catch (RemoteException ignore) {}
19296                         if (aInfo == null) {
19297                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19298                                     + " ssp=" + ssp + " data=" + data);
19299                             return ActivityManager.BROADCAST_SUCCESS;
19300                         }
19301                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19302                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19303                                 new String[] {ssp}, userId);
19304                     }
19305                     break;
19306                 }
19307                 case Intent.ACTION_PACKAGE_ADDED:
19308                 {
19309                     // Special case for adding a package: by default turn on compatibility mode.
19310                     Uri data = intent.getData();
19311                     String ssp;
19312                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19313                         final boolean replacing =
19314                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19315                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19316
19317                         try {
19318                             ApplicationInfo ai = AppGlobals.getPackageManager().
19319                                     getApplicationInfo(ssp, 0, 0);
19320                             mBatteryStatsService.notePackageInstalled(ssp,
19321                                     ai != null ? ai.versionCode : 0);
19322                         } catch (RemoteException e) {
19323                         }
19324                     }
19325                     break;
19326                 }
19327                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19328                 {
19329                     Uri data = intent.getData();
19330                     String ssp;
19331                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19332                         // Hide the "unsupported display" dialog if necessary.
19333                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19334                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19335                             mUnsupportedDisplaySizeDialog.dismiss();
19336                             mUnsupportedDisplaySizeDialog = null;
19337                         }
19338                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
19339                     }
19340                     break;
19341                 }
19342                 case Intent.ACTION_TIMEZONE_CHANGED:
19343                     // If this is the time zone changed action, queue up a message that will reset
19344                     // the timezone of all currently running processes. This message will get
19345                     // queued up before the broadcast happens.
19346                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19347                     break;
19348                 case Intent.ACTION_TIME_CHANGED:
19349                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19350                     // the tri-state value it may contain and "unknown".
19351                     // For convenience we re-use the Intent extra values.
19352                     final int NO_EXTRA_VALUE_FOUND = -1;
19353                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19354                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19355                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
19356                     // Only send a message if the time preference is available.
19357                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19358                         Message updateTimePreferenceMsg =
19359                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19360                                         timeFormatPreferenceMsgValue, 0);
19361                         mHandler.sendMessage(updateTimePreferenceMsg);
19362                     }
19363                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19364                     synchronized (stats) {
19365                         stats.noteCurrentTimeChangedLocked();
19366                     }
19367                     break;
19368                 case Intent.ACTION_CLEAR_DNS_CACHE:
19369                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19370                     break;
19371                 case Proxy.PROXY_CHANGE_ACTION:
19372                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19373                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19374                     break;
19375                 case android.hardware.Camera.ACTION_NEW_PICTURE:
19376                 case android.hardware.Camera.ACTION_NEW_VIDEO:
19377                     // In N we just turned these off; in O we are turing them back on partly,
19378                     // only for registered receivers.  This will still address the main problem
19379                     // (a spam of apps waking up when a picture is taken putting significant
19380                     // memory pressure on the system at a bad point), while still allowing apps
19381                     // that are already actively running to know about this happening.
19382                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19383                     break;
19384                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19385                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19386                     break;
19387                 case "com.android.launcher.action.INSTALL_SHORTCUT":
19388                     // As of O, we no longer support this broadcasts, even for pre-O apps.
19389                     // Apps should now be using ShortcutManager.pinRequestShortcut().
19390                     Log.w(TAG, "Broadcast " + action
19391                             + " no longer supported. It will not be delivered.");
19392                     return ActivityManager.BROADCAST_SUCCESS;
19393             }
19394
19395             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19396                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19397                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19398                 final int uid = getUidFromIntent(intent);
19399                 if (uid != -1) {
19400                     final UidRecord uidRec = mActiveUids.get(uid);
19401                     if (uidRec != null) {
19402                         uidRec.updateHasInternetPermission();
19403                     }
19404                 }
19405             }
19406         }
19407
19408         // Add to the sticky list if requested.
19409         if (sticky) {
19410             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19411                     callingPid, callingUid)
19412                     != PackageManager.PERMISSION_GRANTED) {
19413                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19414                         + callingPid + ", uid=" + callingUid
19415                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19416                 Slog.w(TAG, msg);
19417                 throw new SecurityException(msg);
19418             }
19419             if (requiredPermissions != null && requiredPermissions.length > 0) {
19420                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19421                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
19422                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19423             }
19424             if (intent.getComponent() != null) {
19425                 throw new SecurityException(
19426                         "Sticky broadcasts can't target a specific component");
19427             }
19428             // We use userId directly here, since the "all" target is maintained
19429             // as a separate set of sticky broadcasts.
19430             if (userId != UserHandle.USER_ALL) {
19431                 // But first, if this is not a broadcast to all users, then
19432                 // make sure it doesn't conflict with an existing broadcast to
19433                 // all users.
19434                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19435                         UserHandle.USER_ALL);
19436                 if (stickies != null) {
19437                     ArrayList<Intent> list = stickies.get(intent.getAction());
19438                     if (list != null) {
19439                         int N = list.size();
19440                         int i;
19441                         for (i=0; i<N; i++) {
19442                             if (intent.filterEquals(list.get(i))) {
19443                                 throw new IllegalArgumentException(
19444                                         "Sticky broadcast " + intent + " for user "
19445                                         + userId + " conflicts with existing global broadcast");
19446                             }
19447                         }
19448                     }
19449                 }
19450             }
19451             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19452             if (stickies == null) {
19453                 stickies = new ArrayMap<>();
19454                 mStickyBroadcasts.put(userId, stickies);
19455             }
19456             ArrayList<Intent> list = stickies.get(intent.getAction());
19457             if (list == null) {
19458                 list = new ArrayList<>();
19459                 stickies.put(intent.getAction(), list);
19460             }
19461             final int stickiesCount = list.size();
19462             int i;
19463             for (i = 0; i < stickiesCount; i++) {
19464                 if (intent.filterEquals(list.get(i))) {
19465                     // This sticky already exists, replace it.
19466                     list.set(i, new Intent(intent));
19467                     break;
19468                 }
19469             }
19470             if (i >= stickiesCount) {
19471                 list.add(new Intent(intent));
19472             }
19473         }
19474
19475         int[] users;
19476         if (userId == UserHandle.USER_ALL) {
19477             // Caller wants broadcast to go to all started users.
19478             users = mUserController.getStartedUserArrayLocked();
19479         } else {
19480             // Caller wants broadcast to go to one specific user.
19481             users = new int[] {userId};
19482         }
19483
19484         // Figure out who all will receive this broadcast.
19485         List receivers = null;
19486         List<BroadcastFilter> registeredReceivers = null;
19487         // Need to resolve the intent to interested receivers...
19488         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19489                  == 0) {
19490             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19491         }
19492         if (intent.getComponent() == null) {
19493             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19494                 // Query one target user at a time, excluding shell-restricted users
19495                 for (int i = 0; i < users.length; i++) {
19496                     if (mUserController.hasUserRestriction(
19497                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19498                         continue;
19499                     }
19500                     List<BroadcastFilter> registeredReceiversForUser =
19501                             mReceiverResolver.queryIntent(intent,
19502                                     resolvedType, false /*defaultOnly*/, users[i]);
19503                     if (registeredReceivers == null) {
19504                         registeredReceivers = registeredReceiversForUser;
19505                     } else if (registeredReceiversForUser != null) {
19506                         registeredReceivers.addAll(registeredReceiversForUser);
19507                     }
19508                 }
19509             } else {
19510                 registeredReceivers = mReceiverResolver.queryIntent(intent,
19511                         resolvedType, false /*defaultOnly*/, userId);
19512             }
19513         }
19514
19515         final boolean replacePending =
19516                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19517
19518         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19519                 + " replacePending=" + replacePending);
19520
19521         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19522         if (!ordered && NR > 0) {
19523             // If we are not serializing this broadcast, then send the
19524             // registered receivers separately so they don't wait for the
19525             // components to be launched.
19526             if (isCallerSystem) {
19527                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19528                         isProtectedBroadcast, registeredReceivers);
19529             }
19530             final BroadcastQueue queue = broadcastQueueForIntent(intent);
19531             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19532                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19533                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19534                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19535             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19536             final boolean replaced = replacePending
19537                     && (queue.replaceParallelBroadcastLocked(r) != null);
19538             // Note: We assume resultTo is null for non-ordered broadcasts.
19539             if (!replaced) {
19540                 queue.enqueueParallelBroadcastLocked(r);
19541                 queue.scheduleBroadcastsLocked();
19542             }
19543             registeredReceivers = null;
19544             NR = 0;
19545         }
19546
19547         // Merge into one list.
19548         int ir = 0;
19549         if (receivers != null) {
19550             // A special case for PACKAGE_ADDED: do not allow the package
19551             // being added to see this broadcast.  This prevents them from
19552             // using this as a back door to get run as soon as they are
19553             // installed.  Maybe in the future we want to have a special install
19554             // broadcast or such for apps, but we'd like to deliberately make
19555             // this decision.
19556             String skipPackages[] = null;
19557             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19558                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19559                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19560                 Uri data = intent.getData();
19561                 if (data != null) {
19562                     String pkgName = data.getSchemeSpecificPart();
19563                     if (pkgName != null) {
19564                         skipPackages = new String[] { pkgName };
19565                     }
19566                 }
19567             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19568                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19569             }
19570             if (skipPackages != null && (skipPackages.length > 0)) {
19571                 for (String skipPackage : skipPackages) {
19572                     if (skipPackage != null) {
19573                         int NT = receivers.size();
19574                         for (int it=0; it<NT; it++) {
19575                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
19576                             if (curt.activityInfo.packageName.equals(skipPackage)) {
19577                                 receivers.remove(it);
19578                                 it--;
19579                                 NT--;
19580                             }
19581                         }
19582                     }
19583                 }
19584             }
19585
19586             int NT = receivers != null ? receivers.size() : 0;
19587             int it = 0;
19588             ResolveInfo curt = null;
19589             BroadcastFilter curr = null;
19590             while (it < NT && ir < NR) {
19591                 if (curt == null) {
19592                     curt = (ResolveInfo)receivers.get(it);
19593                 }
19594                 if (curr == null) {
19595                     curr = registeredReceivers.get(ir);
19596                 }
19597                 if (curr.getPriority() >= curt.priority) {
19598                     // Insert this broadcast record into the final list.
19599                     receivers.add(it, curr);
19600                     ir++;
19601                     curr = null;
19602                     it++;
19603                     NT++;
19604                 } else {
19605                     // Skip to the next ResolveInfo in the final list.
19606                     it++;
19607                     curt = null;
19608                 }
19609             }
19610         }
19611         while (ir < NR) {
19612             if (receivers == null) {
19613                 receivers = new ArrayList();
19614             }
19615             receivers.add(registeredReceivers.get(ir));
19616             ir++;
19617         }
19618
19619         if (isCallerSystem) {
19620             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19621                     isProtectedBroadcast, receivers);
19622         }
19623
19624         if ((receivers != null && receivers.size() > 0)
19625                 || resultTo != null) {
19626             BroadcastQueue queue = broadcastQueueForIntent(intent);
19627             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19628                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19629                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19630                     resultData, resultExtras, ordered, sticky, false, userId);
19631
19632             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19633                     + ": prev had " + queue.mOrderedBroadcasts.size());
19634             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19635                     "Enqueueing broadcast " + r.intent.getAction());
19636
19637             final BroadcastRecord oldRecord =
19638                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19639             if (oldRecord != null) {
19640                 // Replaced, fire the result-to receiver.
19641                 if (oldRecord.resultTo != null) {
19642                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19643                     try {
19644                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19645                                 oldRecord.intent,
19646                                 Activity.RESULT_CANCELED, null, null,
19647                                 false, false, oldRecord.userId);
19648                     } catch (RemoteException e) {
19649                         Slog.w(TAG, "Failure ["
19650                                 + queue.mQueueName + "] sending broadcast result of "
19651                                 + intent, e);
19652
19653                     }
19654                 }
19655             } else {
19656                 queue.enqueueOrderedBroadcastLocked(r);
19657                 queue.scheduleBroadcastsLocked();
19658             }
19659         } else {
19660             // There was nobody interested in the broadcast, but we still want to record
19661             // that it happened.
19662             if (intent.getComponent() == null && intent.getPackage() == null
19663                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19664                 // This was an implicit broadcast... let's record it for posterity.
19665                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19666             }
19667         }
19668
19669         return ActivityManager.BROADCAST_SUCCESS;
19670     }
19671
19672     /**
19673      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19674      */
19675     private int getUidFromIntent(Intent intent) {
19676         if (intent == null) {
19677             return -1;
19678         }
19679         final Bundle intentExtras = intent.getExtras();
19680         return intent.hasExtra(Intent.EXTRA_UID)
19681                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19682     }
19683
19684     final void rotateBroadcastStatsIfNeededLocked() {
19685         final long now = SystemClock.elapsedRealtime();
19686         if (mCurBroadcastStats == null ||
19687                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19688             mLastBroadcastStats = mCurBroadcastStats;
19689             if (mLastBroadcastStats != null) {
19690                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19691                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19692             }
19693             mCurBroadcastStats = new BroadcastStats();
19694         }
19695     }
19696
19697     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19698             int skipCount, long dispatchTime) {
19699         rotateBroadcastStatsIfNeededLocked();
19700         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19701     }
19702
19703     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19704         rotateBroadcastStatsIfNeededLocked();
19705         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19706     }
19707
19708     final Intent verifyBroadcastLocked(Intent intent) {
19709         // Refuse possible leaked file descriptors
19710         if (intent != null && intent.hasFileDescriptors() == true) {
19711             throw new IllegalArgumentException("File descriptors passed in Intent");
19712         }
19713
19714         int flags = intent.getFlags();
19715
19716         if (!mProcessesReady) {
19717             // if the caller really truly claims to know what they're doing, go
19718             // ahead and allow the broadcast without launching any receivers
19719             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19720                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19721             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19722                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19723                         + " before boot completion");
19724                 throw new IllegalStateException("Cannot broadcast before boot completed");
19725             }
19726         }
19727
19728         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19729             throw new IllegalArgumentException(
19730                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19731         }
19732
19733         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19734             switch (Binder.getCallingUid()) {
19735                 case ROOT_UID:
19736                 case SHELL_UID:
19737                     break;
19738                 default:
19739                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19740                             + Binder.getCallingUid());
19741                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19742                     break;
19743             }
19744         }
19745
19746         return intent;
19747     }
19748
19749     public final int broadcastIntent(IApplicationThread caller,
19750             Intent intent, String resolvedType, IIntentReceiver resultTo,
19751             int resultCode, String resultData, Bundle resultExtras,
19752             String[] requiredPermissions, int appOp, Bundle bOptions,
19753             boolean serialized, boolean sticky, int userId) {
19754         enforceNotIsolatedCaller("broadcastIntent");
19755         synchronized(this) {
19756             intent = verifyBroadcastLocked(intent);
19757
19758             final ProcessRecord callerApp = getRecordForAppLocked(caller);
19759             final int callingPid = Binder.getCallingPid();
19760             final int callingUid = Binder.getCallingUid();
19761             final long origId = Binder.clearCallingIdentity();
19762             int res = broadcastIntentLocked(callerApp,
19763                     callerApp != null ? callerApp.info.packageName : null,
19764                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19765                     requiredPermissions, appOp, bOptions, serialized, sticky,
19766                     callingPid, callingUid, userId);
19767             Binder.restoreCallingIdentity(origId);
19768             return res;
19769         }
19770     }
19771
19772
19773     int broadcastIntentInPackage(String packageName, int uid,
19774             Intent intent, String resolvedType, IIntentReceiver resultTo,
19775             int resultCode, String resultData, Bundle resultExtras,
19776             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19777             int userId) {
19778         synchronized(this) {
19779             intent = verifyBroadcastLocked(intent);
19780
19781             final long origId = Binder.clearCallingIdentity();
19782             String[] requiredPermissions = requiredPermission == null ? null
19783                     : new String[] {requiredPermission};
19784             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19785                     resultTo, resultCode, resultData, resultExtras,
19786                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19787                     sticky, -1, uid, userId);
19788             Binder.restoreCallingIdentity(origId);
19789             return res;
19790         }
19791     }
19792
19793     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19794         // Refuse possible leaked file descriptors
19795         if (intent != null && intent.hasFileDescriptors() == true) {
19796             throw new IllegalArgumentException("File descriptors passed in Intent");
19797         }
19798
19799         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19800                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19801
19802         synchronized(this) {
19803             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19804                     != PackageManager.PERMISSION_GRANTED) {
19805                 String msg = "Permission Denial: unbroadcastIntent() from pid="
19806                         + Binder.getCallingPid()
19807                         + ", uid=" + Binder.getCallingUid()
19808                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19809                 Slog.w(TAG, msg);
19810                 throw new SecurityException(msg);
19811             }
19812             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19813             if (stickies != null) {
19814                 ArrayList<Intent> list = stickies.get(intent.getAction());
19815                 if (list != null) {
19816                     int N = list.size();
19817                     int i;
19818                     for (i=0; i<N; i++) {
19819                         if (intent.filterEquals(list.get(i))) {
19820                             list.remove(i);
19821                             break;
19822                         }
19823                     }
19824                     if (list.size() <= 0) {
19825                         stickies.remove(intent.getAction());
19826                     }
19827                 }
19828                 if (stickies.size() <= 0) {
19829                     mStickyBroadcasts.remove(userId);
19830                 }
19831             }
19832         }
19833     }
19834
19835     void backgroundServicesFinishedLocked(int userId) {
19836         for (BroadcastQueue queue : mBroadcastQueues) {
19837             queue.backgroundServicesFinishedLocked(userId);
19838         }
19839     }
19840
19841     public void finishReceiver(IBinder who, int resultCode, String resultData,
19842             Bundle resultExtras, boolean resultAbort, int flags) {
19843         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19844
19845         // Refuse possible leaked file descriptors
19846         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19847             throw new IllegalArgumentException("File descriptors passed in Bundle");
19848         }
19849
19850         final long origId = Binder.clearCallingIdentity();
19851         try {
19852             boolean doNext = false;
19853             BroadcastRecord r;
19854
19855             synchronized(this) {
19856                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19857                         ? mFgBroadcastQueue : mBgBroadcastQueue;
19858                 r = queue.getMatchingOrderedReceiver(who);
19859                 if (r != null) {
19860                     doNext = r.queue.finishReceiverLocked(r, resultCode,
19861                         resultData, resultExtras, resultAbort, true);
19862                 }
19863             }
19864
19865             if (doNext) {
19866                 r.queue.processNextBroadcast(false);
19867             }
19868             trimApplications();
19869         } finally {
19870             Binder.restoreCallingIdentity(origId);
19871         }
19872     }
19873
19874     // =========================================================
19875     // INSTRUMENTATION
19876     // =========================================================
19877
19878     public boolean startInstrumentation(ComponentName className,
19879             String profileFile, int flags, Bundle arguments,
19880             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19881             int userId, String abiOverride) {
19882         enforceNotIsolatedCaller("startInstrumentation");
19883         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19884                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19885         // Refuse possible leaked file descriptors
19886         if (arguments != null && arguments.hasFileDescriptors()) {
19887             throw new IllegalArgumentException("File descriptors passed in Bundle");
19888         }
19889
19890         synchronized(this) {
19891             InstrumentationInfo ii = null;
19892             ApplicationInfo ai = null;
19893             try {
19894                 ii = mContext.getPackageManager().getInstrumentationInfo(
19895                     className, STOCK_PM_FLAGS);
19896                 ai = AppGlobals.getPackageManager().getApplicationInfo(
19897                         ii.targetPackage, STOCK_PM_FLAGS, userId);
19898             } catch (PackageManager.NameNotFoundException e) {
19899             } catch (RemoteException e) {
19900             }
19901             if (ii == null) {
19902                 reportStartInstrumentationFailureLocked(watcher, className,
19903                         "Unable to find instrumentation info for: " + className);
19904                 return false;
19905             }
19906             if (ai == null) {
19907                 reportStartInstrumentationFailureLocked(watcher, className,
19908                         "Unable to find instrumentation target package: " + ii.targetPackage);
19909                 return false;
19910             }
19911             if (!ai.hasCode()) {
19912                 reportStartInstrumentationFailureLocked(watcher, className,
19913                         "Instrumentation target has no code: " + ii.targetPackage);
19914                 return false;
19915             }
19916
19917             int match = mContext.getPackageManager().checkSignatures(
19918                     ii.targetPackage, ii.packageName);
19919             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19920                 String msg = "Permission Denial: starting instrumentation "
19921                         + className + " from pid="
19922                         + Binder.getCallingPid()
19923                         + ", uid=" + Binder.getCallingPid()
19924                         + " not allowed because package " + ii.packageName
19925                         + " does not have a signature matching the target "
19926                         + ii.targetPackage;
19927                 reportStartInstrumentationFailureLocked(watcher, className, msg);
19928                 throw new SecurityException(msg);
19929             }
19930
19931             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19932             activeInstr.mClass = className;
19933             String defProcess = ai.processName;;
19934             if (ii.targetProcesses == null) {
19935                 activeInstr.mTargetProcesses = new String[]{ai.processName};
19936             } else if (ii.targetProcesses.equals("*")) {
19937                 activeInstr.mTargetProcesses = new String[0];
19938             } else {
19939                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19940                 defProcess = activeInstr.mTargetProcesses[0];
19941             }
19942             activeInstr.mTargetInfo = ai;
19943             activeInstr.mProfileFile = profileFile;
19944             activeInstr.mArguments = arguments;
19945             activeInstr.mWatcher = watcher;
19946             activeInstr.mUiAutomationConnection = uiAutomationConnection;
19947             activeInstr.mResultClass = className;
19948
19949             final long origId = Binder.clearCallingIdentity();
19950             // Instrumentation can kill and relaunch even persistent processes
19951             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19952                     "start instr");
19953             ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19954             app.instr = activeInstr;
19955             activeInstr.mFinished = false;
19956             activeInstr.mRunningProcesses.add(app);
19957             if (!mActiveInstrumentation.contains(activeInstr)) {
19958                 mActiveInstrumentation.add(activeInstr);
19959             }
19960             Binder.restoreCallingIdentity(origId);
19961         }
19962
19963         return true;
19964     }
19965
19966     /**
19967      * Report errors that occur while attempting to start Instrumentation.  Always writes the
19968      * error to the logs, but if somebody is watching, send the report there too.  This enables
19969      * the "am" command to report errors with more information.
19970      *
19971      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19972      * @param cn The component name of the instrumentation.
19973      * @param report The error report.
19974      */
19975     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19976             ComponentName cn, String report) {
19977         Slog.w(TAG, report);
19978         if (watcher != null) {
19979             Bundle results = new Bundle();
19980             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19981             results.putString("Error", report);
19982             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19983         }
19984     }
19985
19986     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19987         if (app.instr == null) {
19988             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19989             return;
19990         }
19991
19992         if (!app.instr.mFinished && results != null) {
19993             if (app.instr.mCurResults == null) {
19994                 app.instr.mCurResults = new Bundle(results);
19995             } else {
19996                 app.instr.mCurResults.putAll(results);
19997             }
19998         }
19999     }
20000
20001     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20002         int userId = UserHandle.getCallingUserId();
20003         // Refuse possible leaked file descriptors
20004         if (results != null && results.hasFileDescriptors()) {
20005             throw new IllegalArgumentException("File descriptors passed in Intent");
20006         }
20007
20008         synchronized(this) {
20009             ProcessRecord app = getRecordForAppLocked(target);
20010             if (app == null) {
20011                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20012                 return;
20013             }
20014             final long origId = Binder.clearCallingIdentity();
20015             addInstrumentationResultsLocked(app, results);
20016             Binder.restoreCallingIdentity(origId);
20017         }
20018     }
20019
20020     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20021         if (app.instr == null) {
20022             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20023             return;
20024         }
20025
20026         if (!app.instr.mFinished) {
20027             if (app.instr.mWatcher != null) {
20028                 Bundle finalResults = app.instr.mCurResults;
20029                 if (finalResults != null) {
20030                     if (app.instr.mCurResults != null && results != null) {
20031                         finalResults.putAll(results);
20032                     }
20033                 } else {
20034                     finalResults = results;
20035                 }
20036                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20037                         app.instr.mClass, resultCode, finalResults);
20038             }
20039
20040             // Can't call out of the system process with a lock held, so post a message.
20041             if (app.instr.mUiAutomationConnection != null) {
20042                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20043                         app.instr.mUiAutomationConnection).sendToTarget();
20044             }
20045             app.instr.mFinished = true;
20046         }
20047
20048         app.instr.removeProcess(app);
20049         app.instr = null;
20050
20051         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20052                 "finished inst");
20053     }
20054
20055     public void finishInstrumentation(IApplicationThread target,
20056             int resultCode, Bundle results) {
20057         int userId = UserHandle.getCallingUserId();
20058         // Refuse possible leaked file descriptors
20059         if (results != null && results.hasFileDescriptors()) {
20060             throw new IllegalArgumentException("File descriptors passed in Intent");
20061         }
20062
20063         synchronized(this) {
20064             ProcessRecord app = getRecordForAppLocked(target);
20065             if (app == null) {
20066                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20067                 return;
20068             }
20069             final long origId = Binder.clearCallingIdentity();
20070             finishInstrumentationLocked(app, resultCode, results);
20071             Binder.restoreCallingIdentity(origId);
20072         }
20073     }
20074
20075     // =========================================================
20076     // CONFIGURATION
20077     // =========================================================
20078
20079     public ConfigurationInfo getDeviceConfigurationInfo() {
20080         ConfigurationInfo config = new ConfigurationInfo();
20081         synchronized (this) {
20082             final Configuration globalConfig = getGlobalConfiguration();
20083             config.reqTouchScreen = globalConfig.touchscreen;
20084             config.reqKeyboardType = globalConfig.keyboard;
20085             config.reqNavigation = globalConfig.navigation;
20086             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20087                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20088                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20089             }
20090             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20091                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20092                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20093             }
20094             config.reqGlEsVersion = GL_ES_VERSION;
20095         }
20096         return config;
20097     }
20098
20099     ActivityStack getFocusedStack() {
20100         return mStackSupervisor.getFocusedStack();
20101     }
20102
20103     @Override
20104     public int getFocusedStackId() throws RemoteException {
20105         ActivityStack focusedStack = getFocusedStack();
20106         if (focusedStack != null) {
20107             return focusedStack.getStackId();
20108         }
20109         return -1;
20110     }
20111
20112     public Configuration getConfiguration() {
20113         Configuration ci;
20114         synchronized(this) {
20115             ci = new Configuration(getGlobalConfiguration());
20116             ci.userSetLocale = false;
20117         }
20118         return ci;
20119     }
20120
20121     @Override
20122     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20123         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20124         synchronized (this) {
20125             mSuppressResizeConfigChanges = suppress;
20126         }
20127     }
20128
20129     /**
20130      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20131      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20132      *       activity and clearing the task at the same time.
20133      */
20134     @Override
20135     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20136         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20137         if (StackId.isHomeOrRecentsStack(fromStackId)) {
20138             throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20139         }
20140         synchronized (this) {
20141             final long origId = Binder.clearCallingIdentity();
20142             try {
20143                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20144             } finally {
20145                 Binder.restoreCallingIdentity(origId);
20146             }
20147         }
20148     }
20149
20150     @Override
20151     public void updatePersistentConfiguration(Configuration values) {
20152         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20153         enforceWriteSettingsPermission("updatePersistentConfiguration()");
20154         if (values == null) {
20155             throw new NullPointerException("Configuration must not be null");
20156         }
20157
20158         int userId = UserHandle.getCallingUserId();
20159
20160         synchronized(this) {
20161             updatePersistentConfigurationLocked(values, userId);
20162         }
20163     }
20164
20165     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20166         final long origId = Binder.clearCallingIdentity();
20167         try {
20168             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20169         } finally {
20170             Binder.restoreCallingIdentity(origId);
20171         }
20172     }
20173
20174     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20175         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20176                 FONT_SCALE, 1.0f, userId);
20177
20178         synchronized (this) {
20179             if (getGlobalConfiguration().fontScale == scaleFactor) {
20180                 return;
20181             }
20182
20183             final Configuration configuration
20184                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20185             configuration.fontScale = scaleFactor;
20186             updatePersistentConfigurationLocked(configuration, userId);
20187         }
20188     }
20189
20190     private void enforceWriteSettingsPermission(String func) {
20191         int uid = Binder.getCallingUid();
20192         if (uid == ROOT_UID) {
20193             return;
20194         }
20195
20196         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20197                 Settings.getPackageNameForUid(mContext, uid), false)) {
20198             return;
20199         }
20200
20201         String msg = "Permission Denial: " + func + " from pid="
20202                 + Binder.getCallingPid()
20203                 + ", uid=" + uid
20204                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20205         Slog.w(TAG, msg);
20206         throw new SecurityException(msg);
20207     }
20208
20209     @Override
20210     public boolean updateConfiguration(Configuration values) {
20211         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20212
20213         synchronized(this) {
20214             if (values == null && mWindowManager != null) {
20215                 // sentinel: fetch the current configuration from the window manager
20216                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20217             }
20218
20219             if (mWindowManager != null) {
20220                 // Update OOM levels based on display size.
20221                 mProcessList.applyDisplaySize(mWindowManager);
20222             }
20223
20224             final long origId = Binder.clearCallingIdentity();
20225             try {
20226                 if (values != null) {
20227                     Settings.System.clearConfiguration(values);
20228                 }
20229                 updateConfigurationLocked(values, null, false, false /* persistent */,
20230                         UserHandle.USER_NULL, false /* deferResume */,
20231                         mTmpUpdateConfigurationResult);
20232                 return mTmpUpdateConfigurationResult.changes != 0;
20233             } finally {
20234                 Binder.restoreCallingIdentity(origId);
20235             }
20236         }
20237     }
20238
20239     void updateUserConfigurationLocked() {
20240         final Configuration configuration = new Configuration(getGlobalConfiguration());
20241         final int currentUserId = mUserController.getCurrentUserIdLocked();
20242         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20243                 currentUserId, Settings.System.canWrite(mContext));
20244         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20245                 false /* persistent */, currentUserId, false /* deferResume */);
20246     }
20247
20248     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20249             boolean initLocale) {
20250         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20251     }
20252
20253     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20254             boolean initLocale, boolean deferResume) {
20255         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20256         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20257                 UserHandle.USER_NULL, deferResume);
20258     }
20259
20260     // To cache the list of supported system locales
20261     private String[] mSupportedSystemLocales = null;
20262
20263     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20264             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20265         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20266                 deferResume, null /* result */);
20267     }
20268
20269     /**
20270      * Do either or both things: (1) change the current configuration, and (2)
20271      * make sure the given activity is running with the (now) current
20272      * configuration.  Returns true if the activity has been left running, or
20273      * false if <var>starting</var> is being destroyed to match the new
20274      * configuration.
20275      *
20276      * @param userId is only used when persistent parameter is set to true to persist configuration
20277      *               for that particular user
20278      */
20279     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20280             boolean initLocale, boolean persistent, int userId, boolean deferResume,
20281             UpdateConfigurationResult result) {
20282         int changes = 0;
20283         boolean kept = true;
20284
20285         if (mWindowManager != null) {
20286             mWindowManager.deferSurfaceLayout();
20287         }
20288         try {
20289             if (values != null) {
20290                 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20291                         deferResume);
20292             }
20293
20294             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20295         } finally {
20296             if (mWindowManager != null) {
20297                 mWindowManager.continueSurfaceLayout();
20298             }
20299         }
20300
20301         if (result != null) {
20302             result.changes = changes;
20303             result.activityRelaunched = !kept;
20304         }
20305         return kept;
20306     }
20307
20308     /** Update default (global) configuration and notify listeners about changes. */
20309     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20310             boolean persistent, int userId, boolean deferResume) {
20311         mTempConfig.setTo(getGlobalConfiguration());
20312         final int changes = mTempConfig.updateFrom(values);
20313         if (changes == 0) {
20314             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20315             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20316             // performDisplayOverrideConfigUpdate in order to send the new display configuration
20317             // (even if there are no actual changes) to unfreeze the window.
20318             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20319             return 0;
20320         }
20321
20322         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20323                 "Updating global configuration to: " + values);
20324
20325         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20326
20327         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20328             final LocaleList locales = values.getLocales();
20329             int bestLocaleIndex = 0;
20330             if (locales.size() > 1) {
20331                 if (mSupportedSystemLocales == null) {
20332                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20333                 }
20334                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20335             }
20336             SystemProperties.set("persist.sys.locale",
20337                     locales.get(bestLocaleIndex).toLanguageTag());
20338             LocaleList.setDefault(locales, bestLocaleIndex);
20339             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20340                     locales.get(bestLocaleIndex)));
20341         }
20342
20343         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20344         mTempConfig.seq = mConfigurationSeq;
20345
20346         // Update stored global config and notify everyone about the change.
20347         mStackSupervisor.onConfigurationChanged(mTempConfig);
20348
20349         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20350         // TODO(multi-display): Update UsageEvents#Event to include displayId.
20351         mUsageStatsService.reportConfigurationChange(mTempConfig,
20352                 mUserController.getCurrentUserIdLocked());
20353
20354         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20355         mShowDialogs = shouldShowDialogs(mTempConfig);
20356
20357         AttributeCache ac = AttributeCache.instance();
20358         if (ac != null) {
20359             ac.updateConfiguration(mTempConfig);
20360         }
20361
20362         // Make sure all resources in our process are updated right now, so that anyone who is going
20363         // to retrieve resource values after we return will be sure to get the new ones. This is
20364         // especially important during boot, where the first config change needs to guarantee all
20365         // resources have that config before following boot code is executed.
20366         mSystemThread.applyConfigurationToResources(mTempConfig);
20367
20368         // We need another copy of global config because we're scheduling some calls instead of
20369         // running them in place. We need to be sure that object we send will be handled unchanged.
20370         final Configuration configCopy = new Configuration(mTempConfig);
20371         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20372             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20373             msg.obj = configCopy;
20374             msg.arg1 = userId;
20375             mHandler.sendMessage(msg);
20376         }
20377
20378         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20379             ProcessRecord app = mLruProcesses.get(i);
20380             try {
20381                 if (app.thread != null) {
20382                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20383                             + app.processName + " new config " + configCopy);
20384                     app.thread.scheduleConfigurationChanged(configCopy);
20385                 }
20386             } catch (Exception e) {
20387             }
20388         }
20389
20390         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20391         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20392                 | Intent.FLAG_RECEIVER_FOREGROUND
20393                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20394         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20395                 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20396                 UserHandle.USER_ALL);
20397         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20398             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20399             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20400                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20401                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20402             if (initLocale || !mProcessesReady) {
20403                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20404             }
20405             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20406                     AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20407                     UserHandle.USER_ALL);
20408         }
20409
20410         // Override configuration of the default display duplicates global config, so we need to
20411         // update it also. This will also notify WindowManager about changes.
20412         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20413                 DEFAULT_DISPLAY);
20414
20415         return changes;
20416     }
20417
20418     @Override
20419     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20420         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20421
20422         synchronized (this) {
20423             // Check if display is initialized in AM.
20424             if (!mStackSupervisor.isDisplayAdded(displayId)) {
20425                 // Call might come when display is not yet added or has already been removed.
20426                 if (DEBUG_CONFIGURATION) {
20427                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20428                             + displayId);
20429                 }
20430                 return false;
20431             }
20432
20433             if (values == null && mWindowManager != null) {
20434                 // sentinel: fetch the current configuration from the window manager
20435                 values = mWindowManager.computeNewConfiguration(displayId);
20436             }
20437
20438             if (mWindowManager != null) {
20439                 // Update OOM levels based on display size.
20440                 mProcessList.applyDisplaySize(mWindowManager);
20441             }
20442
20443             final long origId = Binder.clearCallingIdentity();
20444             try {
20445                 if (values != null) {
20446                     Settings.System.clearConfiguration(values);
20447                 }
20448                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20449                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20450                 return mTmpUpdateConfigurationResult.changes != 0;
20451             } finally {
20452                 Binder.restoreCallingIdentity(origId);
20453             }
20454         }
20455     }
20456
20457     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20458             boolean deferResume, int displayId) {
20459         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20460                 displayId, null /* result */);
20461     }
20462
20463     /**
20464      * Updates override configuration specific for the selected display. If no config is provided,
20465      * new one will be computed in WM based on current display info.
20466      */
20467     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20468             ActivityRecord starting, boolean deferResume, int displayId,
20469             UpdateConfigurationResult result) {
20470         int changes = 0;
20471         boolean kept = true;
20472
20473         if (mWindowManager != null) {
20474             mWindowManager.deferSurfaceLayout();
20475         }
20476         try {
20477             if (values != null) {
20478                 if (displayId == DEFAULT_DISPLAY) {
20479                     // Override configuration of the default display duplicates global config, so
20480                     // we're calling global config update instead for default display. It will also
20481                     // apply the correct override config.
20482                     changes = updateGlobalConfiguration(values, false /* initLocale */,
20483                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20484                 } else {
20485                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20486                 }
20487             }
20488
20489             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20490         } finally {
20491             if (mWindowManager != null) {
20492                 mWindowManager.continueSurfaceLayout();
20493             }
20494         }
20495
20496         if (result != null) {
20497             result.changes = changes;
20498             result.activityRelaunched = !kept;
20499         }
20500         return kept;
20501     }
20502
20503     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20504             int displayId) {
20505         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20506         final int changes = mTempConfig.updateFrom(values);
20507         if (changes != 0) {
20508             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20509                     + mTempConfig + " for displayId=" + displayId);
20510             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20511
20512             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20513             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20514                 // Reset the unsupported display size dialog.
20515                 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20516
20517                 killAllBackgroundProcessesExcept(N,
20518                         ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20519             }
20520         }
20521
20522         // Update the configuration with WM first and check if any of the stacks need to be resized
20523         // due to the configuration change. If so, resize the stacks now and do any relaunches if
20524         // necessary. This way we don't need to relaunch again afterwards in
20525         // ensureActivityConfigurationLocked().
20526         if (mWindowManager != null) {
20527             final int[] resizedStacks =
20528                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20529             if (resizedStacks != null) {
20530                 for (int stackId : resizedStacks) {
20531                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20532                 }
20533             }
20534         }
20535
20536         return changes;
20537     }
20538
20539     /** Applies latest configuration and/or visibility updates if needed. */
20540     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20541         boolean kept = true;
20542         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20543         // mainStack is null during startup.
20544         if (mainStack != null) {
20545             if (changes != 0 && starting == null) {
20546                 // If the configuration changed, and the caller is not already
20547                 // in the process of starting an activity, then find the top
20548                 // activity to check if its configuration needs to change.
20549                 starting = mainStack.topRunningActivityLocked();
20550             }
20551
20552             if (starting != null) {
20553                 kept = starting.ensureActivityConfigurationLocked(changes,
20554                         false /* preserveWindow */);
20555                 // And we need to make sure at this point that all other activities
20556                 // are made visible with the correct configuration.
20557                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20558                         !PRESERVE_WINDOWS);
20559             }
20560         }
20561
20562         return kept;
20563     }
20564
20565     /** Helper method that requests bounds from WM and applies them to stack. */
20566     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20567         final Rect newStackBounds = new Rect();
20568         mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20569         mStackSupervisor.resizeStackLocked(
20570                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20571                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20572                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20573     }
20574
20575     /**
20576      * Decide based on the configuration whether we should show the ANR,
20577      * crash, etc dialogs.  The idea is that if there is no affordance to
20578      * press the on-screen buttons, or the user experience would be more
20579      * greatly impacted than the crash itself, we shouldn't show the dialog.
20580      *
20581      * A thought: SystemUI might also want to get told about this, the Power
20582      * dialog / global actions also might want different behaviors.
20583      */
20584     private static boolean shouldShowDialogs(Configuration config) {
20585         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20586                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20587                                    && config.navigation == Configuration.NAVIGATION_NONAV);
20588         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20589         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20590                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20591                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20592                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20593         return inputMethodExists && uiModeSupportsDialogs;
20594     }
20595
20596     @Override
20597     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20598         synchronized (this) {
20599             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20600             if (srec != null) {
20601                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20602             }
20603         }
20604         return false;
20605     }
20606
20607     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20608             Intent resultData) {
20609
20610         synchronized (this) {
20611             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20612             if (r != null) {
20613                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20614             }
20615             return false;
20616         }
20617     }
20618
20619     public int getLaunchedFromUid(IBinder activityToken) {
20620         ActivityRecord srec;
20621         synchronized (this) {
20622             srec = ActivityRecord.forTokenLocked(activityToken);
20623         }
20624         if (srec == null) {
20625             return -1;
20626         }
20627         return srec.launchedFromUid;
20628     }
20629
20630     public String getLaunchedFromPackage(IBinder activityToken) {
20631         ActivityRecord srec;
20632         synchronized (this) {
20633             srec = ActivityRecord.forTokenLocked(activityToken);
20634         }
20635         if (srec == null) {
20636             return null;
20637         }
20638         return srec.launchedFromPackage;
20639     }
20640
20641     // =========================================================
20642     // LIFETIME MANAGEMENT
20643     // =========================================================
20644
20645     // Returns whether the app is receiving broadcast.
20646     // If receiving, fetch all broadcast queues which the app is
20647     // the current [or imminent] receiver on.
20648     private boolean isReceivingBroadcastLocked(ProcessRecord app,
20649             ArraySet<BroadcastQueue> receivingQueues) {
20650         if (!app.curReceivers.isEmpty()) {
20651             for (BroadcastRecord r : app.curReceivers) {
20652                 receivingQueues.add(r.queue);
20653             }
20654             return true;
20655         }
20656
20657         // It's not the current receiver, but it might be starting up to become one
20658         for (BroadcastQueue queue : mBroadcastQueues) {
20659             final BroadcastRecord r = queue.mPendingBroadcast;
20660             if (r != null && r.curApp == app) {
20661                 // found it; report which queue it's in
20662                 receivingQueues.add(queue);
20663             }
20664         }
20665
20666         return !receivingQueues.isEmpty();
20667     }
20668
20669     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20670             int targetUid, ComponentName targetComponent, String targetProcess) {
20671         if (!mTrackingAssociations) {
20672             return null;
20673         }
20674         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20675                 = mAssociations.get(targetUid);
20676         if (components == null) {
20677             components = new ArrayMap<>();
20678             mAssociations.put(targetUid, components);
20679         }
20680         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20681         if (sourceUids == null) {
20682             sourceUids = new SparseArray<>();
20683             components.put(targetComponent, sourceUids);
20684         }
20685         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20686         if (sourceProcesses == null) {
20687             sourceProcesses = new ArrayMap<>();
20688             sourceUids.put(sourceUid, sourceProcesses);
20689         }
20690         Association ass = sourceProcesses.get(sourceProcess);
20691         if (ass == null) {
20692             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20693                     targetProcess);
20694             sourceProcesses.put(sourceProcess, ass);
20695         }
20696         ass.mCount++;
20697         ass.mNesting++;
20698         if (ass.mNesting == 1) {
20699             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20700             ass.mLastState = sourceState;
20701         }
20702         return ass;
20703     }
20704
20705     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20706             ComponentName targetComponent) {
20707         if (!mTrackingAssociations) {
20708             return;
20709         }
20710         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20711                 = mAssociations.get(targetUid);
20712         if (components == null) {
20713             return;
20714         }
20715         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20716         if (sourceUids == null) {
20717             return;
20718         }
20719         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20720         if (sourceProcesses == null) {
20721             return;
20722         }
20723         Association ass = sourceProcesses.get(sourceProcess);
20724         if (ass == null || ass.mNesting <= 0) {
20725             return;
20726         }
20727         ass.mNesting--;
20728         if (ass.mNesting == 0) {
20729             long uptime = SystemClock.uptimeMillis();
20730             ass.mTime += uptime - ass.mStartTime;
20731             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20732                     += uptime - ass.mLastStateUptime;
20733             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20734         }
20735     }
20736
20737     private void noteUidProcessState(final int uid, final int state) {
20738         mBatteryStatsService.noteUidProcessState(uid, state);
20739         if (mTrackingAssociations) {
20740             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20741                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20742                         = mAssociations.valueAt(i1);
20743                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20744                     SparseArray<ArrayMap<String, Association>> sourceUids
20745                             = targetComponents.valueAt(i2);
20746                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20747                     if (sourceProcesses != null) {
20748                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20749                             Association ass = sourceProcesses.valueAt(i4);
20750                             if (ass.mNesting >= 1) {
20751                                 // currently associated
20752                                 long uptime = SystemClock.uptimeMillis();
20753                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20754                                         += uptime - ass.mLastStateUptime;
20755                                 ass.mLastState = state;
20756                                 ass.mLastStateUptime = uptime;
20757                             }
20758                         }
20759                     }
20760                 }
20761             }
20762         }
20763     }
20764
20765     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20766             boolean doingAll, long now) {
20767         if (mAdjSeq == app.adjSeq) {
20768             // This adjustment has already been computed.
20769             return app.curRawAdj;
20770         }
20771
20772         if (app.thread == null) {
20773             app.adjSeq = mAdjSeq;
20774             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20775             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20776             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20777         }
20778
20779         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20780         app.adjSource = null;
20781         app.adjTarget = null;
20782         app.empty = false;
20783         app.cached = false;
20784
20785         final int activitiesSize = app.activities.size();
20786
20787         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20788             // The max adjustment doesn't allow this app to be anything
20789             // below foreground, so it is not worth doing work for it.
20790             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20791             app.adjType = "fixed";
20792             app.adjSeq = mAdjSeq;
20793             app.curRawAdj = app.maxAdj;
20794             app.foregroundActivities = false;
20795             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20796             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20797             // System processes can do UI, and when they do we want to have
20798             // them trim their memory after the user leaves the UI.  To
20799             // facilitate this, here we need to determine whether or not it
20800             // is currently showing UI.
20801             app.systemNoUi = true;
20802             if (app == TOP_APP) {
20803                 app.systemNoUi = false;
20804                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20805                 app.adjType = "pers-top-activity";
20806             } else if (app.hasTopUi) {
20807                 app.systemNoUi = false;
20808                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20809                 app.adjType = "pers-top-ui";
20810             } else if (activitiesSize > 0) {
20811                 for (int j = 0; j < activitiesSize; j++) {
20812                     final ActivityRecord r = app.activities.get(j);
20813                     if (r.visible) {
20814                         app.systemNoUi = false;
20815                     }
20816                 }
20817             }
20818             if (!app.systemNoUi) {
20819                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20820             }
20821             return (app.curAdj=app.maxAdj);
20822         }
20823
20824         app.systemNoUi = false;
20825
20826         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20827
20828         // Determine the importance of the process, starting with most
20829         // important to least, and assign an appropriate OOM adjustment.
20830         int adj;
20831         int schedGroup;
20832         int procState;
20833         boolean foregroundActivities = false;
20834         mTmpBroadcastQueue.clear();
20835         if (app == TOP_APP) {
20836             // The last app on the list is the foreground app.
20837             adj = ProcessList.FOREGROUND_APP_ADJ;
20838             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20839             app.adjType = "top-activity";
20840             foregroundActivities = true;
20841             procState = PROCESS_STATE_CUR_TOP;
20842             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20843         } else if (app.instr != null) {
20844             // Don't want to kill running instrumentation.
20845             adj = ProcessList.FOREGROUND_APP_ADJ;
20846             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20847             app.adjType = "instrumentation";
20848             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20849             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20850         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20851             // An app that is currently receiving a broadcast also
20852             // counts as being in the foreground for OOM killer purposes.
20853             // It's placed in a sched group based on the nature of the
20854             // broadcast as reflected by which queue it's active in.
20855             adj = ProcessList.FOREGROUND_APP_ADJ;
20856             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20857                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20858             app.adjType = "broadcast";
20859             procState = ActivityManager.PROCESS_STATE_RECEIVER;
20860             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20861         } else if (app.executingServices.size() > 0) {
20862             // An app that is currently executing a service callback also
20863             // counts as being in the foreground.
20864             adj = ProcessList.FOREGROUND_APP_ADJ;
20865             schedGroup = app.execServicesFg ?
20866                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20867             app.adjType = "exec-service";
20868             procState = ActivityManager.PROCESS_STATE_SERVICE;
20869             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20870             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20871         } else {
20872             // As far as we know the process is empty.  We may change our mind later.
20873             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20874             // At this point we don't actually know the adjustment.  Use the cached adj
20875             // value that the caller wants us to.
20876             adj = cachedAdj;
20877             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20878             app.cached = true;
20879             app.empty = true;
20880             app.adjType = "cch-empty";
20881             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20882         }
20883
20884         // Examine all activities if not already foreground.
20885         if (!foregroundActivities && activitiesSize > 0) {
20886             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20887             for (int j = 0; j < activitiesSize; j++) {
20888                 final ActivityRecord r = app.activities.get(j);
20889                 if (r.app != app) {
20890                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20891                             + " instead of expected " + app);
20892                     if (r.app == null || (r.app.uid == app.uid)) {
20893                         // Only fix things up when they look sane
20894                         r.app = app;
20895                     } else {
20896                         continue;
20897                     }
20898                 }
20899                 if (r.visible) {
20900                     // App has a visible activity; only upgrade adjustment.
20901                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
20902                         adj = ProcessList.VISIBLE_APP_ADJ;
20903                         app.adjType = "vis-activity";
20904                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20905                     }
20906                     if (procState > PROCESS_STATE_CUR_TOP) {
20907                         procState = PROCESS_STATE_CUR_TOP;
20908                         app.adjType = "vis-activity";
20909                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20910                     }
20911                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20912                     app.cached = false;
20913                     app.empty = false;
20914                     foregroundActivities = true;
20915                     final TaskRecord task = r.getTask();
20916                     if (task != null && minLayer > 0) {
20917                         final int layer = task.mLayerRank;
20918                         if (layer >= 0 && minLayer > layer) {
20919                             minLayer = layer;
20920                         }
20921                     }
20922                     break;
20923                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20924                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20925                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20926                         app.adjType = "pause-activity";
20927                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20928                     }
20929                     if (procState > PROCESS_STATE_CUR_TOP) {
20930                         procState = PROCESS_STATE_CUR_TOP;
20931                         app.adjType = "pause-activity";
20932                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20933                     }
20934                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20935                     app.cached = false;
20936                     app.empty = false;
20937                     foregroundActivities = true;
20938                 } else if (r.state == ActivityState.STOPPING) {
20939                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20940                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20941                         app.adjType = "stop-activity";
20942                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20943                     }
20944                     // For the process state, we will at this point consider the
20945                     // process to be cached.  It will be cached either as an activity
20946                     // or empty depending on whether the activity is finishing.  We do
20947                     // this so that we can treat the process as cached for purposes of
20948                     // memory trimming (determing current memory level, trim command to
20949                     // send to process) since there can be an arbitrary number of stopping
20950                     // processes and they should soon all go into the cached state.
20951                     if (!r.finishing) {
20952                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20953                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20954                             app.adjType = "stop-activity";
20955                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20956                         }
20957                     }
20958                     app.cached = false;
20959                     app.empty = false;
20960                     foregroundActivities = true;
20961                 } else {
20962                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20963                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20964                         app.adjType = "cch-act";
20965                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
20966                     }
20967                 }
20968             }
20969             if (adj == ProcessList.VISIBLE_APP_ADJ) {
20970                 adj += minLayer;
20971             }
20972         }
20973
20974         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20975                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20976             if (app.foregroundServices) {
20977                 // The user is aware of this app, so make it visible.
20978                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20979                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20980                 app.cached = false;
20981                 app.adjType = "fg-service";
20982                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20983                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
20984             } else if (app.hasOverlayUi) {
20985                 // The process is display an overlay UI.
20986                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20987                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20988                 app.cached = false;
20989                 app.adjType = "has-overlay-ui";
20990                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20991                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
20992             }
20993         }
20994
20995         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20996                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
20997             if (app.forcingToImportant != null) {
20998                 // This is currently used for toasts...  they are not interactive, and
20999                 // we don't want them to cause the app to become fully foreground (and
21000                 // thus out of background check), so we yes the best background level we can.
21001                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21002                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21003                 app.cached = false;
21004                 app.adjType = "force-imp";
21005                 app.adjSource = app.forcingToImportant;
21006                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21007                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21008             }
21009         }
21010
21011         if (app == mHeavyWeightProcess) {
21012             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21013                 // We don't want to kill the current heavy-weight process.
21014                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21015                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21016                 app.cached = false;
21017                 app.adjType = "heavy";
21018                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21019             }
21020             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21021                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21022                 app.adjType = "heavy";
21023                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21024             }
21025         }
21026
21027         if (app == mHomeProcess) {
21028             if (adj > ProcessList.HOME_APP_ADJ) {
21029                 // This process is hosting what we currently consider to be the
21030                 // home app, so we don't want to let it go into the background.
21031                 adj = ProcessList.HOME_APP_ADJ;
21032                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21033                 app.cached = false;
21034                 app.adjType = "home";
21035                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21036             }
21037             if (procState > ActivityManager.PROCESS_STATE_HOME) {
21038                 procState = ActivityManager.PROCESS_STATE_HOME;
21039                 app.adjType = "home";
21040                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21041             }
21042         }
21043
21044         if (app == mPreviousProcess && app.activities.size() > 0) {
21045             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21046                 // This was the previous process that showed UI to the user.
21047                 // We want to try to keep it around more aggressively, to give
21048                 // a good experience around switching between two apps.
21049                 adj = ProcessList.PREVIOUS_APP_ADJ;
21050                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21051                 app.cached = false;
21052                 app.adjType = "previous";
21053                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21054             }
21055             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21056                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21057                 app.adjType = "previous";
21058                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21059             }
21060         }
21061
21062         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21063                 + " reason=" + app.adjType);
21064
21065         // By default, we use the computed adjustment.  It may be changed if
21066         // there are applications dependent on our services or providers, but
21067         // this gives us a baseline and makes sure we don't get into an
21068         // infinite recursion.
21069         app.adjSeq = mAdjSeq;
21070         app.curRawAdj = adj;
21071         app.hasStartedServices = false;
21072
21073         if (mBackupTarget != null && app == mBackupTarget.app) {
21074             // If possible we want to avoid killing apps while they're being backed up
21075             if (adj > ProcessList.BACKUP_APP_ADJ) {
21076                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21077                 adj = ProcessList.BACKUP_APP_ADJ;
21078                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21079                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21080                 }
21081                 app.adjType = "backup";
21082                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21083                 app.cached = false;
21084             }
21085             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21086                 procState = ActivityManager.PROCESS_STATE_BACKUP;
21087                 app.adjType = "backup";
21088                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21089             }
21090         }
21091
21092         boolean mayBeTop = false;
21093         String mayBeTopType = null;
21094         Object mayBeTopSource = null;
21095         Object mayBeTopTarget = null;
21096
21097         for (int is = app.services.size()-1;
21098                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21099                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21100                         || procState > ActivityManager.PROCESS_STATE_TOP);
21101                 is--) {
21102             ServiceRecord s = app.services.valueAt(is);
21103             if (s.startRequested) {
21104                 app.hasStartedServices = true;
21105                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21106                     procState = ActivityManager.PROCESS_STATE_SERVICE;
21107                     app.adjType = "started-services";
21108                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21109                 }
21110                 if (app.hasShownUi && app != mHomeProcess) {
21111                     // If this process has shown some UI, let it immediately
21112                     // go to the LRU list because it may be pretty heavy with
21113                     // UI stuff.  We'll tag it with a label just to help
21114                     // debug and understand what is going on.
21115                     if (adj > ProcessList.SERVICE_ADJ) {
21116                         app.adjType = "cch-started-ui-services";
21117                     }
21118                 } else {
21119                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21120                         // This service has seen some activity within
21121                         // recent memory, so we will keep its process ahead
21122                         // of the background processes.
21123                         if (adj > ProcessList.SERVICE_ADJ) {
21124                             adj = ProcessList.SERVICE_ADJ;
21125                             app.adjType = "started-services";
21126                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21127                             app.cached = false;
21128                         }
21129                     }
21130                     // If we have let the service slide into the background
21131                     // state, still have some text describing what it is doing
21132                     // even though the service no longer has an impact.
21133                     if (adj > ProcessList.SERVICE_ADJ) {
21134                         app.adjType = "cch-started-services";
21135                     }
21136                 }
21137             }
21138
21139             for (int conni = s.connections.size()-1;
21140                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21141                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21142                             || procState > ActivityManager.PROCESS_STATE_TOP);
21143                     conni--) {
21144                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21145                 for (int i = 0;
21146                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21147                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21148                                 || procState > ActivityManager.PROCESS_STATE_TOP);
21149                         i++) {
21150                     // XXX should compute this based on the max of
21151                     // all connected clients.
21152                     ConnectionRecord cr = clist.get(i);
21153                     if (cr.binding.client == app) {
21154                         // Binding to ourself is not interesting.
21155                         continue;
21156                     }
21157
21158                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21159                         ProcessRecord client = cr.binding.client;
21160                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
21161                                 TOP_APP, doingAll, now);
21162                         int clientProcState = client.curProcState;
21163                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21164                             // If the other app is cached for any reason, for purposes here
21165                             // we are going to consider it empty.  The specific cached state
21166                             // doesn't propagate except under certain conditions.
21167                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21168                         }
21169                         String adjType = null;
21170                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21171                             // Not doing bind OOM management, so treat
21172                             // this guy more like a started service.
21173                             if (app.hasShownUi && app != mHomeProcess) {
21174                                 // If this process has shown some UI, let it immediately
21175                                 // go to the LRU list because it may be pretty heavy with
21176                                 // UI stuff.  We'll tag it with a label just to help
21177                                 // debug and understand what is going on.
21178                                 if (adj > clientAdj) {
21179                                     adjType = "cch-bound-ui-services";
21180                                 }
21181                                 app.cached = false;
21182                                 clientAdj = adj;
21183                                 clientProcState = procState;
21184                             } else {
21185                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21186                                     // This service has not seen activity within
21187                                     // recent memory, so allow it to drop to the
21188                                     // LRU list if there is no other reason to keep
21189                                     // it around.  We'll also tag it with a label just
21190                                     // to help debug and undertand what is going on.
21191                                     if (adj > clientAdj) {
21192                                         adjType = "cch-bound-services";
21193                                     }
21194                                     clientAdj = adj;
21195                                 }
21196                             }
21197                         }
21198                         if (adj > clientAdj) {
21199                             // If this process has recently shown UI, and
21200                             // the process that is binding to it is less
21201                             // important than being visible, then we don't
21202                             // care about the binding as much as we care
21203                             // about letting this process get into the LRU
21204                             // list to be killed and restarted if needed for
21205                             // memory.
21206                             if (app.hasShownUi && app != mHomeProcess
21207                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21208                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21209                                     adjType = "cch-bound-ui-services";
21210                                 }
21211                             } else {
21212                                 int newAdj;
21213                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21214                                         |Context.BIND_IMPORTANT)) != 0) {
21215                                     newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21216                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21217                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21218                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21219                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21220                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21221                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21222                                     newAdj = clientAdj;
21223                                 } else {
21224                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
21225                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21226                                     } else {
21227                                         newAdj = adj;
21228                                     }
21229                                 }
21230                                 if (!client.cached) {
21231                                     app.cached = false;
21232                                 }
21233                                 if (adj >  newAdj) {
21234                                     adj = newAdj;
21235                                     adjType = "service";
21236                                 }
21237                             }
21238                         }
21239                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21240                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21241                             // This will treat important bound services identically to
21242                             // the top app, which may behave differently than generic
21243                             // foreground work.
21244                             if (client.curSchedGroup > schedGroup) {
21245                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21246                                     schedGroup = client.curSchedGroup;
21247                                 } else {
21248                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21249                                 }
21250                             }
21251                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21252                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21253                                     // Special handling of clients who are in the top state.
21254                                     // We *may* want to consider this process to be in the
21255                                     // top state as well, but only if there is not another
21256                                     // reason for it to be running.  Being on the top is a
21257                                     // special state, meaning you are specifically running
21258                                     // for the current top app.  If the process is already
21259                                     // running in the background for some other reason, it
21260                                     // is more important to continue considering it to be
21261                                     // in the background state.
21262                                     mayBeTop = true;
21263                                     mayBeTopType = "service";
21264                                     mayBeTopSource = cr.binding.client;
21265                                     mayBeTopTarget = s.name;
21266                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21267                                 } else {
21268                                     // Special handling for above-top states (persistent
21269                                     // processes).  These should not bring the current process
21270                                     // into the top state, since they are not on top.  Instead
21271                                     // give them the best state after that.
21272                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21273                                         clientProcState =
21274                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21275                                     } else if (mWakefulness
21276                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21277                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21278                                                     != 0) {
21279                                         clientProcState =
21280                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21281                                     } else {
21282                                         clientProcState =
21283                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21284                                     }
21285                                 }
21286                             }
21287                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21288                             if (clientProcState <
21289                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21290                                 clientProcState =
21291                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21292                             }
21293                         } else {
21294                             if (clientProcState <
21295                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21296                                 clientProcState =
21297                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21298                             }
21299                         }
21300                         if (procState > clientProcState) {
21301                             procState = clientProcState;
21302                             if (adjType == null) {
21303                                 adjType = "service";
21304                             }
21305                         }
21306                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21307                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21308                             app.pendingUiClean = true;
21309                         }
21310                         if (adjType != null) {
21311                             app.adjType = adjType;
21312                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21313                                     .REASON_SERVICE_IN_USE;
21314                             app.adjSource = cr.binding.client;
21315                             app.adjSourceProcState = clientProcState;
21316                             app.adjTarget = s.name;
21317                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21318                                     + ": " + app + ", due to " + cr.binding.client
21319                                     + " adj=" + adj + " procState=" + procState);
21320                         }
21321                     }
21322                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21323                         app.treatLikeActivity = true;
21324                     }
21325                     final ActivityRecord a = cr.activity;
21326                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21327                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21328                             (a.visible || a.state == ActivityState.RESUMED ||
21329                              a.state == ActivityState.PAUSING)) {
21330                             adj = ProcessList.FOREGROUND_APP_ADJ;
21331                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21332                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21333                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21334                                 } else {
21335                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21336                                 }
21337                             }
21338                             app.cached = false;
21339                             app.adjType = "service";
21340                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21341                                     .REASON_SERVICE_IN_USE;
21342                             app.adjSource = a;
21343                             app.adjSourceProcState = procState;
21344                             app.adjTarget = s.name;
21345                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21346                                     + app);
21347                         }
21348                     }
21349                 }
21350             }
21351         }
21352
21353         for (int provi = app.pubProviders.size()-1;
21354                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21355                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21356                         || procState > ActivityManager.PROCESS_STATE_TOP);
21357                 provi--) {
21358             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21359             for (int i = cpr.connections.size()-1;
21360                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21361                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21362                             || procState > ActivityManager.PROCESS_STATE_TOP);
21363                     i--) {
21364                 ContentProviderConnection conn = cpr.connections.get(i);
21365                 ProcessRecord client = conn.client;
21366                 if (client == app) {
21367                     // Being our own client is not interesting.
21368                     continue;
21369                 }
21370                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21371                 int clientProcState = client.curProcState;
21372                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21373                     // If the other app is cached for any reason, for purposes here
21374                     // we are going to consider it empty.
21375                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21376                 }
21377                 String adjType = null;
21378                 if (adj > clientAdj) {
21379                     if (app.hasShownUi && app != mHomeProcess
21380                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21381                         adjType = "cch-ui-provider";
21382                     } else {
21383                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21384                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21385                         adjType = "provider";
21386                     }
21387                     app.cached &= client.cached;
21388                 }
21389                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21390                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21391                         // Special handling of clients who are in the top state.
21392                         // We *may* want to consider this process to be in the
21393                         // top state as well, but only if there is not another
21394                         // reason for it to be running.  Being on the top is a
21395                         // special state, meaning you are specifically running
21396                         // for the current top app.  If the process is already
21397                         // running in the background for some other reason, it
21398                         // is more important to continue considering it to be
21399                         // in the background state.
21400                         mayBeTop = true;
21401                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21402                         mayBeTopType = adjType = "provider-top";
21403                         mayBeTopSource = client;
21404                         mayBeTopTarget = cpr.name;
21405                     } else {
21406                         // Special handling for above-top states (persistent
21407                         // processes).  These should not bring the current process
21408                         // into the top state, since they are not on top.  Instead
21409                         // give them the best state after that.
21410                         clientProcState =
21411                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21412                         if (adjType == null) {
21413                             adjType = "provider";
21414                         }
21415                     }
21416                 }
21417                 if (procState > clientProcState) {
21418                     procState = clientProcState;
21419                 }
21420                 if (client.curSchedGroup > schedGroup) {
21421                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21422                 }
21423                 if (adjType != null) {
21424                     app.adjType = adjType;
21425                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21426                             .REASON_PROVIDER_IN_USE;
21427                     app.adjSource = client;
21428                     app.adjSourceProcState = clientProcState;
21429                     app.adjTarget = cpr.name;
21430                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21431                             + ": " + app + ", due to " + client
21432                             + " adj=" + adj + " procState=" + procState);
21433                 }
21434             }
21435             // If the provider has external (non-framework) process
21436             // dependencies, ensure that its adjustment is at least
21437             // FOREGROUND_APP_ADJ.
21438             if (cpr.hasExternalProcessHandles()) {
21439                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21440                     adj = ProcessList.FOREGROUND_APP_ADJ;
21441                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21442                     app.cached = false;
21443                     app.adjType = "ext-provider";
21444                     app.adjTarget = cpr.name;
21445                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21446                 }
21447                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21448                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21449                 }
21450             }
21451         }
21452
21453         if (app.lastProviderTime > 0 &&
21454                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21455             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21456                 adj = ProcessList.PREVIOUS_APP_ADJ;
21457                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21458                 app.cached = false;
21459                 app.adjType = "recent-provider";
21460                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21461             }
21462             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21463                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21464                 app.adjType = "recent-provider";
21465                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21466             }
21467         }
21468
21469         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21470             // A client of one of our services or providers is in the top state.  We
21471             // *may* want to be in the top state, but not if we are already running in
21472             // the background for some other reason.  For the decision here, we are going
21473             // to pick out a few specific states that we want to remain in when a client
21474             // is top (states that tend to be longer-term) and otherwise allow it to go
21475             // to the top state.
21476             switch (procState) {
21477                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21478                     // Something else is keeping it at this level, just leave it.
21479                     break;
21480                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21481                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21482                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21483                 case ActivityManager.PROCESS_STATE_SERVICE:
21484                     // These all are longer-term states, so pull them up to the top
21485                     // of the background states, but not all the way to the top state.
21486                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21487                     app.adjType = mayBeTopType;
21488                     app.adjSource = mayBeTopSource;
21489                     app.adjTarget = mayBeTopTarget;
21490                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21491                             + ": " + app + ", due to " + mayBeTopSource
21492                             + " adj=" + adj + " procState=" + procState);
21493                     break;
21494                 default:
21495                     // Otherwise, top is a better choice, so take it.
21496                     procState = ActivityManager.PROCESS_STATE_TOP;
21497                     app.adjType = mayBeTopType;
21498                     app.adjSource = mayBeTopSource;
21499                     app.adjTarget = mayBeTopTarget;
21500                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21501                             + ": " + app + ", due to " + mayBeTopSource
21502                             + " adj=" + adj + " procState=" + procState);
21503                     break;
21504             }
21505         }
21506
21507         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21508             if (app.hasClientActivities) {
21509                 // This is a cached process, but with client activities.  Mark it so.
21510                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21511                 app.adjType = "cch-client-act";
21512             } else if (app.treatLikeActivity) {
21513                 // This is a cached process, but somebody wants us to treat it like it has
21514                 // an activity, okay!
21515                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21516                 app.adjType = "cch-as-act";
21517             }
21518         }
21519
21520         if (adj == ProcessList.SERVICE_ADJ) {
21521             if (doingAll) {
21522                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21523                 mNewNumServiceProcs++;
21524                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21525                 if (!app.serviceb) {
21526                     // This service isn't far enough down on the LRU list to
21527                     // normally be a B service, but if we are low on RAM and it
21528                     // is large we want to force it down since we would prefer to
21529                     // keep launcher over it.
21530                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21531                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21532                         app.serviceHighRam = true;
21533                         app.serviceb = true;
21534                         //Slog.i(TAG, "ADJ " + app + " high ram!");
21535                     } else {
21536                         mNewNumAServiceProcs++;
21537                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
21538                     }
21539                 } else {
21540                     app.serviceHighRam = false;
21541                 }
21542             }
21543             if (app.serviceb) {
21544                 adj = ProcessList.SERVICE_B_ADJ;
21545             }
21546         }
21547
21548         app.curRawAdj = adj;
21549
21550         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21551         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21552         if (adj > app.maxAdj) {
21553             adj = app.maxAdj;
21554             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21555                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21556             }
21557         }
21558
21559         // Do final modification to adj.  Everything we do between here and applying
21560         // the final setAdj must be done in this function, because we will also use
21561         // it when computing the final cached adj later.  Note that we don't need to
21562         // worry about this for max adj above, since max adj will always be used to
21563         // keep it out of the cached vaues.
21564         app.curAdj = app.modifyRawOomAdj(adj);
21565         app.curSchedGroup = schedGroup;
21566         app.curProcState = procState;
21567         app.foregroundActivities = foregroundActivities;
21568
21569         return app.curRawAdj;
21570     }
21571
21572     /**
21573      * Record new PSS sample for a process.
21574      */
21575     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21576             long now) {
21577         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21578                 swapPss * 1024);
21579         proc.lastPssTime = now;
21580         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21581         if (DEBUG_PSS) Slog.d(TAG_PSS,
21582                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21583                 + " state=" + ProcessList.makeProcStateString(procState));
21584         if (proc.initialIdlePss == 0) {
21585             proc.initialIdlePss = pss;
21586         }
21587         proc.lastPss = pss;
21588         proc.lastSwapPss = swapPss;
21589         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21590             proc.lastCachedPss = pss;
21591             proc.lastCachedSwapPss = swapPss;
21592         }
21593
21594         final SparseArray<Pair<Long, String>> watchUids
21595                 = mMemWatchProcesses.getMap().get(proc.processName);
21596         Long check = null;
21597         if (watchUids != null) {
21598             Pair<Long, String> val = watchUids.get(proc.uid);
21599             if (val == null) {
21600                 val = watchUids.get(0);
21601             }
21602             if (val != null) {
21603                 check = val.first;
21604             }
21605         }
21606         if (check != null) {
21607             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21608                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21609                 if (!isDebuggable) {
21610                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21611                         isDebuggable = true;
21612                     }
21613                 }
21614                 if (isDebuggable) {
21615                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21616                     final ProcessRecord myProc = proc;
21617                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
21618                     mMemWatchDumpProcName = proc.processName;
21619                     mMemWatchDumpFile = heapdumpFile.toString();
21620                     mMemWatchDumpPid = proc.pid;
21621                     mMemWatchDumpUid = proc.uid;
21622                     BackgroundThread.getHandler().post(new Runnable() {
21623                         @Override
21624                         public void run() {
21625                             revokeUriPermission(ActivityThread.currentActivityThread()
21626                                             .getApplicationThread(),
21627                                     null, DumpHeapActivity.JAVA_URI,
21628                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
21629                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21630                                     UserHandle.myUserId());
21631                             ParcelFileDescriptor fd = null;
21632                             try {
21633                                 heapdumpFile.delete();
21634                                 fd = ParcelFileDescriptor.open(heapdumpFile,
21635                                         ParcelFileDescriptor.MODE_CREATE |
21636                                                 ParcelFileDescriptor.MODE_TRUNCATE |
21637                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
21638                                                 ParcelFileDescriptor.MODE_APPEND);
21639                                 IApplicationThread thread = myProc.thread;
21640                                 if (thread != null) {
21641                                     try {
21642                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
21643                                                 "Requesting dump heap from "
21644                                                 + myProc + " to " + heapdumpFile);
21645                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
21646                                     } catch (RemoteException e) {
21647                                     }
21648                                 }
21649                             } catch (FileNotFoundException e) {
21650                                 e.printStackTrace();
21651                             } finally {
21652                                 if (fd != null) {
21653                                     try {
21654                                         fd.close();
21655                                     } catch (IOException e) {
21656                                     }
21657                                 }
21658                             }
21659                         }
21660                     });
21661                 } else {
21662                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21663                             + ", but debugging not enabled");
21664                 }
21665             }
21666         }
21667     }
21668
21669     /**
21670      * Schedule PSS collection of a process.
21671      */
21672     void requestPssLocked(ProcessRecord proc, int procState) {
21673         if (mPendingPssProcesses.contains(proc)) {
21674             return;
21675         }
21676         if (mPendingPssProcesses.size() == 0) {
21677             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21678         }
21679         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21680         proc.pssProcState = procState;
21681         mPendingPssProcesses.add(proc);
21682     }
21683
21684     /**
21685      * Schedule PSS collection of all processes.
21686      */
21687     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21688         if (!always) {
21689             if (now < (mLastFullPssTime +
21690                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21691                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
21692                 return;
21693             }
21694         }
21695         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21696         mLastFullPssTime = now;
21697         mFullPssPending = true;
21698         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21699         mPendingPssProcesses.clear();
21700         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21701             ProcessRecord app = mLruProcesses.get(i);
21702             if (app.thread == null
21703                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21704                 continue;
21705             }
21706             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21707                 app.pssProcState = app.setProcState;
21708                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21709                         mTestPssMode, isSleepingLocked(), now);
21710                 mPendingPssProcesses.add(app);
21711             }
21712         }
21713         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21714     }
21715
21716     public void setTestPssMode(boolean enabled) {
21717         synchronized (this) {
21718             mTestPssMode = enabled;
21719             if (enabled) {
21720                 // Whenever we enable the mode, we want to take a snapshot all of current
21721                 // process mem use.
21722                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21723             }
21724         }
21725     }
21726
21727     /**
21728      * Ask a given process to GC right now.
21729      */
21730     final void performAppGcLocked(ProcessRecord app) {
21731         try {
21732             app.lastRequestedGc = SystemClock.uptimeMillis();
21733             if (app.thread != null) {
21734                 if (app.reportLowMemory) {
21735                     app.reportLowMemory = false;
21736                     app.thread.scheduleLowMemory();
21737                 } else {
21738                     app.thread.processInBackground();
21739                 }
21740             }
21741         } catch (Exception e) {
21742             // whatever.
21743         }
21744     }
21745
21746     /**
21747      * Returns true if things are idle enough to perform GCs.
21748      */
21749     private final boolean canGcNowLocked() {
21750         boolean processingBroadcasts = false;
21751         for (BroadcastQueue q : mBroadcastQueues) {
21752             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21753                 processingBroadcasts = true;
21754             }
21755         }
21756         return !processingBroadcasts
21757                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21758     }
21759
21760     /**
21761      * Perform GCs on all processes that are waiting for it, but only
21762      * if things are idle.
21763      */
21764     final void performAppGcsLocked() {
21765         final int N = mProcessesToGc.size();
21766         if (N <= 0) {
21767             return;
21768         }
21769         if (canGcNowLocked()) {
21770             while (mProcessesToGc.size() > 0) {
21771                 ProcessRecord proc = mProcessesToGc.remove(0);
21772                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21773                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21774                             <= SystemClock.uptimeMillis()) {
21775                         // To avoid spamming the system, we will GC processes one
21776                         // at a time, waiting a few seconds between each.
21777                         performAppGcLocked(proc);
21778                         scheduleAppGcsLocked();
21779                         return;
21780                     } else {
21781                         // It hasn't been long enough since we last GCed this
21782                         // process...  put it in the list to wait for its time.
21783                         addProcessToGcListLocked(proc);
21784                         break;
21785                     }
21786                 }
21787             }
21788
21789             scheduleAppGcsLocked();
21790         }
21791     }
21792
21793     /**
21794      * If all looks good, perform GCs on all processes waiting for them.
21795      */
21796     final void performAppGcsIfAppropriateLocked() {
21797         if (canGcNowLocked()) {
21798             performAppGcsLocked();
21799             return;
21800         }
21801         // Still not idle, wait some more.
21802         scheduleAppGcsLocked();
21803     }
21804
21805     /**
21806      * Schedule the execution of all pending app GCs.
21807      */
21808     final void scheduleAppGcsLocked() {
21809         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21810
21811         if (mProcessesToGc.size() > 0) {
21812             // Schedule a GC for the time to the next process.
21813             ProcessRecord proc = mProcessesToGc.get(0);
21814             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21815
21816             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21817             long now = SystemClock.uptimeMillis();
21818             if (when < (now+mConstants.GC_TIMEOUT)) {
21819                 when = now + mConstants.GC_TIMEOUT;
21820             }
21821             mHandler.sendMessageAtTime(msg, when);
21822         }
21823     }
21824
21825     /**
21826      * Add a process to the array of processes waiting to be GCed.  Keeps the
21827      * list in sorted order by the last GC time.  The process can't already be
21828      * on the list.
21829      */
21830     final void addProcessToGcListLocked(ProcessRecord proc) {
21831         boolean added = false;
21832         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21833             if (mProcessesToGc.get(i).lastRequestedGc <
21834                     proc.lastRequestedGc) {
21835                 added = true;
21836                 mProcessesToGc.add(i+1, proc);
21837                 break;
21838             }
21839         }
21840         if (!added) {
21841             mProcessesToGc.add(0, proc);
21842         }
21843     }
21844
21845     /**
21846      * Set up to ask a process to GC itself.  This will either do it
21847      * immediately, or put it on the list of processes to gc the next
21848      * time things are idle.
21849      */
21850     final void scheduleAppGcLocked(ProcessRecord app) {
21851         long now = SystemClock.uptimeMillis();
21852         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21853             return;
21854         }
21855         if (!mProcessesToGc.contains(app)) {
21856             addProcessToGcListLocked(app);
21857             scheduleAppGcsLocked();
21858         }
21859     }
21860
21861     final void checkExcessivePowerUsageLocked(boolean doKills) {
21862         updateCpuStatsNow();
21863
21864         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21865         boolean doWakeKills = doKills;
21866         boolean doCpuKills = doKills;
21867         if (mLastPowerCheckRealtime == 0) {
21868             doWakeKills = false;
21869         }
21870         if (mLastPowerCheckUptime == 0) {
21871             doCpuKills = false;
21872         }
21873         if (stats.isScreenOn()) {
21874             doWakeKills = false;
21875         }
21876         final long curRealtime = SystemClock.elapsedRealtime();
21877         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21878         final long curUptime = SystemClock.uptimeMillis();
21879         final long uptimeSince = curUptime - mLastPowerCheckUptime;
21880         mLastPowerCheckRealtime = curRealtime;
21881         mLastPowerCheckUptime = curUptime;
21882         if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
21883             doWakeKills = false;
21884         }
21885         if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
21886             doCpuKills = false;
21887         }
21888         int i = mLruProcesses.size();
21889         while (i > 0) {
21890             i--;
21891             ProcessRecord app = mLruProcesses.get(i);
21892             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21893                 long wtime;
21894                 synchronized (stats) {
21895                     wtime = stats.getProcessWakeTime(app.info.uid,
21896                             app.pid, curRealtime);
21897                 }
21898                 long wtimeUsed = wtime - app.lastWakeTime;
21899                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21900                 if (DEBUG_POWER) {
21901                     StringBuilder sb = new StringBuilder(128);
21902                     sb.append("Wake for ");
21903                     app.toShortString(sb);
21904                     sb.append(": over ");
21905                     TimeUtils.formatDuration(realtimeSince, sb);
21906                     sb.append(" used ");
21907                     TimeUtils.formatDuration(wtimeUsed, sb);
21908                     sb.append(" (");
21909                     sb.append((wtimeUsed*100)/realtimeSince);
21910                     sb.append("%)");
21911                     Slog.i(TAG_POWER, sb.toString());
21912                     sb.setLength(0);
21913                     sb.append("CPU for ");
21914                     app.toShortString(sb);
21915                     sb.append(": over ");
21916                     TimeUtils.formatDuration(uptimeSince, sb);
21917                     sb.append(" used ");
21918                     TimeUtils.formatDuration(cputimeUsed, sb);
21919                     sb.append(" (");
21920                     sb.append((cputimeUsed*100)/uptimeSince);
21921                     sb.append("%)");
21922                     Slog.i(TAG_POWER, sb.toString());
21923                 }
21924                 // If a process has held a wake lock for more
21925                 // than 50% of the time during this period,
21926                 // that sounds bad.  Kill!
21927                 if (doWakeKills && realtimeSince > 0
21928                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
21929                     synchronized (stats) {
21930                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21931                                 realtimeSince, wtimeUsed);
21932                     }
21933                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21934                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21935                 } else if (doCpuKills && uptimeSince > 0
21936                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
21937                     synchronized (stats) {
21938                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21939                                 uptimeSince, cputimeUsed);
21940                     }
21941                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21942                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21943                 } else {
21944                     app.lastWakeTime = wtime;
21945                     app.lastCpuTime = app.curCpuTime;
21946                 }
21947             }
21948         }
21949     }
21950
21951     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21952             long nowElapsed) {
21953         boolean success = true;
21954
21955         if (app.curRawAdj != app.setRawAdj) {
21956             app.setRawAdj = app.curRawAdj;
21957         }
21958
21959         int changes = 0;
21960
21961         if (app.curAdj != app.setAdj) {
21962             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21963             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21964                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21965                     + app.adjType);
21966             app.setAdj = app.curAdj;
21967             app.verifiedAdj = ProcessList.INVALID_ADJ;
21968         }
21969
21970         if (app.setSchedGroup != app.curSchedGroup) {
21971             int oldSchedGroup = app.setSchedGroup;
21972             app.setSchedGroup = app.curSchedGroup;
21973             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21974                     "Setting sched group of " + app.processName
21975                     + " to " + app.curSchedGroup);
21976             if (app.waitingToKill != null && app.curReceivers.isEmpty()
21977                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21978                 app.kill(app.waitingToKill, true);
21979                 success = false;
21980             } else {
21981                 int processGroup;
21982                 switch (app.curSchedGroup) {
21983                     case ProcessList.SCHED_GROUP_BACKGROUND:
21984                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21985                         break;
21986                     case ProcessList.SCHED_GROUP_TOP_APP:
21987                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21988                         processGroup = THREAD_GROUP_TOP_APP;
21989                         break;
21990                     default:
21991                         processGroup = THREAD_GROUP_DEFAULT;
21992                         break;
21993                 }
21994                 long oldId = Binder.clearCallingIdentity();
21995                 try {
21996                     setProcessGroup(app.pid, processGroup);
21997                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21998                         // do nothing if we already switched to RT
21999                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22000                             mVrController.onTopProcChangedLocked(app);
22001                             if (mUseFifoUiScheduling) {
22002                                 // Switch UI pipeline for app to SCHED_FIFO
22003                                 app.savedPriority = Process.getThreadPriority(app.pid);
22004                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22005                                 if (app.renderThreadTid != 0) {
22006                                     scheduleAsFifoPriority(app.renderThreadTid,
22007                                         /* suppressLogs */true);
22008                                     if (DEBUG_OOM_ADJ) {
22009                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
22010                                             app.renderThreadTid + ") to FIFO");
22011                                     }
22012                                 } else {
22013                                     if (DEBUG_OOM_ADJ) {
22014                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
22015                                     }
22016                                 }
22017                             } else {
22018                                 // Boost priority for top app UI and render threads
22019                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22020                                 if (app.renderThreadTid != 0) {
22021                                     try {
22022                                         setThreadPriority(app.renderThreadTid,
22023                                                 TOP_APP_PRIORITY_BOOST);
22024                                     } catch (IllegalArgumentException e) {
22025                                         // thread died, ignore
22026                                     }
22027                                 }
22028                             }
22029                         }
22030                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22031                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22032                         mVrController.onTopProcChangedLocked(app);
22033                         if (mUseFifoUiScheduling) {
22034                             // Reset UI pipeline to SCHED_OTHER
22035                             setThreadScheduler(app.pid, SCHED_OTHER, 0);
22036                             setThreadPriority(app.pid, app.savedPriority);
22037                             if (app.renderThreadTid != 0) {
22038                                 setThreadScheduler(app.renderThreadTid,
22039                                     SCHED_OTHER, 0);
22040                                 setThreadPriority(app.renderThreadTid, -4);
22041                             }
22042                         } else {
22043                             // Reset priority for top app UI and render threads
22044                             setThreadPriority(app.pid, 0);
22045                             if (app.renderThreadTid != 0) {
22046                                 setThreadPriority(app.renderThreadTid, 0);
22047                             }
22048                         }
22049                     }
22050                 } catch (Exception e) {
22051                     if (false) {
22052                         Slog.w(TAG, "Failed setting process group of " + app.pid
22053                                 + " to " + app.curSchedGroup);
22054                         Slog.w(TAG, "at location", e);
22055                     }
22056                 } finally {
22057                     Binder.restoreCallingIdentity(oldId);
22058                 }
22059             }
22060         }
22061         if (app.repForegroundActivities != app.foregroundActivities) {
22062             app.repForegroundActivities = app.foregroundActivities;
22063             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22064         }
22065         if (app.repProcState != app.curProcState) {
22066             app.repProcState = app.curProcState;
22067             if (app.thread != null) {
22068                 try {
22069                     if (false) {
22070                         //RuntimeException h = new RuntimeException("here");
22071                         Slog.i(TAG, "Sending new process state " + app.repProcState
22072                                 + " to " + app /*, h*/);
22073                     }
22074                     app.thread.setProcessState(app.repProcState);
22075                 } catch (RemoteException e) {
22076                 }
22077             }
22078         }
22079         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22080                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22081             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22082                 // Experimental code to more aggressively collect pss while
22083                 // running test...  the problem is that this tends to collect
22084                 // the data right when a process is transitioning between process
22085                 // states, which well tend to give noisy data.
22086                 long start = SystemClock.uptimeMillis();
22087                 long pss = Debug.getPss(app.pid, mTmpLong, null);
22088                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22089                 mPendingPssProcesses.remove(app);
22090                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22091                         + " to " + app.curProcState + ": "
22092                         + (SystemClock.uptimeMillis()-start) + "ms");
22093             }
22094             app.lastStateTime = now;
22095             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22096                     mTestPssMode, isSleepingLocked(), now);
22097             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22098                     + ProcessList.makeProcStateString(app.setProcState) + " to "
22099                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22100                     + (app.nextPssTime-now) + ": " + app);
22101         } else {
22102             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22103                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22104                     mTestPssMode)))) {
22105                 requestPssLocked(app, app.setProcState);
22106                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22107                         mTestPssMode, isSleepingLocked(), now);
22108             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22109                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22110         }
22111         if (app.setProcState != app.curProcState) {
22112             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22113                     "Proc state change of " + app.processName
22114                             + " to " + app.curProcState);
22115             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22116             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22117             if (setImportant && !curImportant) {
22118                 // This app is no longer something we consider important enough to allow to
22119                 // use arbitrary amounts of battery power.  Note
22120                 // its current wake lock time to later know to kill it if
22121                 // it is not behaving well.
22122                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22123                 synchronized (stats) {
22124                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
22125                             app.pid, nowElapsed);
22126                 }
22127                 app.lastCpuTime = app.curCpuTime;
22128
22129             }
22130             // Inform UsageStats of important process state change
22131             // Must be called before updating setProcState
22132             maybeUpdateUsageStatsLocked(app, nowElapsed);
22133
22134             app.setProcState = app.curProcState;
22135             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22136                 app.notCachedSinceIdle = false;
22137             }
22138             if (!doingAll) {
22139                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22140             } else {
22141                 app.procStateChanged = true;
22142             }
22143         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22144                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22145             // For apps that sit around for a long time in the interactive state, we need
22146             // to report this at least once a day so they don't go idle.
22147             maybeUpdateUsageStatsLocked(app, nowElapsed);
22148         }
22149
22150         if (changes != 0) {
22151             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22152                     "Changes in " + app + ": " + changes);
22153             int i = mPendingProcessChanges.size()-1;
22154             ProcessChangeItem item = null;
22155             while (i >= 0) {
22156                 item = mPendingProcessChanges.get(i);
22157                 if (item.pid == app.pid) {
22158                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22159                             "Re-using existing item: " + item);
22160                     break;
22161                 }
22162                 i--;
22163             }
22164             if (i < 0) {
22165                 // No existing item in pending changes; need a new one.
22166                 final int NA = mAvailProcessChanges.size();
22167                 if (NA > 0) {
22168                     item = mAvailProcessChanges.remove(NA-1);
22169                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22170                             "Retrieving available item: " + item);
22171                 } else {
22172                     item = new ProcessChangeItem();
22173                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22174                             "Allocating new item: " + item);
22175                 }
22176                 item.changes = 0;
22177                 item.pid = app.pid;
22178                 item.uid = app.info.uid;
22179                 if (mPendingProcessChanges.size() == 0) {
22180                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22181                             "*** Enqueueing dispatch processes changed!");
22182                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22183                 }
22184                 mPendingProcessChanges.add(item);
22185             }
22186             item.changes |= changes;
22187             item.foregroundActivities = app.repForegroundActivities;
22188             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22189                     "Item " + Integer.toHexString(System.identityHashCode(item))
22190                     + " " + app.toShortString() + ": changes=" + item.changes
22191                     + " foreground=" + item.foregroundActivities
22192                     + " type=" + app.adjType + " source=" + app.adjSource
22193                     + " target=" + app.adjTarget);
22194         }
22195
22196         return success;
22197     }
22198
22199     private boolean isEphemeralLocked(int uid) {
22200         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22201         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22202             return false;
22203         }
22204         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22205                 packages[0]);
22206     }
22207
22208     @VisibleForTesting
22209     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22210         final UidRecord.ChangeItem pendingChange;
22211         if (uidRec == null || uidRec.pendingChange == null) {
22212             if (mPendingUidChanges.size() == 0) {
22213                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22214                         "*** Enqueueing dispatch uid changed!");
22215                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22216             }
22217             final int NA = mAvailUidChanges.size();
22218             if (NA > 0) {
22219                 pendingChange = mAvailUidChanges.remove(NA-1);
22220                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22221                         "Retrieving available item: " + pendingChange);
22222             } else {
22223                 pendingChange = new UidRecord.ChangeItem();
22224                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22225                         "Allocating new item: " + pendingChange);
22226             }
22227             if (uidRec != null) {
22228                 uidRec.pendingChange = pendingChange;
22229                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
22230                     // If this uid is going away, and we haven't yet reported it is gone,
22231                     // then do so now.
22232                     change = UidRecord.CHANGE_GONE_IDLE;
22233                 }
22234             } else if (uid < 0) {
22235                 throw new IllegalArgumentException("No UidRecord or uid");
22236             }
22237             pendingChange.uidRecord = uidRec;
22238             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22239             mPendingUidChanges.add(pendingChange);
22240         } else {
22241             pendingChange = uidRec.pendingChange;
22242             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
22243                 change = UidRecord.CHANGE_GONE_IDLE;
22244             }
22245         }
22246         pendingChange.change = change;
22247         pendingChange.processState = uidRec != null
22248                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22249         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22250         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22251         if (uidRec != null) {
22252             uidRec.updateLastDispatchedProcStateSeq(change);
22253         }
22254
22255         // Directly update the power manager, since we sit on top of it and it is critical
22256         // it be kept in sync (so wake locks will be held as soon as appropriate).
22257         if (mLocalPowerManager != null) {
22258             switch (change) {
22259                 case UidRecord.CHANGE_GONE:
22260                 case UidRecord.CHANGE_GONE_IDLE:
22261                     mLocalPowerManager.uidGone(pendingChange.uid);
22262                     break;
22263                 case UidRecord.CHANGE_IDLE:
22264                     mLocalPowerManager.uidIdle(pendingChange.uid);
22265                     break;
22266                 case UidRecord.CHANGE_ACTIVE:
22267                     mLocalPowerManager.uidActive(pendingChange.uid);
22268                     break;
22269                 default:
22270                     mLocalPowerManager.updateUidProcState(pendingChange.uid,
22271                             pendingChange.processState);
22272                     break;
22273             }
22274         }
22275     }
22276
22277     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22278             String authority) {
22279         if (app == null) return;
22280         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22281             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22282             if (userState == null) return;
22283             final long now = SystemClock.elapsedRealtime();
22284             Long lastReported = userState.mProviderLastReportedFg.get(authority);
22285             if (lastReported == null || lastReported < now - 60 * 1000L) {
22286                 if (mSystemReady) {
22287                     // Cannot touch the user stats if not system ready
22288                     mUsageStatsService.reportContentProviderUsage(
22289                             authority, providerPkgName, app.userId);
22290                 }
22291                 userState.mProviderLastReportedFg.put(authority, now);
22292             }
22293         }
22294     }
22295
22296     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22297         if (DEBUG_USAGE_STATS) {
22298             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22299                     + "] state changes: old = " + app.setProcState + ", new = "
22300                     + app.curProcState);
22301         }
22302         if (mUsageStatsService == null) {
22303             return;
22304         }
22305         boolean isInteraction;
22306         // To avoid some abuse patterns, we are going to be careful about what we consider
22307         // to be an app interaction.  Being the top activity doesn't count while the display
22308         // is sleeping, nor do short foreground services.
22309         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22310             isInteraction = true;
22311             app.fgInteractionTime = 0;
22312         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22313             if (app.fgInteractionTime == 0) {
22314                 app.fgInteractionTime = nowElapsed;
22315                 isInteraction = false;
22316             } else {
22317                 isInteraction = nowElapsed > app.fgInteractionTime
22318                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22319             }
22320         } else {
22321             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22322             app.fgInteractionTime = 0;
22323         }
22324         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22325                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22326             app.interactionEventTime = nowElapsed;
22327             String[] packages = app.getPackageList();
22328             if (packages != null) {
22329                 for (int i = 0; i < packages.length; i++) {
22330                     mUsageStatsService.reportEvent(packages[i], app.userId,
22331                             UsageEvents.Event.SYSTEM_INTERACTION);
22332                 }
22333             }
22334         }
22335         app.reportedInteraction = isInteraction;
22336         if (!isInteraction) {
22337             app.interactionEventTime = 0;
22338         }
22339     }
22340
22341     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22342         if (proc.thread != null) {
22343             if (proc.baseProcessTracker != null) {
22344                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22345             }
22346         }
22347     }
22348
22349     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22350             ProcessRecord TOP_APP, boolean doingAll, long now) {
22351         if (app.thread == null) {
22352             return false;
22353         }
22354
22355         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22356
22357         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22358     }
22359
22360     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22361             boolean oomAdj) {
22362         if (isForeground != proc.foregroundServices) {
22363             proc.foregroundServices = isForeground;
22364             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22365                     proc.info.uid);
22366             if (isForeground) {
22367                 if (curProcs == null) {
22368                     curProcs = new ArrayList<ProcessRecord>();
22369                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22370                 }
22371                 if (!curProcs.contains(proc)) {
22372                     curProcs.add(proc);
22373                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22374                             proc.info.packageName, proc.info.uid);
22375                 }
22376             } else {
22377                 if (curProcs != null) {
22378                     if (curProcs.remove(proc)) {
22379                         mBatteryStatsService.noteEvent(
22380                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22381                                 proc.info.packageName, proc.info.uid);
22382                         if (curProcs.size() <= 0) {
22383                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22384                         }
22385                     }
22386                 }
22387             }
22388             if (oomAdj) {
22389                 updateOomAdjLocked();
22390             }
22391         }
22392     }
22393
22394     private final ActivityRecord resumedAppLocked() {
22395         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22396         String pkg;
22397         int uid;
22398         if (act != null) {
22399             pkg = act.packageName;
22400             uid = act.info.applicationInfo.uid;
22401         } else {
22402             pkg = null;
22403             uid = -1;
22404         }
22405         // Has the UID or resumed package name changed?
22406         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22407                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22408             if (mCurResumedPackage != null) {
22409                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22410                         mCurResumedPackage, mCurResumedUid);
22411             }
22412             mCurResumedPackage = pkg;
22413             mCurResumedUid = uid;
22414             if (mCurResumedPackage != null) {
22415                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22416                         mCurResumedPackage, mCurResumedUid);
22417             }
22418         }
22419         return act;
22420     }
22421
22422     /**
22423      * Update OomAdj for a specific process.
22424      * @param app The process to update
22425      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22426      *                  if necessary, or skip.
22427      * @return whether updateOomAdjLocked(app) was successful.
22428      */
22429     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22430         final ActivityRecord TOP_ACT = resumedAppLocked();
22431         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22432         final boolean wasCached = app.cached;
22433
22434         mAdjSeq++;
22435
22436         // This is the desired cached adjusment we want to tell it to use.
22437         // If our app is currently cached, we know it, and that is it.  Otherwise,
22438         // we don't know it yet, and it needs to now be cached we will then
22439         // need to do a complete oom adj.
22440         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22441                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22442         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22443                 SystemClock.uptimeMillis());
22444         if (oomAdjAll
22445                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22446             // Changed to/from cached state, so apps after it in the LRU
22447             // list may also be changed.
22448             updateOomAdjLocked();
22449         }
22450         return success;
22451     }
22452
22453     final void updateOomAdjLocked() {
22454         final ActivityRecord TOP_ACT = resumedAppLocked();
22455         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22456         final long now = SystemClock.uptimeMillis();
22457         final long nowElapsed = SystemClock.elapsedRealtime();
22458         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22459         final int N = mLruProcesses.size();
22460
22461         if (false) {
22462             RuntimeException e = new RuntimeException();
22463             e.fillInStackTrace();
22464             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22465         }
22466
22467         // Reset state in all uid records.
22468         for (int i=mActiveUids.size()-1; i>=0; i--) {
22469             final UidRecord uidRec = mActiveUids.valueAt(i);
22470             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22471                     "Starting update of " + uidRec);
22472             uidRec.reset();
22473         }
22474
22475         mStackSupervisor.rankTaskLayersIfNeeded();
22476
22477         mAdjSeq++;
22478         mNewNumServiceProcs = 0;
22479         mNewNumAServiceProcs = 0;
22480
22481         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22482         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22483
22484         // Let's determine how many processes we have running vs.
22485         // how many slots we have for background processes; we may want
22486         // to put multiple processes in a slot of there are enough of
22487         // them.
22488         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22489                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22490         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22491         if (numEmptyProcs > cachedProcessLimit) {
22492             // If there are more empty processes than our limit on cached
22493             // processes, then use the cached process limit for the factor.
22494             // This ensures that the really old empty processes get pushed
22495             // down to the bottom, so if we are running low on memory we will
22496             // have a better chance at keeping around more cached processes
22497             // instead of a gazillion empty processes.
22498             numEmptyProcs = cachedProcessLimit;
22499         }
22500         int emptyFactor = numEmptyProcs/numSlots;
22501         if (emptyFactor < 1) emptyFactor = 1;
22502         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22503         if (cachedFactor < 1) cachedFactor = 1;
22504         int stepCached = 0;
22505         int stepEmpty = 0;
22506         int numCached = 0;
22507         int numEmpty = 0;
22508         int numTrimming = 0;
22509
22510         mNumNonCachedProcs = 0;
22511         mNumCachedHiddenProcs = 0;
22512
22513         // First update the OOM adjustment for each of the
22514         // application processes based on their current state.
22515         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22516         int nextCachedAdj = curCachedAdj+1;
22517         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22518         int nextEmptyAdj = curEmptyAdj+2;
22519         for (int i=N-1; i>=0; i--) {
22520             ProcessRecord app = mLruProcesses.get(i);
22521             if (!app.killedByAm && app.thread != null) {
22522                 app.procStateChanged = false;
22523                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22524
22525                 // If we haven't yet assigned the final cached adj
22526                 // to the process, do that now.
22527                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22528                     switch (app.curProcState) {
22529                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22530                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22531                             // This process is a cached process holding activities...
22532                             // assign it the next cached value for that type, and then
22533                             // step that cached level.
22534                             app.curRawAdj = curCachedAdj;
22535                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22536                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22537                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22538                                     + ")");
22539                             if (curCachedAdj != nextCachedAdj) {
22540                                 stepCached++;
22541                                 if (stepCached >= cachedFactor) {
22542                                     stepCached = 0;
22543                                     curCachedAdj = nextCachedAdj;
22544                                     nextCachedAdj += 2;
22545                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22546                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22547                                     }
22548                                 }
22549                             }
22550                             break;
22551                         default:
22552                             // For everything else, assign next empty cached process
22553                             // level and bump that up.  Note that this means that
22554                             // long-running services that have dropped down to the
22555                             // cached level will be treated as empty (since their process
22556                             // state is still as a service), which is what we want.
22557                             app.curRawAdj = curEmptyAdj;
22558                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22559                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22560                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22561                                     + ")");
22562                             if (curEmptyAdj != nextEmptyAdj) {
22563                                 stepEmpty++;
22564                                 if (stepEmpty >= emptyFactor) {
22565                                     stepEmpty = 0;
22566                                     curEmptyAdj = nextEmptyAdj;
22567                                     nextEmptyAdj += 2;
22568                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22569                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22570                                     }
22571                                 }
22572                             }
22573                             break;
22574                     }
22575                 }
22576
22577                 applyOomAdjLocked(app, true, now, nowElapsed);
22578
22579                 // Count the number of process types.
22580                 switch (app.curProcState) {
22581                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22582                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22583                         mNumCachedHiddenProcs++;
22584                         numCached++;
22585                         if (numCached > cachedProcessLimit) {
22586                             app.kill("cached #" + numCached, true);
22587                         }
22588                         break;
22589                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22590                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22591                                 && app.lastActivityTime < oldTime) {
22592                             app.kill("empty for "
22593                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22594                                     / 1000) + "s", true);
22595                         } else {
22596                             numEmpty++;
22597                             if (numEmpty > emptyProcessLimit) {
22598                                 app.kill("empty #" + numEmpty, true);
22599                             }
22600                         }
22601                         break;
22602                     default:
22603                         mNumNonCachedProcs++;
22604                         break;
22605                 }
22606
22607                 if (app.isolated && app.services.size() <= 0) {
22608                     // If this is an isolated process, and there are no
22609                     // services running in it, then the process is no longer
22610                     // needed.  We agressively kill these because we can by
22611                     // definition not re-use the same process again, and it is
22612                     // good to avoid having whatever code was running in them
22613                     // left sitting around after no longer needed.
22614                     app.kill("isolated not needed", true);
22615                 } else {
22616                     // Keeping this process, update its uid.
22617                     final UidRecord uidRec = app.uidRecord;
22618                     if (uidRec != null) {
22619                         uidRec.ephemeral = app.info.isInstantApp();
22620                         if (uidRec.curProcState > app.curProcState) {
22621                             uidRec.curProcState = app.curProcState;
22622                         }
22623                         if (app.foregroundServices) {
22624                             uidRec.foregroundServices = true;
22625                         }
22626                     }
22627                 }
22628
22629                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22630                         && !app.killedByAm) {
22631                     numTrimming++;
22632                 }
22633             }
22634         }
22635
22636         incrementProcStateSeqAndNotifyAppsLocked();
22637
22638         mNumServiceProcs = mNewNumServiceProcs;
22639
22640         // Now determine the memory trimming level of background processes.
22641         // Unfortunately we need to start at the back of the list to do this
22642         // properly.  We only do this if the number of background apps we
22643         // are managing to keep around is less than half the maximum we desire;
22644         // if we are keeping a good number around, we'll let them use whatever
22645         // memory they want.
22646         final int numCachedAndEmpty = numCached + numEmpty;
22647         int memFactor;
22648         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22649                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22650             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22651                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22652             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22653                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22654             } else {
22655                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22656             }
22657         } else {
22658             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22659         }
22660         // We always allow the memory level to go up (better).  We only allow it to go
22661         // down if we are in a state where that is allowed, *and* the total number of processes
22662         // has gone down since last time.
22663         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22664                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22665                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22666         if (memFactor > mLastMemoryLevel) {
22667             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22668                 memFactor = mLastMemoryLevel;
22669                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22670             }
22671         }
22672         if (memFactor != mLastMemoryLevel) {
22673             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22674         }
22675         mLastMemoryLevel = memFactor;
22676         mLastNumProcesses = mLruProcesses.size();
22677         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22678         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22679         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22680             if (mLowRamStartTime == 0) {
22681                 mLowRamStartTime = now;
22682             }
22683             int step = 0;
22684             int fgTrimLevel;
22685             switch (memFactor) {
22686                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22687                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22688                     break;
22689                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22690                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22691                     break;
22692                 default:
22693                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22694                     break;
22695             }
22696             int factor = numTrimming/3;
22697             int minFactor = 2;
22698             if (mHomeProcess != null) minFactor++;
22699             if (mPreviousProcess != null) minFactor++;
22700             if (factor < minFactor) factor = minFactor;
22701             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22702             for (int i=N-1; i>=0; i--) {
22703                 ProcessRecord app = mLruProcesses.get(i);
22704                 if (allChanged || app.procStateChanged) {
22705                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22706                     app.procStateChanged = false;
22707                 }
22708                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22709                         && !app.killedByAm) {
22710                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
22711                         try {
22712                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22713                                     "Trimming memory of " + app.processName + " to " + curLevel);
22714                             app.thread.scheduleTrimMemory(curLevel);
22715                         } catch (RemoteException e) {
22716                         }
22717                         if (false) {
22718                             // For now we won't do this; our memory trimming seems
22719                             // to be good enough at this point that destroying
22720                             // activities causes more harm than good.
22721                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22722                                     && app != mHomeProcess && app != mPreviousProcess) {
22723                                 // Need to do this on its own message because the stack may not
22724                                 // be in a consistent state at this point.
22725                                 // For these apps we will also finish their activities
22726                                 // to help them free memory.
22727                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22728                             }
22729                         }
22730                     }
22731                     app.trimMemoryLevel = curLevel;
22732                     step++;
22733                     if (step >= factor) {
22734                         step = 0;
22735                         switch (curLevel) {
22736                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22737                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22738                                 break;
22739                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22740                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22741                                 break;
22742                         }
22743                     }
22744                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22745                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22746                             && app.thread != null) {
22747                         try {
22748                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22749                                     "Trimming memory of heavy-weight " + app.processName
22750                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22751                             app.thread.scheduleTrimMemory(
22752                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22753                         } catch (RemoteException e) {
22754                         }
22755                     }
22756                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22757                 } else {
22758                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22759                             || app.systemNoUi) && app.pendingUiClean) {
22760                         // If this application is now in the background and it
22761                         // had done UI, then give it the special trim level to
22762                         // have it free UI resources.
22763                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22764                         if (app.trimMemoryLevel < level && app.thread != null) {
22765                             try {
22766                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22767                                         "Trimming memory of bg-ui " + app.processName
22768                                         + " to " + level);
22769                                 app.thread.scheduleTrimMemory(level);
22770                             } catch (RemoteException e) {
22771                             }
22772                         }
22773                         app.pendingUiClean = false;
22774                     }
22775                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22776                         try {
22777                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22778                                     "Trimming memory of fg " + app.processName
22779                                     + " to " + fgTrimLevel);
22780                             app.thread.scheduleTrimMemory(fgTrimLevel);
22781                         } catch (RemoteException e) {
22782                         }
22783                     }
22784                     app.trimMemoryLevel = fgTrimLevel;
22785                 }
22786             }
22787         } else {
22788             if (mLowRamStartTime != 0) {
22789                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22790                 mLowRamStartTime = 0;
22791             }
22792             for (int i=N-1; i>=0; i--) {
22793                 ProcessRecord app = mLruProcesses.get(i);
22794                 if (allChanged || app.procStateChanged) {
22795                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22796                     app.procStateChanged = false;
22797                 }
22798                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22799                         || app.systemNoUi) && app.pendingUiClean) {
22800                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22801                             && app.thread != null) {
22802                         try {
22803                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22804                                     "Trimming memory of ui hidden " + app.processName
22805                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22806                             app.thread.scheduleTrimMemory(
22807                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22808                         } catch (RemoteException e) {
22809                         }
22810                     }
22811                     app.pendingUiClean = false;
22812                 }
22813                 app.trimMemoryLevel = 0;
22814             }
22815         }
22816
22817         if (mAlwaysFinishActivities) {
22818             // Need to do this on its own message because the stack may not
22819             // be in a consistent state at this point.
22820             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22821         }
22822
22823         if (allChanged) {
22824             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22825         }
22826
22827         // Update from any uid changes.
22828         if (mLocalPowerManager != null) {
22829             mLocalPowerManager.startUidChanges();
22830         }
22831         for (int i=mActiveUids.size()-1; i>=0; i--) {
22832             final UidRecord uidRec = mActiveUids.valueAt(i);
22833             int uidChange = UidRecord.CHANGE_PROCSTATE;
22834             if (uidRec.setProcState != uidRec.curProcState
22835                     || uidRec.setWhitelist != uidRec.curWhitelist) {
22836                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22837                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22838                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22839                         + " to " + uidRec.curWhitelist);
22840                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22841                         && !uidRec.curWhitelist) {
22842                     // UID is now in the background (and not on the temp whitelist).  Was it
22843                     // previously in the foreground (or on the temp whitelist)?
22844                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22845                             || uidRec.setWhitelist) {
22846                         uidRec.lastBackgroundTime = nowElapsed;
22847                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22848                             // Note: the background settle time is in elapsed realtime, while
22849                             // the handler time base is uptime.  All this means is that we may
22850                             // stop background uids later than we had intended, but that only
22851                             // happens because the device was sleeping so we are okay anyway.
22852                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22853                                     mConstants.BACKGROUND_SETTLE_TIME);
22854                         }
22855                     }
22856                 } else {
22857                     if (uidRec.idle) {
22858                         uidChange = UidRecord.CHANGE_ACTIVE;
22859                         EventLogTags.writeAmUidActive(uidRec.uid);
22860                         uidRec.idle = false;
22861                     }
22862                     uidRec.lastBackgroundTime = 0;
22863                 }
22864                 uidRec.setProcState = uidRec.curProcState;
22865                 uidRec.setWhitelist = uidRec.curWhitelist;
22866                 enqueueUidChangeLocked(uidRec, -1, uidChange);
22867                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22868                 if (uidRec.foregroundServices) {
22869                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
22870                 }
22871             }
22872         }
22873         if (mLocalPowerManager != null) {
22874             mLocalPowerManager.finishUidChanges();
22875         }
22876
22877         if (mProcessStats.shouldWriteNowLocked(now)) {
22878             mHandler.post(new Runnable() {
22879                 @Override public void run() {
22880                     synchronized (ActivityManagerService.this) {
22881                         mProcessStats.writeStateAsyncLocked();
22882                     }
22883                 }
22884             });
22885         }
22886
22887         if (DEBUG_OOM_ADJ) {
22888             final long duration = SystemClock.uptimeMillis() - now;
22889             if (false) {
22890                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22891                         new RuntimeException("here").fillInStackTrace());
22892             } else {
22893                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22894             }
22895         }
22896     }
22897
22898     @Override
22899     public void makePackageIdle(String packageName, int userId) {
22900         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22901                 != PackageManager.PERMISSION_GRANTED) {
22902             String msg = "Permission Denial: makePackageIdle() from pid="
22903                     + Binder.getCallingPid()
22904                     + ", uid=" + Binder.getCallingUid()
22905                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22906             Slog.w(TAG, msg);
22907             throw new SecurityException(msg);
22908         }
22909         final int callingPid = Binder.getCallingPid();
22910         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22911                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22912         long callingId = Binder.clearCallingIdentity();
22913         synchronized(this) {
22914             try {
22915                 IPackageManager pm = AppGlobals.getPackageManager();
22916                 int pkgUid = -1;
22917                 try {
22918                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22919                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22920                 } catch (RemoteException e) {
22921                 }
22922                 if (pkgUid == -1) {
22923                     throw new IllegalArgumentException("Unknown package name " + packageName);
22924                 }
22925
22926                 if (mLocalPowerManager != null) {
22927                     mLocalPowerManager.startUidChanges();
22928                 }
22929                 final int appId = UserHandle.getAppId(pkgUid);
22930                 final int N = mActiveUids.size();
22931                 for (int i=N-1; i>=0; i--) {
22932                     final UidRecord uidRec = mActiveUids.valueAt(i);
22933                     final long bgTime = uidRec.lastBackgroundTime;
22934                     if (bgTime > 0 && !uidRec.idle) {
22935                         if (UserHandle.getAppId(uidRec.uid) == appId) {
22936                             if (userId == UserHandle.USER_ALL ||
22937                                     userId == UserHandle.getUserId(uidRec.uid)) {
22938                                 EventLogTags.writeAmUidIdle(uidRec.uid);
22939                                 uidRec.idle = true;
22940                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22941                                         + " from package " + packageName + " user " + userId);
22942                                 doStopUidLocked(uidRec.uid, uidRec);
22943                             }
22944                         }
22945                     }
22946                 }
22947             } finally {
22948                 if (mLocalPowerManager != null) {
22949                     mLocalPowerManager.finishUidChanges();
22950                 }
22951                 Binder.restoreCallingIdentity(callingId);
22952             }
22953         }
22954     }
22955
22956     final void idleUids() {
22957         synchronized (this) {
22958             final int N = mActiveUids.size();
22959             if (N <= 0) {
22960                 return;
22961             }
22962             final long nowElapsed = SystemClock.elapsedRealtime();
22963             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22964             long nextTime = 0;
22965             if (mLocalPowerManager != null) {
22966                 mLocalPowerManager.startUidChanges();
22967             }
22968             for (int i=N-1; i>=0; i--) {
22969                 final UidRecord uidRec = mActiveUids.valueAt(i);
22970                 final long bgTime = uidRec.lastBackgroundTime;
22971                 if (bgTime > 0 && !uidRec.idle) {
22972                     if (bgTime <= maxBgTime) {
22973                         EventLogTags.writeAmUidIdle(uidRec.uid);
22974                         uidRec.idle = true;
22975                         doStopUidLocked(uidRec.uid, uidRec);
22976                     } else {
22977                         if (nextTime == 0 || nextTime > bgTime) {
22978                             nextTime = bgTime;
22979                         }
22980                     }
22981                 }
22982             }
22983             if (mLocalPowerManager != null) {
22984                 mLocalPowerManager.finishUidChanges();
22985             }
22986             if (nextTime > 0) {
22987                 mHandler.removeMessages(IDLE_UIDS_MSG);
22988                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22989                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
22990             }
22991         }
22992     }
22993
22994     /**
22995      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
22996      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
22997      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
22998      */
22999     @VisibleForTesting
23000     @GuardedBy("this")
23001     void incrementProcStateSeqAndNotifyAppsLocked() {
23002         if (mWaitForNetworkTimeoutMs <= 0) {
23003             return;
23004         }
23005         // Used for identifying which uids need to block for network.
23006         ArrayList<Integer> blockingUids = null;
23007         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23008             final UidRecord uidRec = mActiveUids.valueAt(i);
23009             // If the network is not restricted for uid, then nothing to do here.
23010             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23011                 continue;
23012             }
23013             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23014                 continue;
23015             }
23016             // If process state is not changed, then there's nothing to do.
23017             if (uidRec.setProcState == uidRec.curProcState) {
23018                 continue;
23019             }
23020             final int blockState = getBlockStateForUid(uidRec);
23021             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23022             // there's nothing the app needs to do in this scenario.
23023             if (blockState == NETWORK_STATE_NO_CHANGE) {
23024                 continue;
23025             }
23026             synchronized (uidRec.networkStateLock) {
23027                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23028                 if (blockState == NETWORK_STATE_BLOCK) {
23029                     if (blockingUids == null) {
23030                         blockingUids = new ArrayList<>();
23031                     }
23032                     blockingUids.add(uidRec.uid);
23033                 } else {
23034                     if (DEBUG_NETWORK) {
23035                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23036                                 + " threads for uid: " + uidRec);
23037                     }
23038                     if (uidRec.waitingForNetwork) {
23039                         uidRec.networkStateLock.notifyAll();
23040                     }
23041                 }
23042             }
23043         }
23044
23045         // There are no uids that need to block, so nothing more to do.
23046         if (blockingUids == null) {
23047             return;
23048         }
23049
23050         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23051             final ProcessRecord app = mLruProcesses.get(i);
23052             if (!blockingUids.contains(app.uid)) {
23053                 continue;
23054             }
23055             if (!app.killedByAm && app.thread != null) {
23056                 final UidRecord uidRec = mActiveUids.get(app.uid);
23057                 try {
23058                     if (DEBUG_NETWORK) {
23059                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23060                                 + uidRec);
23061                     }
23062                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23063                 } catch (RemoteException ignored) {
23064                 }
23065             }
23066         }
23067     }
23068
23069     /**
23070      * Checks if the uid is coming from background to foreground or vice versa and returns
23071      * appropriate block state based on this.
23072      *
23073      * @return blockState based on whether the uid is coming from background to foreground or
23074      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23075      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23076      *         {@link #NETWORK_STATE_NO_CHANGE}.
23077      */
23078     @VisibleForTesting
23079     int getBlockStateForUid(UidRecord uidRec) {
23080         // Denotes whether uid's process state is currently allowed network access.
23081         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23082                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23083         // Denotes whether uid's process state was previously allowed network access.
23084         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23085                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23086
23087         // When the uid is coming to foreground, AMS should inform the app thread that it should
23088         // block for the network rules to get updated before launching an activity.
23089         if (!wasAllowed && isAllowed) {
23090             return NETWORK_STATE_BLOCK;
23091         }
23092         // When the uid is going to background, AMS should inform the app thread that if an
23093         // activity launch is blocked for the network rules to get updated, it should be unblocked.
23094         if (wasAllowed && !isAllowed) {
23095             return NETWORK_STATE_UNBLOCK;
23096         }
23097         return NETWORK_STATE_NO_CHANGE;
23098     }
23099
23100     final void runInBackgroundDisabled(int uid) {
23101         synchronized (this) {
23102             UidRecord uidRec = mActiveUids.get(uid);
23103             if (uidRec != null) {
23104                 // This uid is actually running...  should it be considered background now?
23105                 if (uidRec.idle) {
23106                     doStopUidLocked(uidRec.uid, uidRec);
23107                 }
23108             } else {
23109                 // This uid isn't actually running...  still send a report about it being "stopped".
23110                 doStopUidLocked(uid, null);
23111             }
23112         }
23113     }
23114
23115     final void doStopUidLocked(int uid, final UidRecord uidRec) {
23116         mServices.stopInBackgroundLocked(uid);
23117         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23118     }
23119
23120     /**
23121      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23122      */
23123     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23124             long duration, String tag) {
23125         if (DEBUG_WHITELISTS) {
23126             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23127                     + targetUid + ", " + duration + ")");
23128         }
23129
23130         synchronized (mPidsSelfLocked) {
23131             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23132             if (pr == null) {
23133                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23134                         + callerPid);
23135                 return;
23136             }
23137             if (!pr.whitelistManager) {
23138                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23139                         != PackageManager.PERMISSION_GRANTED) {
23140                     if (DEBUG_WHITELISTS) {
23141                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23142                                 + ": pid " + callerPid + " is not allowed");
23143                     }
23144                     return;
23145                 }
23146             }
23147         }
23148
23149         tempWhitelistUidLocked(targetUid, duration, tag);
23150     }
23151
23152     /**
23153      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23154      */
23155     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23156         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23157         setUidTempWhitelistStateLocked(targetUid, true);
23158         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23159     }
23160
23161     void pushTempWhitelist() {
23162         final int N;
23163         final PendingTempWhitelist[] list;
23164
23165         // First copy out the pending changes...  we need to leave them in the map for now,
23166         // in case someone needs to check what is coming up while we don't have the lock held.
23167         synchronized(this) {
23168             N = mPendingTempWhitelist.size();
23169             list = new PendingTempWhitelist[N];
23170             for (int i = 0; i < N; i++) {
23171                 list[i] = mPendingTempWhitelist.valueAt(i);
23172             }
23173         }
23174
23175         // Now safely dispatch changes to device idle controller.
23176         for (int i = 0; i < N; i++) {
23177             PendingTempWhitelist ptw = list[i];
23178             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23179                     ptw.duration, true, ptw.tag);
23180         }
23181
23182         // And now we can safely remove them from the map.
23183         synchronized(this) {
23184             for (int i = 0; i < N; i++) {
23185                 PendingTempWhitelist ptw = list[i];
23186                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23187                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23188                     mPendingTempWhitelist.removeAt(index);
23189                 }
23190             }
23191         }
23192     }
23193
23194     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23195         boolean changed = false;
23196         for (int i=mActiveUids.size()-1; i>=0; i--) {
23197             final UidRecord uidRec = mActiveUids.valueAt(i);
23198             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23199                 uidRec.curWhitelist = onWhitelist;
23200                 changed = true;
23201             }
23202         }
23203         if (changed) {
23204             updateOomAdjLocked();
23205         }
23206     }
23207
23208     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23209         boolean changed = false;
23210         final UidRecord uidRec = mActiveUids.get(uid);
23211         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23212             uidRec.curWhitelist = onWhitelist;
23213             updateOomAdjLocked();
23214         }
23215     }
23216
23217     final void trimApplications() {
23218         synchronized (this) {
23219             int i;
23220
23221             // First remove any unused application processes whose package
23222             // has been removed.
23223             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23224                 final ProcessRecord app = mRemovedProcesses.get(i);
23225                 if (app.activities.size() == 0
23226                         && app.curReceivers.isEmpty() && app.services.size() == 0) {
23227                     Slog.i(
23228                         TAG, "Exiting empty application process "
23229                         + app.toShortString() + " ("
23230                         + (app.thread != null ? app.thread.asBinder() : null)
23231                         + ")\n");
23232                     if (app.pid > 0 && app.pid != MY_PID) {
23233                         app.kill("empty", false);
23234                     } else {
23235                         try {
23236                             app.thread.scheduleExit();
23237                         } catch (Exception e) {
23238                             // Ignore exceptions.
23239                         }
23240                     }
23241                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23242                     mRemovedProcesses.remove(i);
23243
23244                     if (app.persistent) {
23245                         addAppLocked(app.info, null, false, null /* ABI override */);
23246                     }
23247                 }
23248             }
23249
23250             // Now update the oom adj for all processes.
23251             updateOomAdjLocked();
23252         }
23253     }
23254
23255     /** This method sends the specified signal to each of the persistent apps */
23256     public void signalPersistentProcesses(int sig) throws RemoteException {
23257         if (sig != SIGNAL_USR1) {
23258             throw new SecurityException("Only SIGNAL_USR1 is allowed");
23259         }
23260
23261         synchronized (this) {
23262             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23263                     != PackageManager.PERMISSION_GRANTED) {
23264                 throw new SecurityException("Requires permission "
23265                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23266             }
23267
23268             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23269                 ProcessRecord r = mLruProcesses.get(i);
23270                 if (r.thread != null && r.persistent) {
23271                     sendSignal(r.pid, sig);
23272                 }
23273             }
23274         }
23275     }
23276
23277     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23278         if (proc == null || proc == mProfileProc) {
23279             proc = mProfileProc;
23280             profileType = mProfileType;
23281             clearProfilerLocked();
23282         }
23283         if (proc == null) {
23284             return;
23285         }
23286         try {
23287             proc.thread.profilerControl(false, null, profileType);
23288         } catch (RemoteException e) {
23289             throw new IllegalStateException("Process disappeared");
23290         }
23291     }
23292
23293     private void clearProfilerLocked() {
23294         if (mProfileFd != null) {
23295             try {
23296                 mProfileFd.close();
23297             } catch (IOException e) {
23298             }
23299         }
23300         mProfileApp = null;
23301         mProfileProc = null;
23302         mProfileFile = null;
23303         mProfileType = 0;
23304         mAutoStopProfiler = false;
23305         mStreamingOutput = false;
23306         mSamplingInterval = 0;
23307     }
23308
23309     public boolean profileControl(String process, int userId, boolean start,
23310             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23311
23312         try {
23313             synchronized (this) {
23314                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23315                 // its own permission.
23316                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23317                         != PackageManager.PERMISSION_GRANTED) {
23318                     throw new SecurityException("Requires permission "
23319                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23320                 }
23321
23322                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23323                     throw new IllegalArgumentException("null profile info or fd");
23324                 }
23325
23326                 ProcessRecord proc = null;
23327                 if (process != null) {
23328                     proc = findProcessLocked(process, userId, "profileControl");
23329                 }
23330
23331                 if (start && (proc == null || proc.thread == null)) {
23332                     throw new IllegalArgumentException("Unknown process: " + process);
23333                 }
23334
23335                 if (start) {
23336                     stopProfilerLocked(null, 0);
23337                     setProfileApp(proc.info, proc.processName, profilerInfo);
23338                     mProfileProc = proc;
23339                     mProfileType = profileType;
23340                     ParcelFileDescriptor fd = profilerInfo.profileFd;
23341                     try {
23342                         fd = fd.dup();
23343                     } catch (IOException e) {
23344                         fd = null;
23345                     }
23346                     profilerInfo.profileFd = fd;
23347                     proc.thread.profilerControl(start, profilerInfo, profileType);
23348                     fd = null;
23349                     try {
23350                         mProfileFd.close();
23351                     } catch (IOException e) {
23352                     }
23353                     mProfileFd = null;
23354                 } else {
23355                     stopProfilerLocked(proc, profileType);
23356                     if (profilerInfo != null && profilerInfo.profileFd != null) {
23357                         try {
23358                             profilerInfo.profileFd.close();
23359                         } catch (IOException e) {
23360                         }
23361                     }
23362                 }
23363
23364                 return true;
23365             }
23366         } catch (RemoteException e) {
23367             throw new IllegalStateException("Process disappeared");
23368         } finally {
23369             if (profilerInfo != null && profilerInfo.profileFd != null) {
23370                 try {
23371                     profilerInfo.profileFd.close();
23372                 } catch (IOException e) {
23373                 }
23374             }
23375         }
23376     }
23377
23378     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23379         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23380                 userId, true, ALLOW_FULL_ONLY, callName, null);
23381         ProcessRecord proc = null;
23382         try {
23383             int pid = Integer.parseInt(process);
23384             synchronized (mPidsSelfLocked) {
23385                 proc = mPidsSelfLocked.get(pid);
23386             }
23387         } catch (NumberFormatException e) {
23388         }
23389
23390         if (proc == null) {
23391             ArrayMap<String, SparseArray<ProcessRecord>> all
23392                     = mProcessNames.getMap();
23393             SparseArray<ProcessRecord> procs = all.get(process);
23394             if (procs != null && procs.size() > 0) {
23395                 proc = procs.valueAt(0);
23396                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23397                     for (int i=1; i<procs.size(); i++) {
23398                         ProcessRecord thisProc = procs.valueAt(i);
23399                         if (thisProc.userId == userId) {
23400                             proc = thisProc;
23401                             break;
23402                         }
23403                     }
23404                 }
23405             }
23406         }
23407
23408         return proc;
23409     }
23410
23411     public boolean dumpHeap(String process, int userId, boolean managed,
23412             String path, ParcelFileDescriptor fd) throws RemoteException {
23413
23414         try {
23415             synchronized (this) {
23416                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23417                 // its own permission (same as profileControl).
23418                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23419                         != PackageManager.PERMISSION_GRANTED) {
23420                     throw new SecurityException("Requires permission "
23421                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23422                 }
23423
23424                 if (fd == null) {
23425                     throw new IllegalArgumentException("null fd");
23426                 }
23427
23428                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23429                 if (proc == null || proc.thread == null) {
23430                     throw new IllegalArgumentException("Unknown process: " + process);
23431                 }
23432
23433                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23434                 if (!isDebuggable) {
23435                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23436                         throw new SecurityException("Process not debuggable: " + proc);
23437                     }
23438                 }
23439
23440                 proc.thread.dumpHeap(managed, path, fd);
23441                 fd = null;
23442                 return true;
23443             }
23444         } catch (RemoteException e) {
23445             throw new IllegalStateException("Process disappeared");
23446         } finally {
23447             if (fd != null) {
23448                 try {
23449                     fd.close();
23450                 } catch (IOException e) {
23451                 }
23452             }
23453         }
23454     }
23455
23456     @Override
23457     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23458             String reportPackage) {
23459         if (processName != null) {
23460             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23461                     "setDumpHeapDebugLimit()");
23462         } else {
23463             synchronized (mPidsSelfLocked) {
23464                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23465                 if (proc == null) {
23466                     throw new SecurityException("No process found for calling pid "
23467                             + Binder.getCallingPid());
23468                 }
23469                 if (!Build.IS_DEBUGGABLE
23470                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23471                     throw new SecurityException("Not running a debuggable build");
23472                 }
23473                 processName = proc.processName;
23474                 uid = proc.uid;
23475                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23476                     throw new SecurityException("Package " + reportPackage + " is not running in "
23477                             + proc);
23478                 }
23479             }
23480         }
23481         synchronized (this) {
23482             if (maxMemSize > 0) {
23483                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23484             } else {
23485                 if (uid != 0) {
23486                     mMemWatchProcesses.remove(processName, uid);
23487                 } else {
23488                     mMemWatchProcesses.getMap().remove(processName);
23489                 }
23490             }
23491         }
23492     }
23493
23494     @Override
23495     public void dumpHeapFinished(String path) {
23496         synchronized (this) {
23497             if (Binder.getCallingPid() != mMemWatchDumpPid) {
23498                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23499                         + " does not match last pid " + mMemWatchDumpPid);
23500                 return;
23501             }
23502             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23503                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23504                         + " does not match last path " + mMemWatchDumpFile);
23505                 return;
23506             }
23507             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23508             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23509         }
23510     }
23511
23512     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23513     public void monitor() {
23514         synchronized (this) { }
23515     }
23516
23517     void onCoreSettingsChange(Bundle settings) {
23518         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23519             ProcessRecord processRecord = mLruProcesses.get(i);
23520             try {
23521                 if (processRecord.thread != null) {
23522                     processRecord.thread.setCoreSettings(settings);
23523                 }
23524             } catch (RemoteException re) {
23525                 /* ignore */
23526             }
23527         }
23528     }
23529
23530     // Multi-user methods
23531
23532     /**
23533      * Start user, if its not already running, but don't bring it to foreground.
23534      */
23535     @Override
23536     public boolean startUserInBackground(final int userId) {
23537         return mUserController.startUser(userId, /* foreground */ false);
23538     }
23539
23540     @Override
23541     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23542         return mUserController.unlockUser(userId, token, secret, listener);
23543     }
23544
23545     @Override
23546     public boolean switchUser(final int targetUserId) {
23547         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23548         int currentUserId;
23549         UserInfo targetUserInfo;
23550         synchronized (this) {
23551             currentUserId = mUserController.getCurrentUserIdLocked();
23552             targetUserInfo = mUserController.getUserInfo(targetUserId);
23553             if (targetUserId == currentUserId) {
23554                 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23555                 return true;
23556             }
23557             if (targetUserInfo == null) {
23558                 Slog.w(TAG, "No user info for user #" + targetUserId);
23559                 return false;
23560             }
23561             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23562                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23563                         + " when device is in demo mode");
23564                 return false;
23565             }
23566             if (!targetUserInfo.supportsSwitchTo()) {
23567                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23568                 return false;
23569             }
23570             if (targetUserInfo.isManagedProfile()) {
23571                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23572                 return false;
23573             }
23574             mUserController.setTargetUserIdLocked(targetUserId);
23575         }
23576         if (mUserController.mUserSwitchUiEnabled) {
23577             UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23578             Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23579             mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23580             mUiHandler.sendMessage(mHandler.obtainMessage(
23581                     START_USER_SWITCH_UI_MSG, userNames));
23582         } else {
23583             mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23584             mHandler.sendMessage(mHandler.obtainMessage(
23585                     START_USER_SWITCH_FG_MSG, targetUserId, 0));
23586         }
23587         return true;
23588     }
23589
23590     void scheduleStartProfilesLocked() {
23591         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23592             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23593                     DateUtils.SECOND_IN_MILLIS);
23594         }
23595     }
23596
23597     @Override
23598     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23599         return mUserController.stopUser(userId, force, callback);
23600     }
23601
23602     @Override
23603     public UserInfo getCurrentUser() {
23604         return mUserController.getCurrentUser();
23605     }
23606
23607     String getStartedUserState(int userId) {
23608         synchronized (this) {
23609             final UserState userState = mUserController.getStartedUserStateLocked(userId);
23610             return UserState.stateToString(userState.state);
23611         }
23612     }
23613
23614     @Override
23615     public boolean isUserRunning(int userId, int flags) {
23616         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23617                 && checkCallingPermission(INTERACT_ACROSS_USERS)
23618                     != PackageManager.PERMISSION_GRANTED) {
23619             String msg = "Permission Denial: isUserRunning() from pid="
23620                     + Binder.getCallingPid()
23621                     + ", uid=" + Binder.getCallingUid()
23622                     + " requires " + INTERACT_ACROSS_USERS;
23623             Slog.w(TAG, msg);
23624             throw new SecurityException(msg);
23625         }
23626         synchronized (this) {
23627             return mUserController.isUserRunningLocked(userId, flags);
23628         }
23629     }
23630
23631     @Override
23632     public int[] getRunningUserIds() {
23633         if (checkCallingPermission(INTERACT_ACROSS_USERS)
23634                 != PackageManager.PERMISSION_GRANTED) {
23635             String msg = "Permission Denial: isUserRunning() from pid="
23636                     + Binder.getCallingPid()
23637                     + ", uid=" + Binder.getCallingUid()
23638                     + " requires " + INTERACT_ACROSS_USERS;
23639             Slog.w(TAG, msg);
23640             throw new SecurityException(msg);
23641         }
23642         synchronized (this) {
23643             return mUserController.getStartedUserArrayLocked();
23644         }
23645     }
23646
23647     @Override
23648     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23649         mUserController.registerUserSwitchObserver(observer, name);
23650     }
23651
23652     @Override
23653     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23654         mUserController.unregisterUserSwitchObserver(observer);
23655     }
23656
23657     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23658         if (info == null) return null;
23659         ApplicationInfo newInfo = new ApplicationInfo(info);
23660         newInfo.initForUser(userId);
23661         return newInfo;
23662     }
23663
23664     public boolean isUserStopped(int userId) {
23665         synchronized (this) {
23666             return mUserController.getStartedUserStateLocked(userId) == null;
23667         }
23668     }
23669
23670     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23671         if (aInfo == null
23672                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23673             return aInfo;
23674         }
23675
23676         ActivityInfo info = new ActivityInfo(aInfo);
23677         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23678         return info;
23679     }
23680
23681     private boolean processSanityChecksLocked(ProcessRecord process) {
23682         if (process == null || process.thread == null) {
23683             return false;
23684         }
23685
23686         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23687         if (!isDebuggable) {
23688             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23689                 return false;
23690             }
23691         }
23692
23693         return true;
23694     }
23695
23696     public boolean startBinderTracking() throws RemoteException {
23697         synchronized (this) {
23698             mBinderTransactionTrackingEnabled = true;
23699             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23700             // permission (same as profileControl).
23701             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23702                     != PackageManager.PERMISSION_GRANTED) {
23703                 throw new SecurityException("Requires permission "
23704                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23705             }
23706
23707             for (int i = 0; i < mLruProcesses.size(); i++) {
23708                 ProcessRecord process = mLruProcesses.get(i);
23709                 if (!processSanityChecksLocked(process)) {
23710                     continue;
23711                 }
23712                 try {
23713                     process.thread.startBinderTracking();
23714                 } catch (RemoteException e) {
23715                     Log.v(TAG, "Process disappared");
23716                 }
23717             }
23718             return true;
23719         }
23720     }
23721
23722     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23723         try {
23724             synchronized (this) {
23725                 mBinderTransactionTrackingEnabled = false;
23726                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23727                 // permission (same as profileControl).
23728                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23729                         != PackageManager.PERMISSION_GRANTED) {
23730                     throw new SecurityException("Requires permission "
23731                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23732                 }
23733
23734                 if (fd == null) {
23735                     throw new IllegalArgumentException("null fd");
23736                 }
23737
23738                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23739                 pw.println("Binder transaction traces for all processes.\n");
23740                 for (ProcessRecord process : mLruProcesses) {
23741                     if (!processSanityChecksLocked(process)) {
23742                         continue;
23743                     }
23744
23745                     pw.println("Traces for process: " + process.processName);
23746                     pw.flush();
23747                     try {
23748                         TransferPipe tp = new TransferPipe();
23749                         try {
23750                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23751                             tp.go(fd.getFileDescriptor());
23752                         } finally {
23753                             tp.kill();
23754                         }
23755                     } catch (IOException e) {
23756                         pw.println("Failure while dumping IPC traces from " + process +
23757                                 ".  Exception: " + e);
23758                         pw.flush();
23759                     } catch (RemoteException e) {
23760                         pw.println("Got a RemoteException while dumping IPC traces from " +
23761                                 process + ".  Exception: " + e);
23762                         pw.flush();
23763                     }
23764                 }
23765                 fd = null;
23766                 return true;
23767             }
23768         } finally {
23769             if (fd != null) {
23770                 try {
23771                     fd.close();
23772                 } catch (IOException e) {
23773                 }
23774             }
23775         }
23776     }
23777
23778     @VisibleForTesting
23779     final class LocalService extends ActivityManagerInternal {
23780         @Override
23781         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23782                 int targetUserId) {
23783             synchronized (ActivityManagerService.this) {
23784                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23785                         targetPkg, intent, null, targetUserId);
23786             }
23787         }
23788
23789         @Override
23790         public String checkContentProviderAccess(String authority, int userId) {
23791             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23792         }
23793
23794         @Override
23795         public void onWakefulnessChanged(int wakefulness) {
23796             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23797         }
23798
23799         @Override
23800         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23801                 String processName, String abiOverride, int uid, Runnable crashHandler) {
23802             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23803                     processName, abiOverride, uid, crashHandler);
23804         }
23805
23806         @Override
23807         public SleepToken acquireSleepToken(String tag) {
23808             Preconditions.checkNotNull(tag);
23809
23810             synchronized (ActivityManagerService.this) {
23811                 SleepTokenImpl token = new SleepTokenImpl(tag);
23812                 mSleepTokens.add(token);
23813                 updateSleepIfNeededLocked();
23814                 return token;
23815             }
23816         }
23817
23818         @Override
23819         public ComponentName getHomeActivityForUser(int userId) {
23820             synchronized (ActivityManagerService.this) {
23821                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23822                 return homeActivity == null ? null : homeActivity.realActivity;
23823             }
23824         }
23825
23826         @Override
23827         public void onUserRemoved(int userId) {
23828             synchronized (ActivityManagerService.this) {
23829                 ActivityManagerService.this.onUserStoppedLocked(userId);
23830             }
23831         }
23832
23833         @Override
23834         public void onLocalVoiceInteractionStarted(IBinder activity,
23835                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23836             synchronized (ActivityManagerService.this) {
23837                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23838                         voiceSession, voiceInteractor);
23839             }
23840         }
23841
23842         @Override
23843         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23844             synchronized (ActivityManagerService.this) {
23845                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23846                         reasons, timestamp);
23847             }
23848         }
23849
23850         @Override
23851         public void notifyAppTransitionFinished() {
23852             synchronized (ActivityManagerService.this) {
23853                 mStackSupervisor.notifyAppTransitionDone();
23854             }
23855         }
23856
23857         @Override
23858         public void notifyAppTransitionCancelled() {
23859             synchronized (ActivityManagerService.this) {
23860                 mStackSupervisor.notifyAppTransitionDone();
23861             }
23862         }
23863
23864         @Override
23865         public List<IBinder> getTopVisibleActivities() {
23866             synchronized (ActivityManagerService.this) {
23867                 return mStackSupervisor.getTopVisibleActivities();
23868             }
23869         }
23870
23871         @Override
23872         public void notifyDockedStackMinimizedChanged(boolean minimized) {
23873             synchronized (ActivityManagerService.this) {
23874                 mStackSupervisor.setDockedStackMinimized(minimized);
23875             }
23876         }
23877
23878         @Override
23879         public void killForegroundAppsForUser(int userHandle) {
23880             synchronized (ActivityManagerService.this) {
23881                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23882                 final int NP = mProcessNames.getMap().size();
23883                 for (int ip = 0; ip < NP; ip++) {
23884                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23885                     final int NA = apps.size();
23886                     for (int ia = 0; ia < NA; ia++) {
23887                         final ProcessRecord app = apps.valueAt(ia);
23888                         if (app.persistent) {
23889                             // We don't kill persistent processes.
23890                             continue;
23891                         }
23892                         if (app.removed) {
23893                             procs.add(app);
23894                         } else if (app.userId == userHandle && app.foregroundActivities) {
23895                             app.removed = true;
23896                             procs.add(app);
23897                         }
23898                     }
23899                 }
23900
23901                 final int N = procs.size();
23902                 for (int i = 0; i < N; i++) {
23903                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
23904                 }
23905             }
23906         }
23907
23908         @Override
23909         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23910                 long duration) {
23911             if (!(target instanceof PendingIntentRecord)) {
23912                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23913                 return;
23914             }
23915             ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23916         }
23917
23918         @Override
23919         public void setDeviceIdleWhitelist(int[] appids) {
23920             synchronized (ActivityManagerService.this) {
23921                 mDeviceIdleWhitelist = appids;
23922             }
23923         }
23924
23925         @Override
23926         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23927             synchronized (ActivityManagerService.this) {
23928                 mDeviceIdleTempWhitelist = appids;
23929                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
23930             }
23931         }
23932
23933         @Override
23934         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23935                 int userId) {
23936             Preconditions.checkNotNull(values, "Configuration must not be null");
23937             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23938             synchronized (ActivityManagerService.this) {
23939                 updateConfigurationLocked(values, null, false, true, userId,
23940                         false /* deferResume */);
23941             }
23942         }
23943
23944         @Override
23945         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23946                 Bundle bOptions) {
23947             Preconditions.checkNotNull(intents, "intents");
23948             final String[] resolvedTypes = new String[intents.length];
23949             for (int i = 0; i < intents.length; i++) {
23950                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23951             }
23952
23953             // UID of the package on user userId.
23954             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23955             // packageUid may not be initialized.
23956             int packageUid = 0;
23957             try {
23958                 packageUid = AppGlobals.getPackageManager().getPackageUid(
23959                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23960             } catch (RemoteException e) {
23961                 // Shouldn't happen.
23962             }
23963
23964             synchronized (ActivityManagerService.this) {
23965                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23966                         /*resultTo*/ null, bOptions, userId);
23967             }
23968         }
23969
23970         @Override
23971         public int getUidProcessState(int uid) {
23972             return getUidState(uid);
23973         }
23974
23975         @Override
23976         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23977             synchronized (ActivityManagerService.this) {
23978
23979                 // We might change the visibilities here, so prepare an empty app transition which
23980                 // might be overridden later if we actually change visibilities.
23981                 mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23982                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23983                 mWindowManager.executeAppTransition();
23984             }
23985             if (callback != null) {
23986                 callback.run();
23987             }
23988         }
23989
23990         @Override
23991         public boolean isSystemReady() {
23992             // no need to synchronize(this) just to read & return the value
23993             return mSystemReady;
23994         }
23995
23996         @Override
23997         public void notifyKeyguardTrustedChanged() {
23998             synchronized (ActivityManagerService.this) {
23999                 if (mKeyguardController.isKeyguardShowing()) {
24000                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24001                 }
24002             }
24003         }
24004
24005         /**
24006          * Sets if the given pid has an overlay UI or not.
24007          *
24008          * @param pid The pid we are setting overlay UI for.
24009          * @param hasOverlayUi True if the process has overlay UI.
24010          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24011          */
24012         @Override
24013         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24014             synchronized (ActivityManagerService.this) {
24015                 final ProcessRecord pr;
24016                 synchronized (mPidsSelfLocked) {
24017                     pr = mPidsSelfLocked.get(pid);
24018                     if (pr == null) {
24019                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24020                         return;
24021                     }
24022                 }
24023                 if (pr.hasOverlayUi == hasOverlayUi) {
24024                     return;
24025                 }
24026                 pr.hasOverlayUi = hasOverlayUi;
24027                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24028                 updateOomAdjLocked(pr, true);
24029             }
24030         }
24031
24032         /**
24033          * Called after the network policy rules are updated by
24034          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24035          * and {@param procStateSeq}.
24036          */
24037         @Override
24038         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24039             if (DEBUG_NETWORK) {
24040                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24041                         + uid + " seq: " + procStateSeq);
24042             }
24043             UidRecord record;
24044             synchronized (ActivityManagerService.this) {
24045                 record = mActiveUids.get(uid);
24046                 if (record == null) {
24047                     if (DEBUG_NETWORK) {
24048                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24049                                 + " procStateSeq: " + procStateSeq);
24050                     }
24051                     return;
24052                 }
24053             }
24054             synchronized (record.networkStateLock) {
24055                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24056                     if (DEBUG_NETWORK) {
24057                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24058                                 + " been handled for uid: " + uid);
24059                     }
24060                     return;
24061                 }
24062                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24063                 if (record.curProcStateSeq > procStateSeq) {
24064                     if (DEBUG_NETWORK) {
24065                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24066                                 + ", curProcstateSeq: " + record.curProcStateSeq
24067                                 + ", procStateSeq: " + procStateSeq);
24068                     }
24069                     return;
24070                 }
24071                 if (record.waitingForNetwork) {
24072                     if (DEBUG_NETWORK) {
24073                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24074                                 + ", procStateSeq: " + procStateSeq);
24075                     }
24076                     record.networkStateLock.notifyAll();
24077                 }
24078             }
24079         }
24080
24081         /**
24082          * Called after virtual display Id is updated by
24083          * {@link com.android.server.vr.Vr2dDisplay} with a specific
24084          * {@param vrVr2dDisplayId}.
24085          */
24086         @Override
24087         public void setVr2dDisplayId(int vr2dDisplayId) {
24088             if (DEBUG_STACK) {
24089                 Slog.d(TAG, "setVr2dDisplayId called for: " +
24090                         vr2dDisplayId);
24091             }
24092             synchronized (ActivityManagerService.this) {
24093                 mVr2dDisplayId = vr2dDisplayId;
24094             }
24095         }
24096
24097         @Override
24098         public void saveANRState(String reason) {
24099             synchronized (ActivityManagerService.this) {
24100                 final StringWriter sw = new StringWriter();
24101                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24102                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24103                 if (reason != null) {
24104                     pw.println("  Reason: " + reason);
24105                 }
24106                 pw.println();
24107                 mActivityStarter.dump(pw, "  ");
24108                 pw.println();
24109                 pw.println("-------------------------------------------------------------------------------");
24110                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24111                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24112                         "" /* header */);
24113                 pw.println();
24114                 pw.close();
24115
24116                 mLastANRState = sw.toString();
24117             }
24118         }
24119
24120         @Override
24121         public void clearSavedANRState() {
24122             synchronized (ActivityManagerService.this) {
24123                 mLastANRState = null;
24124             }
24125         }
24126     }
24127
24128     /**
24129      * Called by app main thread to wait for the network policy rules to get updated.
24130      *
24131      * @param procStateSeq The sequence number indicating the process state change that the main
24132      *                     thread is interested in.
24133      */
24134     @Override
24135     public void waitForNetworkStateUpdate(long procStateSeq) {
24136         final int callingUid = Binder.getCallingUid();
24137         if (DEBUG_NETWORK) {
24138             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24139         }
24140         UidRecord record;
24141         synchronized (this) {
24142             record = mActiveUids.get(callingUid);
24143             if (record == null) {
24144                 return;
24145             }
24146         }
24147         synchronized (record.networkStateLock) {
24148             if (record.lastDispatchedProcStateSeq < procStateSeq) {
24149                 if (DEBUG_NETWORK) {
24150                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24151                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24152                             + " lastProcStateSeqDispatchedToObservers: "
24153                             + record.lastDispatchedProcStateSeq);
24154                 }
24155                 return;
24156             }
24157             if (record.curProcStateSeq > procStateSeq) {
24158                 if (DEBUG_NETWORK) {
24159                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24160                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24161                             + ", procStateSeq: " + procStateSeq);
24162                 }
24163                 return;
24164             }
24165             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24166                 if (DEBUG_NETWORK) {
24167                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24168                             + procStateSeq + ", so no need to wait. Uid: "
24169                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24170                             + record.lastNetworkUpdatedProcStateSeq);
24171                 }
24172                 return;
24173             }
24174             try {
24175                 if (DEBUG_NETWORK) {
24176                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24177                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24178                 }
24179                 final long startTime = SystemClock.uptimeMillis();
24180                 record.waitingForNetwork = true;
24181                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24182                 record.waitingForNetwork = false;
24183                 final long totalTime = SystemClock.uptimeMillis() - startTime;
24184                 if (totalTime >= mWaitForNetworkTimeoutMs) {
24185                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24186                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24187                             + procStateSeq + " UidRec: " + record
24188                             + " validateUidRec: " + mValidateUids.get(callingUid));
24189                 }
24190             } catch (InterruptedException e) {
24191                 Thread.currentThread().interrupt();
24192             }
24193         }
24194     }
24195
24196     public void waitForBroadcastIdle(PrintWriter pw) {
24197         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24198         while (true) {
24199             boolean idle = true;
24200             synchronized (this) {
24201                 for (BroadcastQueue queue : mBroadcastQueues) {
24202                     if (!queue.isIdle()) {
24203                         final String msg = "Waiting for queue " + queue + " to become idle...";
24204                         pw.println(msg);
24205                         pw.flush();
24206                         Slog.v(TAG, msg);
24207                         idle = false;
24208                     }
24209                 }
24210             }
24211
24212             if (idle) {
24213                 final String msg = "All broadcast queues are idle!";
24214                 pw.println(msg);
24215                 pw.flush();
24216                 Slog.v(TAG, msg);
24217                 return;
24218             } else {
24219                 SystemClock.sleep(1000);
24220             }
24221         }
24222     }
24223
24224     /**
24225      * Return the user id of the last resumed activity.
24226      */
24227     @Override
24228     public @UserIdInt int getLastResumedActivityUserId() {
24229         enforceCallingPermission(
24230                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24231         synchronized (this) {
24232             if (mLastResumedActivity == null) {
24233                 return mUserController.getCurrentUserIdLocked();
24234             }
24235             return mLastResumedActivity.userId;
24236         }
24237     }
24238
24239     private final class SleepTokenImpl extends SleepToken {
24240         private final String mTag;
24241         private final long mAcquireTime;
24242
24243         public SleepTokenImpl(String tag) {
24244             mTag = tag;
24245             mAcquireTime = SystemClock.uptimeMillis();
24246         }
24247
24248         @Override
24249         public void release() {
24250             synchronized (ActivityManagerService.this) {
24251                 if (mSleepTokens.remove(this)) {
24252                     updateSleepIfNeededLocked();
24253                 }
24254             }
24255         }
24256
24257         @Override
24258         public String toString() {
24259             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
24260         }
24261     }
24262
24263     /**
24264      * An implementation of IAppTask, that allows an app to manage its own tasks via
24265      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24266      * only the process that calls getAppTasks() can call the AppTask methods.
24267      */
24268     class AppTaskImpl extends IAppTask.Stub {
24269         private int mTaskId;
24270         private int mCallingUid;
24271
24272         public AppTaskImpl(int taskId, int callingUid) {
24273             mTaskId = taskId;
24274             mCallingUid = callingUid;
24275         }
24276
24277         private void checkCaller() {
24278             if (mCallingUid != Binder.getCallingUid()) {
24279                 throw new SecurityException("Caller " + mCallingUid
24280                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24281             }
24282         }
24283
24284         @Override
24285         public void finishAndRemoveTask() {
24286             checkCaller();
24287
24288             synchronized (ActivityManagerService.this) {
24289                 long origId = Binder.clearCallingIdentity();
24290                 try {
24291                     // We remove the task from recents to preserve backwards
24292                     if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24293                             REMOVE_FROM_RECENTS)) {
24294                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24295                     }
24296                 } finally {
24297                     Binder.restoreCallingIdentity(origId);
24298                 }
24299             }
24300         }
24301
24302         @Override
24303         public ActivityManager.RecentTaskInfo getTaskInfo() {
24304             checkCaller();
24305
24306             synchronized (ActivityManagerService.this) {
24307                 long origId = Binder.clearCallingIdentity();
24308                 try {
24309                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24310                     if (tr == null) {
24311                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24312                     }
24313                     return createRecentTaskInfoFromTaskRecord(tr);
24314                 } finally {
24315                     Binder.restoreCallingIdentity(origId);
24316                 }
24317             }
24318         }
24319
24320         @Override
24321         public void moveToFront() {
24322             checkCaller();
24323             // Will bring task to front if it already has a root activity.
24324             final long origId = Binder.clearCallingIdentity();
24325             try {
24326                 synchronized (this) {
24327                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24328                 }
24329             } finally {
24330                 Binder.restoreCallingIdentity(origId);
24331             }
24332         }
24333
24334         @Override
24335         public int startActivity(IBinder whoThread, String callingPackage,
24336                 Intent intent, String resolvedType, Bundle bOptions) {
24337             checkCaller();
24338
24339             int callingUser = UserHandle.getCallingUserId();
24340             TaskRecord tr;
24341             IApplicationThread appThread;
24342             synchronized (ActivityManagerService.this) {
24343                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24344                 if (tr == null) {
24345                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24346                 }
24347                 appThread = IApplicationThread.Stub.asInterface(whoThread);
24348                 if (appThread == null) {
24349                     throw new IllegalArgumentException("Bad app thread " + appThread);
24350                 }
24351             }
24352             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24353                     resolvedType, null, null, null, null, 0, 0, null, null,
24354                     null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
24355         }
24356
24357         @Override
24358         public void setExcludeFromRecents(boolean exclude) {
24359             checkCaller();
24360
24361             synchronized (ActivityManagerService.this) {
24362                 long origId = Binder.clearCallingIdentity();
24363                 try {
24364                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24365                     if (tr == null) {
24366                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24367                     }
24368                     Intent intent = tr.getBaseIntent();
24369                     if (exclude) {
24370                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24371                     } else {
24372                         intent.setFlags(intent.getFlags()
24373                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24374                     }
24375                 } finally {
24376                     Binder.restoreCallingIdentity(origId);
24377                 }
24378             }
24379         }
24380     }
24381
24382     /**
24383      * Kill processes for the user with id userId and that depend on the package named packageName
24384      */
24385     @Override
24386     public void killPackageDependents(String packageName, int userId) {
24387         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24388         if (packageName == null) {
24389             throw new NullPointerException(
24390                     "Cannot kill the dependents of a package without its name.");
24391         }
24392
24393         long callingId = Binder.clearCallingIdentity();
24394         IPackageManager pm = AppGlobals.getPackageManager();
24395         int pkgUid = -1;
24396         try {
24397             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24398         } catch (RemoteException e) {
24399         }
24400         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24401             throw new IllegalArgumentException(
24402                     "Cannot kill dependents of non-existing package " + packageName);
24403         }
24404         try {
24405             synchronized(this) {
24406                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24407                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24408                         "dep: " + packageName);
24409             }
24410         } finally {
24411             Binder.restoreCallingIdentity(callingId);
24412         }
24413     }
24414
24415     @Override
24416     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24417             throws RemoteException {
24418         final long callingId = Binder.clearCallingIdentity();
24419         try {
24420             mKeyguardController.dismissKeyguard(token, callback);
24421         } finally {
24422             Binder.restoreCallingIdentity(callingId);
24423         }
24424     }
24425
24426     @Override
24427     public int restartUserInBackground(final int userId) {
24428         return mUserController.restartUser(userId, /* foreground */ false);
24429     }
24430
24431     @Override
24432     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24433         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24434                 "scheduleApplicationInfoChanged()");
24435
24436         synchronized (this) {
24437             final long origId = Binder.clearCallingIdentity();
24438             try {
24439                 updateApplicationInfoLocked(packageNames, userId);
24440             } finally {
24441                 Binder.restoreCallingIdentity(origId);
24442             }
24443         }
24444     }
24445
24446     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24447         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24448         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24449             final ProcessRecord app = mLruProcesses.get(i);
24450             if (app.thread == null) {
24451                 continue;
24452             }
24453
24454             if (userId != UserHandle.USER_ALL && app.userId != userId) {
24455                 continue;
24456             }
24457
24458             final int packageCount = app.pkgList.size();
24459             for (int j = 0; j < packageCount; j++) {
24460                 final String packageName = app.pkgList.keyAt(j);
24461                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24462                     try {
24463                         final ApplicationInfo ai = AppGlobals.getPackageManager()
24464                                 .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
24465                         if (ai != null) {
24466                             app.thread.scheduleApplicationInfoChanged(ai);
24467                         }
24468                     } catch (RemoteException e) {
24469                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24470                                     packageName, app));
24471                     }
24472                 }
24473             }
24474         }
24475     }
24476
24477     /**
24478      * Attach an agent to the specified process (proces name or PID)
24479      */
24480     public void attachAgent(String process, String path) {
24481         try {
24482             synchronized (this) {
24483                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24484                 if (proc == null || proc.thread == null) {
24485                     throw new IllegalArgumentException("Unknown process: " + process);
24486                 }
24487
24488                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24489                 if (!isDebuggable) {
24490                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24491                         throw new SecurityException("Process not debuggable: " + proc);
24492                     }
24493                 }
24494
24495                 proc.thread.attachAgent(path);
24496             }
24497         } catch (RemoteException e) {
24498             throw new IllegalStateException("Process disappeared");
24499         }
24500     }
24501
24502     @VisibleForTesting
24503     public static class Injector {
24504         private NetworkManagementInternal mNmi;
24505
24506         public Context getContext() {
24507             return null;
24508         }
24509
24510         public AppOpsService getAppOpsService(File file, Handler handler) {
24511             return new AppOpsService(file, handler);
24512         }
24513
24514         public Handler getUiHandler(ActivityManagerService service) {
24515             return service.new UiHandler();
24516         }
24517
24518         public boolean isNetworkRestrictedForUid(int uid) {
24519             if (ensureHasNetworkManagementInternal()) {
24520                 return mNmi.isNetworkRestrictedForUid(uid);
24521             }
24522             return false;
24523         }
24524
24525         private boolean ensureHasNetworkManagementInternal() {
24526             if (mNmi == null) {
24527                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24528             }
24529             return mNmi != null;
24530         }
24531     }
24532 }