OSDN Git Service

Merge "Add permission check for old call handover apis."
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityManagerService.java
1 /*
2  * Copyright (C) 2006-2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.server.am;
18
19 import static android.Manifest.permission.CHANGE_CONFIGURATION;
20 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
24 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25 import static android.Manifest.permission.READ_FRAME_BUFFER;
26 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
28 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
29 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
31 import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
32 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
33 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
34 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
35 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
36 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
37 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
38 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
39 import static android.content.pm.PackageManager.GET_PROVIDERS;
40 import static android.content.pm.PackageManager.MATCH_ANY_USER;
41 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
43 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
44 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
45 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
46 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
47 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
49 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
50 import static android.os.Build.VERSION_CODES.N;
51 import static android.os.Process.BLUETOOTH_UID;
52 import static android.os.Process.FIRST_APPLICATION_UID;
53 import static android.os.Process.FIRST_ISOLATED_UID;
54 import static android.os.Process.LAST_ISOLATED_UID;
55 import static android.os.Process.NFC_UID;
56 import static android.os.Process.PHONE_UID;
57 import static android.os.Process.PROC_CHAR;
58 import static android.os.Process.PROC_OUT_LONG;
59 import static android.os.Process.PROC_PARENS;
60 import static android.os.Process.PROC_SPACE_TERM;
61 import static android.os.Process.ProcessStartResult;
62 import static android.os.Process.ROOT_UID;
63 import static android.os.Process.SCHED_FIFO;
64 import static android.os.Process.SCHED_OTHER;
65 import static android.os.Process.SCHED_RESET_ON_FORK;
66 import static android.os.Process.SHELL_UID;
67 import static android.os.Process.SIGNAL_QUIT;
68 import static android.os.Process.SIGNAL_USR1;
69 import static android.os.Process.SYSTEM_UID;
70 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
71 import static android.os.Process.THREAD_GROUP_DEFAULT;
72 import static android.os.Process.THREAD_GROUP_TOP_APP;
73 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
74 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
75 import static android.os.Process.getFreeMemory;
76 import static android.os.Process.getTotalMemory;
77 import static android.os.Process.isThreadInProcess;
78 import static android.os.Process.killProcess;
79 import static android.os.Process.killProcessQuiet;
80 import static android.os.Process.myPid;
81 import static android.os.Process.myUid;
82 import static android.os.Process.readProcFile;
83 import static android.os.Process.removeAllProcessGroups;
84 import static android.os.Process.sendSignal;
85 import static android.os.Process.setProcessGroup;
86 import static android.os.Process.setThreadPriority;
87 import static android.os.Process.setThreadScheduler;
88 import static android.os.Process.startWebView;
89 import static android.os.Process.zygoteProcess;
90 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
91 import static android.provider.Settings.Global.DEBUG_APP;
92 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
94 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
95 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
96 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
97 import static android.provider.Settings.System.FONT_SCALE;
98 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
99 import static android.text.format.DateUtils.DAY_IN_MILLIS;
100 import static android.view.Display.DEFAULT_DISPLAY;
101 import static android.view.Display.INVALID_DISPLAY;
102 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
103 import static com.android.internal.util.XmlUtils.readIntAttribute;
104 import static com.android.internal.util.XmlUtils.readLongAttribute;
105 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
106 import static com.android.internal.util.XmlUtils.writeIntAttribute;
107 import static com.android.internal.util.XmlUtils.writeLongAttribute;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
140 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
165 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
167 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
168 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
169 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
171 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
172 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
173 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
174 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
175 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
178 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
179 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
180 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
182 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
183 import static com.android.server.wm.AppTransition.TRANSIT_NONE;
184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
186 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
187 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
188 import static org.xmlpull.v1.XmlPullParser.START_TAG;
189
190 import android.Manifest;
191 import android.Manifest.permission;
192 import android.annotation.NonNull;
193 import android.annotation.Nullable;
194 import android.annotation.UserIdInt;
195 import android.app.Activity;
196 import android.app.ActivityManager;
197 import android.app.ActivityManager.RunningTaskInfo;
198 import android.app.ActivityManager.StackId;
199 import android.app.ActivityManager.StackInfo;
200 import android.app.ActivityManager.TaskSnapshot;
201 import android.app.ActivityManager.TaskThumbnailInfo;
202 import android.app.ActivityManagerInternal;
203 import android.app.ActivityManagerInternal.ScreenObserver;
204 import android.app.ActivityManagerInternal.SleepToken;
205 import android.app.ActivityOptions;
206 import android.app.ActivityThread;
207 import android.app.AlertDialog;
208 import android.app.AppGlobals;
209 import android.app.AppOpsManager;
210 import android.app.ApplicationErrorReport;
211 import android.app.ApplicationThreadConstants;
212 import android.app.BroadcastOptions;
213 import android.app.ContentProviderHolder;
214 import android.app.Dialog;
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.pm.ActivityInfo;
258 import android.content.pm.ApplicationInfo;
259 import android.content.pm.ConfigurationInfo;
260 import android.content.pm.IPackageDataObserver;
261 import android.content.pm.IPackageManager;
262 import android.content.pm.InstrumentationInfo;
263 import android.content.pm.PackageInfo;
264 import android.content.pm.PackageManager;
265 import android.content.pm.PackageManager.NameNotFoundException;
266 import android.content.pm.PackageManagerInternal;
267 import android.content.pm.ParceledListSlice;
268 import android.content.pm.PathPermission;
269 import android.content.pm.PermissionInfo;
270 import android.content.pm.ProviderInfo;
271 import android.content.pm.ResolveInfo;
272 import android.content.pm.SELinuxUtil;
273 import android.content.pm.ServiceInfo;
274 import android.content.pm.UserInfo;
275 import android.content.res.CompatibilityInfo;
276 import android.content.res.Configuration;
277 import android.content.res.Resources;
278 import android.database.ContentObserver;
279 import android.graphics.Bitmap;
280 import android.graphics.Point;
281 import android.graphics.Rect;
282 import android.location.LocationManager;
283 import android.media.audiofx.AudioEffect;
284 import android.metrics.LogMaker;
285 import android.net.Proxy;
286 import android.net.ProxyInfo;
287 import android.net.Uri;
288 import android.os.BatteryStats;
289 import android.os.Binder;
290 import android.os.Build;
291 import android.os.Bundle;
292 import android.os.Debug;
293 import android.os.DropBoxManager;
294 import android.os.Environment;
295 import android.os.FactoryTest;
296 import android.os.FileObserver;
297 import android.os.FileUtils;
298 import android.os.Handler;
299 import android.os.IBinder;
300 import android.os.IDeviceIdentifiersPolicyService;
301 import android.os.IPermissionController;
302 import android.os.IProcessInfoService;
303 import android.os.IProgressListener;
304 import android.os.LocaleList;
305 import android.os.Looper;
306 import android.os.Message;
307 import android.os.Parcel;
308 import android.os.ParcelFileDescriptor;
309 import android.os.PersistableBundle;
310 import android.os.PowerManager;
311 import android.os.PowerManagerInternal;
312 import android.os.Process;
313 import android.os.RemoteCallbackList;
314 import android.os.RemoteException;
315 import android.os.ResultReceiver;
316 import android.os.ServiceManager;
317 import android.os.ShellCallback;
318 import android.os.StrictMode;
319 import android.os.SystemClock;
320 import android.os.SystemProperties;
321 import android.os.Trace;
322 import android.os.TransactionTooLargeException;
323 import android.os.UpdateLock;
324 import android.os.UserHandle;
325 import android.os.UserManager;
326 import android.os.WorkSource;
327 import android.os.storage.IStorageManager;
328 import android.os.storage.StorageManager;
329 import android.os.storage.StorageManagerInternal;
330 import android.provider.Downloads;
331 import android.provider.Settings;
332 import android.service.voice.IVoiceInteractionSession;
333 import android.service.voice.VoiceInteractionManagerInternal;
334 import android.service.voice.VoiceInteractionSession;
335 import android.telecom.TelecomManager;
336 import android.text.TextUtils;
337 import android.text.format.DateUtils;
338 import android.text.format.Time;
339 import android.text.style.SuggestionSpan;
340 import android.util.ArrayMap;
341 import android.util.ArraySet;
342 import android.util.AtomicFile;
343 import android.util.TimingsTraceLog;
344 import android.util.DebugUtils;
345 import android.util.DisplayMetrics;
346 import android.util.EventLog;
347 import android.util.Log;
348 import android.util.Pair;
349 import android.util.PrintWriterPrinter;
350 import android.util.Slog;
351 import android.util.SparseArray;
352 import android.util.SparseIntArray;
353 import android.util.TimeUtils;
354 import android.util.Xml;
355 import android.view.Gravity;
356 import android.view.LayoutInflater;
357 import android.view.View;
358 import android.view.WindowManager;
359
360 import com.android.server.job.JobSchedulerInternal;
361 import com.google.android.collect.Lists;
362 import com.google.android.collect.Maps;
363
364 import com.android.internal.R;
365 import com.android.internal.annotations.GuardedBy;
366 import com.android.internal.annotations.VisibleForTesting;
367 import com.android.internal.app.AssistUtils;
368 import com.android.internal.app.DumpHeapActivity;
369 import com.android.internal.app.IAppOpsCallback;
370 import com.android.internal.app.IAppOpsService;
371 import com.android.internal.app.IVoiceInteractor;
372 import com.android.internal.app.ProcessMap;
373 import com.android.internal.app.SystemUserHomeActivity;
374 import com.android.internal.app.procstats.ProcessStats;
375 import com.android.internal.logging.MetricsLogger;
376 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
377 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
378 import com.android.internal.notification.SystemNotificationChannels;
379 import com.android.internal.os.BackgroundThread;
380 import com.android.internal.os.BatteryStatsImpl;
381 import com.android.internal.os.IResultReceiver;
382 import com.android.internal.os.ProcessCpuTracker;
383 import com.android.internal.os.TransferPipe;
384 import com.android.internal.os.Zygote;
385 import com.android.internal.policy.IKeyguardDismissCallback;
386 import com.android.internal.telephony.TelephonyIntents;
387 import com.android.internal.util.ArrayUtils;
388 import com.android.internal.util.DumpUtils;
389 import com.android.internal.util.FastPrintWriter;
390 import com.android.internal.util.FastXmlSerializer;
391 import com.android.internal.util.MemInfoReader;
392 import com.android.internal.util.Preconditions;
393 import com.android.server.AppOpsService;
394 import com.android.server.AttributeCache;
395 import com.android.server.DeviceIdleController;
396 import com.android.server.IntentResolver;
397 import com.android.server.LocalServices;
398 import com.android.server.LockGuard;
399 import com.android.server.NetworkManagementInternal;
400 import com.android.server.RescueParty;
401 import com.android.server.ServiceThread;
402 import com.android.server.SystemConfig;
403 import com.android.server.SystemService;
404 import com.android.server.SystemServiceManager;
405 import com.android.server.ThreadPriorityBooster;
406 import com.android.server.Watchdog;
407 import com.android.server.am.ActivityStack.ActivityState;
408 import com.android.server.firewall.IntentFirewall;
409 import com.android.server.pm.Installer;
410 import com.android.server.pm.Installer.InstallerException;
411 import com.android.server.statusbar.StatusBarManagerInternal;
412 import com.android.server.vr.VrManagerInternal;
413 import com.android.server.wm.PinnedStackWindowController;
414 import com.android.server.wm.WindowManagerService;
415
416 import java.text.SimpleDateFormat;
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_LOCKTASK = TAG + POSTFIX_LOCKTASK;
471     private static final String TAG_LRU = TAG + POSTFIX_LRU;
472     private static final String TAG_MU = TAG + POSTFIX_MU;
473     private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
474     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
475     private static final String TAG_POWER = TAG + POSTFIX_POWER;
476     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
477     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
478     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
479     private static final String TAG_PSS = TAG + POSTFIX_PSS;
480     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
481     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
482     private static final String TAG_STACK = TAG + POSTFIX_STACK;
483     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
484     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
485     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
486     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
487
488     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
489     // here so that while the job scheduler can depend on AMS, the other way around
490     // need not be the case.
491     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
492
493     /** Control over CPU and battery monitoring */
494     // write battery stats every 30 minutes.
495     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
496     static final boolean MONITOR_CPU_USAGE = true;
497     // don't sample cpu less than every 5 seconds.
498     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
499     // wait possibly forever for next cpu sample.
500     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
501     static final boolean MONITOR_THREAD_CPU_USAGE = false;
502
503     // The flags that are set for all calls we make to the package manager.
504     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
505
506     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
507
508     // Amount of time after a call to stopAppSwitches() during which we will
509     // prevent further untrusted switches from happening.
510     static final long APP_SWITCH_DELAY_TIME = 5*1000;
511
512     // How long we wait for a launched process to attach to the activity manager
513     // before we decide it's never going to come up for real.
514     static final int PROC_START_TIMEOUT = 10*1000;
515     // How long we wait for an attached process to publish its content providers
516     // before we decide it must be hung.
517     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
518
519     // How long we wait for a launched process to attach to the activity manager
520     // before we decide it's never going to come up for real, when the process was
521     // started with a wrapper for instrumentation (such as Valgrind) because it
522     // could take much longer than usual.
523     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
524
525     // How long we allow a receiver to run before giving up on it.
526     static final int BROADCAST_FG_TIMEOUT = 10*1000;
527     static final int BROADCAST_BG_TIMEOUT = 60*1000;
528
529     // How long we wait until we timeout on key dispatching.
530     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
531
532     // How long we wait until we timeout on key dispatching during instrumentation.
533     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
534
535     // How long to wait in getAssistContextExtras for the activity and foreground services
536     // to respond with the result.
537     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
538
539     // How long top wait when going through the modern assist (which doesn't need to block
540     // on getting this result before starting to launch its UI).
541     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
542
543     // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
544     static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
545
546     // Maximum number of persisted Uri grants a package is allowed
547     static final int MAX_PERSISTED_URI_GRANTS = 128;
548
549     static final int MY_PID = myPid();
550
551     static final String[] EMPTY_STRING_ARRAY = new String[0];
552
553     // How many bytes to write into the dropbox log before truncating
554     static final int DROPBOX_MAX_SIZE = 192 * 1024;
555     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
556     // as one line, but close enough for now.
557     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
558
559     // Access modes for handleIncomingUser.
560     static final int ALLOW_NON_FULL = 0;
561     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
562     static final int ALLOW_FULL_ONLY = 2;
563
564     // Necessary ApplicationInfo flags to mark an app as persistent
565     private static final int PERSISTENT_MASK =
566             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
567
568     // Intent sent when remote bugreport collection has been completed
569     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
570             "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
571
572     // Used to indicate that an app transition should be animated.
573     static final boolean ANIMATE = true;
574
575     // Determines whether to take full screen screenshots
576     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
577
578     /**
579      * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
580      */
581     private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
582
583     /**
584      * State indicating that there is no need for any blocking for network.
585      */
586     @VisibleForTesting
587     static final int NETWORK_STATE_NO_CHANGE = 0;
588
589     /**
590      * State indicating that the main thread needs to be informed about the network wait.
591      */
592     @VisibleForTesting
593     static final int NETWORK_STATE_BLOCK = 1;
594
595     /**
596      * State indicating that any threads waiting for network state to get updated can be unblocked.
597      */
598     @VisibleForTesting
599     static final int NETWORK_STATE_UNBLOCK = 2;
600
601     // Max character limit for a notification title. If the notification title is larger than this
602     // the notification will not be legible to the user.
603     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
604
605     private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
606
607     /** All system services */
608     SystemServiceManager mSystemServiceManager;
609     AssistUtils mAssistUtils;
610
611     private Installer mInstaller;
612
613     /** Run all ActivityStacks through this */
614     final ActivityStackSupervisor mStackSupervisor;
615     private final KeyguardController mKeyguardController;
616
617     final ActivityStarter mActivityStarter;
618
619     final TaskChangeNotificationController mTaskChangeNotificationController;
620
621     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
622
623     final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
624
625     public final IntentFirewall mIntentFirewall;
626
627     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
628     // default action automatically.  Important for devices without direct input
629     // devices.
630     private boolean mShowDialogs = true;
631
632     private final VrController mVrController;
633
634     // VR Vr2d Display Id.
635     int mVr2dDisplayId = INVALID_DISPLAY;
636
637     // Whether we should use SCHED_FIFO for UI and RenderThreads.
638     private boolean mUseFifoUiScheduling = false;
639
640     BroadcastQueue mFgBroadcastQueue;
641     BroadcastQueue mBgBroadcastQueue;
642     // Convenient for easy iteration over the queues. Foreground is first
643     // so that dispatch of foreground broadcasts gets precedence.
644     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
645
646     BroadcastStats mLastBroadcastStats;
647     BroadcastStats mCurBroadcastStats;
648
649     BroadcastQueue broadcastQueueForIntent(Intent intent) {
650         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
651         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
652                 "Broadcast intent " + intent + " on "
653                 + (isFg ? "foreground" : "background") + " queue");
654         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
655     }
656
657     /**
658      * The last resumed activity. This is identical to the current resumed activity most
659      * of the time but could be different when we're pausing one activity before we resume
660      * another activity.
661      */
662     private ActivityRecord mLastResumedActivity;
663
664     /**
665      * If non-null, we are tracking the time the user spends in the currently focused app.
666      */
667     private AppTimeTracker mCurAppTimeTracker;
668
669     /**
670      * List of intents that were used to start the most recent tasks.
671      */
672     final RecentTasks mRecentTasks;
673
674     /**
675      * For addAppTask: cached of the last activity component that was added.
676      */
677     ComponentName mLastAddedTaskComponent;
678
679     /**
680      * For addAppTask: cached of the last activity uid that was added.
681      */
682     int mLastAddedTaskUid;
683
684     /**
685      * For addAppTask: cached of the last ActivityInfo that was added.
686      */
687     ActivityInfo mLastAddedTaskActivity;
688
689     /**
690      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
691      */
692     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
693
694     /**
695      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
696      */
697     String mDeviceOwnerName;
698
699     final UserController mUserController;
700
701     final AppErrors mAppErrors;
702
703     /**
704      * Dump of the activity state at the time of the last ANR. Cleared after
705      * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
706      */
707     String mLastANRState;
708
709     /**
710      * Indicates the maximum time spent waiting for the network rules to get updated.
711      */
712     @VisibleForTesting
713     long mWaitForNetworkTimeoutMs;
714
715     public boolean canShowErrorDialogs() {
716         return mShowDialogs && !mSleeping && !mShuttingDown
717                 && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
718                 && !(UserManager.isDeviceInDemoMode(mContext)
719                         && mUserController.getCurrentUser().isDemo());
720     }
721
722     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
723             THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
724
725     static void boostPriorityForLockedSection() {
726         sThreadPriorityBooster.boost();
727     }
728
729     static void resetPriorityAfterLockedSection() {
730         sThreadPriorityBooster.reset();
731     }
732
733     public class PendingAssistExtras extends Binder implements Runnable {
734         public final ActivityRecord activity;
735         public boolean isHome;
736         public final Bundle extras;
737         public final Intent intent;
738         public final String hint;
739         public final IResultReceiver receiver;
740         public final int userHandle;
741         public boolean haveResult = false;
742         public Bundle result = null;
743         public AssistStructure structure = null;
744         public AssistContent content = null;
745         public Bundle receiverExtras;
746
747         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
748                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
749             activity = _activity;
750             extras = _extras;
751             intent = _intent;
752             hint = _hint;
753             receiver = _receiver;
754             receiverExtras = _receiverExtras;
755             userHandle = _userHandle;
756         }
757
758         @Override
759         public void run() {
760             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
761             synchronized (this) {
762                 haveResult = true;
763                 notifyAll();
764             }
765             pendingAssistExtrasTimedOut(this);
766         }
767     }
768
769     final ArrayList<PendingAssistExtras> mPendingAssistExtras
770             = new ArrayList<PendingAssistExtras>();
771
772     /**
773      * Process management.
774      */
775     final ProcessList mProcessList = new ProcessList();
776
777     /**
778      * All of the applications we currently have running organized by name.
779      * The keys are strings of the application package name (as
780      * returned by the package manager), and the keys are ApplicationRecord
781      * objects.
782      */
783     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
784
785     /**
786      * Tracking long-term execution of processes to look for abuse and other
787      * bad app behavior.
788      */
789     final ProcessStatsService mProcessStats;
790
791     /**
792      * The currently running isolated processes.
793      */
794     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
795
796     /**
797      * Counter for assigning isolated process uids, to avoid frequently reusing the
798      * same ones.
799      */
800     int mNextIsolatedProcessUid = 0;
801
802     /**
803      * The currently running heavy-weight process, if any.
804      */
805     ProcessRecord mHeavyWeightProcess = null;
806
807     /**
808      * Non-persistent appId whitelist for background restrictions
809      */
810     int[] mBackgroundAppIdWhitelist = new int[] {
811             BLUETOOTH_UID
812     };
813
814     /**
815      * Broadcast actions that will always be deliverable to unlaunched/background apps
816      */
817     ArraySet<String> mBackgroundLaunchBroadcasts;
818
819     /**
820      * All of the processes we currently have running organized by pid.
821      * The keys are the pid running the application.
822      *
823      * <p>NOTE: This object is protected by its own lock, NOT the global
824      * activity manager lock!
825      */
826     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
827
828     /**
829      * All of the processes that have been forced to be important.  The key
830      * is the pid of the caller who requested it (we hold a death
831      * link on it).
832      */
833     abstract class ImportanceToken implements IBinder.DeathRecipient {
834         final int pid;
835         final IBinder token;
836         final String reason;
837
838         ImportanceToken(int _pid, IBinder _token, String _reason) {
839             pid = _pid;
840             token = _token;
841             reason = _reason;
842         }
843
844         @Override
845         public String toString() {
846             return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
847                     + " " + reason + " " + pid + " " + token + " }";
848         }
849     }
850     final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
851
852     /**
853      * List of records for processes that someone had tried to start before the
854      * system was ready.  We don't start them at that point, but ensure they
855      * are started by the time booting is complete.
856      */
857     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
858
859     /**
860      * List of persistent applications that are in the process
861      * of being started.
862      */
863     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
864
865     /**
866      * Processes that are being forcibly torn down.
867      */
868     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
869
870     /**
871      * List of running applications, sorted by recent usage.
872      * The first entry in the list is the least recently used.
873      */
874     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
875
876     /**
877      * Where in mLruProcesses that the processes hosting activities start.
878      */
879     int mLruProcessActivityStart = 0;
880
881     /**
882      * Where in mLruProcesses that the processes hosting services start.
883      * This is after (lower index) than mLruProcessesActivityStart.
884      */
885     int mLruProcessServiceStart = 0;
886
887     /**
888      * List of processes that should gc as soon as things are idle.
889      */
890     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
891
892     /**
893      * Processes we want to collect PSS data from.
894      */
895     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
896
897     private boolean mBinderTransactionTrackingEnabled = false;
898
899     /**
900      * Last time we requested PSS data of all processes.
901      */
902     long mLastFullPssTime = SystemClock.uptimeMillis();
903
904     /**
905      * If set, the next time we collect PSS data we should do a full collection
906      * with data from native processes and the kernel.
907      */
908     boolean mFullPssPending = false;
909
910     /**
911      * This is the process holding what we currently consider to be
912      * the "home" activity.
913      */
914     ProcessRecord mHomeProcess;
915
916     /**
917      * This is the process holding the activity the user last visited that
918      * is in a different process from the one they are currently in.
919      */
920     ProcessRecord mPreviousProcess;
921
922     /**
923      * The time at which the previous process was last visible.
924      */
925     long mPreviousProcessVisibleTime;
926
927     /**
928      * Track all uids that have actively running processes.
929      */
930     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
931
932     /**
933      * This is for verifying the UID report flow.
934      */
935     static final boolean VALIDATE_UID_STATES = true;
936     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
937
938     /**
939      * Packages that the user has asked to have run in screen size
940      * compatibility mode instead of filling the screen.
941      */
942     final CompatModePackages mCompatModePackages;
943
944     /**
945      * Set of IntentSenderRecord objects that are currently active.
946      */
947     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
948             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
949
950     /**
951      * Fingerprints (hashCode()) of stack traces that we've
952      * already logged DropBox entries for.  Guarded by itself.  If
953      * something (rogue user app) forces this over
954      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
955      */
956     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
957     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
958
959     /**
960      * Strict Mode background batched logging state.
961      *
962      * The string buffer is guarded by itself, and its lock is also
963      * used to determine if another batched write is already
964      * in-flight.
965      */
966     private final StringBuilder mStrictModeBuffer = new StringBuilder();
967
968     /**
969      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
970      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
971      */
972     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
973
974     /**
975      * Resolver for broadcast intents to registered receivers.
976      * Holds BroadcastFilter (subclass of IntentFilter).
977      */
978     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
979             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
980         @Override
981         protected boolean allowFilterResult(
982                 BroadcastFilter filter, List<BroadcastFilter> dest) {
983             IBinder target = filter.receiverList.receiver.asBinder();
984             for (int i = dest.size() - 1; i >= 0; i--) {
985                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
986                     return false;
987                 }
988             }
989             return true;
990         }
991
992         @Override
993         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
994             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
995                     || userId == filter.owningUserId) {
996                 return super.newResult(filter, match, userId);
997             }
998             return null;
999         }
1000
1001         @Override
1002         protected BroadcastFilter[] newArray(int size) {
1003             return new BroadcastFilter[size];
1004         }
1005
1006         @Override
1007         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1008             return packageName.equals(filter.packageName);
1009         }
1010     };
1011
1012     /**
1013      * State of all active sticky broadcasts per user.  Keys are the action of the
1014      * sticky Intent, values are an ArrayList of all broadcasted intents with
1015      * that action (which should usually be one).  The SparseArray is keyed
1016      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1017      * for stickies that are sent to all users.
1018      */
1019     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1020             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1021
1022     final ActiveServices mServices;
1023
1024     final static class Association {
1025         final int mSourceUid;
1026         final String mSourceProcess;
1027         final int mTargetUid;
1028         final ComponentName mTargetComponent;
1029         final String mTargetProcess;
1030
1031         int mCount;
1032         long mTime;
1033
1034         int mNesting;
1035         long mStartTime;
1036
1037         // states of the source process when the bind occurred.
1038         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1039         long mLastStateUptime;
1040         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1041                 - ActivityManager.MIN_PROCESS_STATE+1];
1042
1043         Association(int sourceUid, String sourceProcess, int targetUid,
1044                 ComponentName targetComponent, String targetProcess) {
1045             mSourceUid = sourceUid;
1046             mSourceProcess = sourceProcess;
1047             mTargetUid = targetUid;
1048             mTargetComponent = targetComponent;
1049             mTargetProcess = targetProcess;
1050         }
1051     }
1052
1053     /**
1054      * When service association tracking is enabled, this is all of the associations we
1055      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1056      * -> association data.
1057      */
1058     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1059             mAssociations = new SparseArray<>();
1060     boolean mTrackingAssociations;
1061
1062     /**
1063      * Backup/restore process management
1064      */
1065     String mBackupAppName = null;
1066     BackupRecord mBackupTarget = null;
1067
1068     final ProviderMap mProviderMap;
1069
1070     /**
1071      * List of content providers who have clients waiting for them.  The
1072      * application is currently being launched and the provider will be
1073      * removed from this list once it is published.
1074      */
1075     final ArrayList<ContentProviderRecord> mLaunchingProviders
1076             = new ArrayList<ContentProviderRecord>();
1077
1078     /**
1079      * File storing persisted {@link #mGrantedUriPermissions}.
1080      */
1081     private final AtomicFile mGrantFile;
1082
1083     /** XML constants used in {@link #mGrantFile} */
1084     private static final String TAG_URI_GRANTS = "uri-grants";
1085     private static final String TAG_URI_GRANT = "uri-grant";
1086     private static final String ATTR_USER_HANDLE = "userHandle";
1087     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1088     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1089     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1090     private static final String ATTR_TARGET_PKG = "targetPkg";
1091     private static final String ATTR_URI = "uri";
1092     private static final String ATTR_MODE_FLAGS = "modeFlags";
1093     private static final String ATTR_CREATED_TIME = "createdTime";
1094     private static final String ATTR_PREFIX = "prefix";
1095
1096     /**
1097      * Global set of specific {@link Uri} permissions that have been granted.
1098      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1099      * to {@link UriPermission#uri} to {@link UriPermission}.
1100      */
1101     @GuardedBy("this")
1102     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1103             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1104
1105     public static class GrantUri {
1106         public final int sourceUserId;
1107         public final Uri uri;
1108         public boolean prefix;
1109
1110         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1111             this.sourceUserId = sourceUserId;
1112             this.uri = uri;
1113             this.prefix = prefix;
1114         }
1115
1116         @Override
1117         public int hashCode() {
1118             int hashCode = 1;
1119             hashCode = 31 * hashCode + sourceUserId;
1120             hashCode = 31 * hashCode + uri.hashCode();
1121             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1122             return hashCode;
1123         }
1124
1125         @Override
1126         public boolean equals(Object o) {
1127             if (o instanceof GrantUri) {
1128                 GrantUri other = (GrantUri) o;
1129                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1130                         && prefix == other.prefix;
1131             }
1132             return false;
1133         }
1134
1135         @Override
1136         public String toString() {
1137             String result = uri.toString() + " [user " + sourceUserId + "]";
1138             if (prefix) result += " [prefix]";
1139             return result;
1140         }
1141
1142         public String toSafeString() {
1143             String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1144             if (prefix) result += " [prefix]";
1145             return result;
1146         }
1147
1148         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1149             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1150                     ContentProvider.getUriWithoutUserId(uri), false);
1151         }
1152     }
1153
1154     CoreSettingsObserver mCoreSettingsObserver;
1155
1156     FontScaleSettingObserver mFontScaleSettingObserver;
1157
1158     private final class FontScaleSettingObserver extends ContentObserver {
1159         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1160
1161         public FontScaleSettingObserver() {
1162             super(mHandler);
1163             ContentResolver resolver = mContext.getContentResolver();
1164             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1165         }
1166
1167         @Override
1168         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1169             if (mFontScaleUri.equals(uri)) {
1170                 updateFontScaleIfNeeded(userId);
1171             }
1172         }
1173     }
1174
1175     /**
1176      * Thread-local storage used to carry caller permissions over through
1177      * indirect content-provider access.
1178      */
1179     private class Identity {
1180         public final IBinder token;
1181         public final int pid;
1182         public final int uid;
1183
1184         Identity(IBinder _token, int _pid, int _uid) {
1185             token = _token;
1186             pid = _pid;
1187             uid = _uid;
1188         }
1189     }
1190
1191     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1192
1193     /**
1194      * All information we have collected about the runtime performance of
1195      * any user id that can impact battery performance.
1196      */
1197     final BatteryStatsService mBatteryStatsService;
1198
1199     /**
1200      * Information about component usage
1201      */
1202     UsageStatsManagerInternal mUsageStatsService;
1203
1204     /**
1205      * Access to DeviceIdleController service.
1206      */
1207     DeviceIdleController.LocalService mLocalDeviceIdleController;
1208
1209     /**
1210      * Set of app ids that are whitelisted for device idle and thus background check.
1211      */
1212     int[] mDeviceIdleWhitelist = new int[0];
1213
1214     /**
1215      * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1216      */
1217     int[] mDeviceIdleTempWhitelist = new int[0];
1218
1219     static final class PendingTempWhitelist {
1220         final int targetUid;
1221         final long duration;
1222         final String tag;
1223
1224         PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1225             targetUid = _targetUid;
1226             duration = _duration;
1227             tag = _tag;
1228         }
1229     }
1230
1231     final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1232
1233     /**
1234      * Information about and control over application operations
1235      */
1236     final AppOpsService mAppOpsService;
1237
1238     /** Current sequencing integer of the configuration, for skipping old configurations. */
1239     private int mConfigurationSeq;
1240
1241     /**
1242      * Temp object used when global and/or display override configuration is updated. It is also
1243      * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1244      * anyone...
1245      */
1246     private Configuration mTempConfig = new Configuration();
1247
1248     private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1249             new UpdateConfigurationResult();
1250     private static final class UpdateConfigurationResult {
1251         // Configuration changes that were updated.
1252         int changes;
1253         // If the activity was relaunched to match the new configuration.
1254         boolean activityRelaunched;
1255
1256         void reset() {
1257             changes = 0;
1258             activityRelaunched = false;
1259         }
1260     }
1261
1262     boolean mSuppressResizeConfigChanges;
1263
1264     /**
1265      * Hardware-reported OpenGLES version.
1266      */
1267     final int GL_ES_VERSION;
1268
1269     /**
1270      * List of initialization arguments to pass to all processes when binding applications to them.
1271      * For example, references to the commonly used services.
1272      */
1273     HashMap<String, IBinder> mAppBindArgs;
1274     HashMap<String, IBinder> mIsolatedAppBindArgs;
1275
1276     /**
1277      * Temporary to avoid allocations.  Protected by main lock.
1278      */
1279     final StringBuilder mStringBuilder = new StringBuilder(256);
1280
1281     /**
1282      * Used to control how we initialize the service.
1283      */
1284     ComponentName mTopComponent;
1285     String mTopAction = Intent.ACTION_MAIN;
1286     String mTopData;
1287
1288     volatile boolean mProcessesReady = false;
1289     volatile boolean mSystemReady = false;
1290     volatile boolean mOnBattery = false;
1291     volatile int mFactoryTest;
1292
1293     @GuardedBy("this") boolean mBooting = false;
1294     @GuardedBy("this") boolean mCallFinishBooting = false;
1295     @GuardedBy("this") boolean mBootAnimationComplete = false;
1296     @GuardedBy("this") boolean mLaunchWarningShown = false;
1297     @GuardedBy("this") boolean mCheckedForSetup = false;
1298
1299     final Context mContext;
1300
1301     /**
1302      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1303      * change at runtime. Use mContext for non-UI purposes.
1304      */
1305     final Context mUiContext;
1306
1307     /**
1308      * The time at which we will allow normal application switches again,
1309      * after a call to {@link #stopAppSwitches()}.
1310      */
1311     long mAppSwitchesAllowedTime;
1312
1313     /**
1314      * This is set to true after the first switch after mAppSwitchesAllowedTime
1315      * is set; any switches after that will clear the time.
1316      */
1317     boolean mDidAppSwitch;
1318
1319     /**
1320      * Last time (in uptime) at which we checked for power usage.
1321      */
1322     long mLastPowerCheckUptime;
1323
1324     /**
1325      * Set while we are wanting to sleep, to prevent any
1326      * activities from being started/resumed.
1327      *
1328      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1329      *
1330      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1331      * while in the sleep state until there is a pending transition out of sleep, in which case
1332      * mSleeping is set to false, and remains false while awake.
1333      *
1334      * Whether mSleeping can quickly toggled between true/false without the device actually
1335      * display changing states is undefined.
1336      */
1337     private boolean mSleeping = false;
1338
1339     /**
1340      * The process state used for processes that are running the top activities.
1341      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1342      */
1343     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1344
1345     /**
1346      * Set while we are running a voice interaction.  This overrides
1347      * sleeping while it is active.
1348      */
1349     IVoiceInteractionSession mRunningVoice;
1350
1351     /**
1352      * For some direct access we need to power manager.
1353      */
1354     PowerManagerInternal mLocalPowerManager;
1355
1356     /**
1357      * We want to hold a wake lock while running a voice interaction session, since
1358      * this may happen with the screen off and we need to keep the CPU running to
1359      * be able to continue to interact with the user.
1360      */
1361     PowerManager.WakeLock mVoiceWakeLock;
1362
1363     /**
1364      * State of external calls telling us if the device is awake or asleep.
1365      */
1366     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1367
1368     /**
1369      * Set if we are shutting down the system, similar to sleeping.
1370      */
1371     boolean mShuttingDown = false;
1372
1373     /**
1374      * Current sequence id for oom_adj computation traversal.
1375      */
1376     int mAdjSeq = 0;
1377
1378     /**
1379      * Current sequence id for process LRU updating.
1380      */
1381     int mLruSeq = 0;
1382
1383     /**
1384      * Keep track of the non-cached/empty process we last found, to help
1385      * determine how to distribute cached/empty processes next time.
1386      */
1387     int mNumNonCachedProcs = 0;
1388
1389     /**
1390      * Keep track of the number of cached hidden procs, to balance oom adj
1391      * distribution between those and empty procs.
1392      */
1393     int mNumCachedHiddenProcs = 0;
1394
1395     /**
1396      * Keep track of the number of service processes we last found, to
1397      * determine on the next iteration which should be B services.
1398      */
1399     int mNumServiceProcs = 0;
1400     int mNewNumAServiceProcs = 0;
1401     int mNewNumServiceProcs = 0;
1402
1403     /**
1404      * Allow the current computed overall memory level of the system to go down?
1405      * This is set to false when we are killing processes for reasons other than
1406      * memory management, so that the now smaller process list will not be taken as
1407      * an indication that memory is tighter.
1408      */
1409     boolean mAllowLowerMemLevel = false;
1410
1411     /**
1412      * The last computed memory level, for holding when we are in a state that
1413      * processes are going away for other reasons.
1414      */
1415     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1416
1417     /**
1418      * The last total number of process we have, to determine if changes actually look
1419      * like a shrinking number of process due to lower RAM.
1420      */
1421     int mLastNumProcesses;
1422
1423     /**
1424      * The uptime of the last time we performed idle maintenance.
1425      */
1426     long mLastIdleTime = SystemClock.uptimeMillis();
1427
1428     /**
1429      * Total time spent with RAM that has been added in the past since the last idle time.
1430      */
1431     long mLowRamTimeSinceLastIdle = 0;
1432
1433     /**
1434      * If RAM is currently low, when that horrible situation started.
1435      */
1436     long mLowRamStartTime = 0;
1437
1438     /**
1439      * For reporting to battery stats the current top application.
1440      */
1441     private String mCurResumedPackage = null;
1442     private int mCurResumedUid = -1;
1443
1444     /**
1445      * For reporting to battery stats the apps currently running foreground
1446      * service.  The ProcessMap is package/uid tuples; each of these contain
1447      * an array of the currently foreground processes.
1448      */
1449     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1450             = new ProcessMap<ArrayList<ProcessRecord>>();
1451
1452     /**
1453      * Set if the systemServer made a call to enterSafeMode.
1454      */
1455     boolean mSafeMode;
1456
1457     /**
1458      * If true, we are running under a test environment so will sample PSS from processes
1459      * much more rapidly to try to collect better data when the tests are rapidly
1460      * running through apps.
1461      */
1462     boolean mTestPssMode = false;
1463
1464     String mDebugApp = null;
1465     boolean mWaitForDebugger = false;
1466     boolean mDebugTransient = false;
1467     String mOrigDebugApp = null;
1468     boolean mOrigWaitForDebugger = false;
1469     boolean mAlwaysFinishActivities = false;
1470     boolean mForceResizableActivities;
1471     /**
1472      * Flag that indicates if multi-window is enabled.
1473      *
1474      * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1475      * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1476      * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1477      * At least one of the forms of multi-window must be enabled in order for this flag to be
1478      * initialized to 'true'.
1479      *
1480      * @see #mSupportsSplitScreenMultiWindow
1481      * @see #mSupportsFreeformWindowManagement
1482      * @see #mSupportsPictureInPicture
1483      * @see #mSupportsMultiDisplay
1484      */
1485     boolean mSupportsMultiWindow;
1486     boolean mSupportsSplitScreenMultiWindow;
1487     boolean mSupportsFreeformWindowManagement;
1488     boolean mSupportsPictureInPicture;
1489     boolean mSupportsMultiDisplay;
1490     boolean mSupportsLeanbackOnly;
1491     IActivityController mController = null;
1492     boolean mControllerIsAMonkey = false;
1493     String mProfileApp = null;
1494     ProcessRecord mProfileProc = null;
1495     ProfilerInfo mProfilerInfo = null;
1496     int mProfileType = 0;
1497     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1498     String mMemWatchDumpProcName;
1499     String mMemWatchDumpFile;
1500     int mMemWatchDumpPid;
1501     int mMemWatchDumpUid;
1502     String mTrackAllocationApp = null;
1503     String mNativeDebuggingApp = null;
1504
1505     final long[] mTmpLong = new long[2];
1506
1507     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1508
1509     /**
1510      * A global counter for generating sequence numbers.
1511      * This value will be used when incrementing sequence numbers in individual uidRecords.
1512      *
1513      * Having a global counter ensures that seq numbers are monotonically increasing for a
1514      * particular uid even when the uidRecord is re-created.
1515      */
1516     @GuardedBy("this")
1517     @VisibleForTesting
1518     long mProcStateSeqCounter = 0;
1519
1520     private final Injector mInjector;
1521
1522     static final class ProcessChangeItem {
1523         static final int CHANGE_ACTIVITIES = 1<<0;
1524         int changes;
1525         int uid;
1526         int pid;
1527         int processState;
1528         boolean foregroundActivities;
1529     }
1530
1531     static final class UidObserverRegistration {
1532         final int uid;
1533         final String pkg;
1534         final int which;
1535         final int cutpoint;
1536
1537         final SparseIntArray lastProcStates;
1538
1539         UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1540             uid = _uid;
1541             pkg = _pkg;
1542             which = _which;
1543             cutpoint = _cutpoint;
1544             if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1545                 lastProcStates = new SparseIntArray();
1546             } else {
1547                 lastProcStates = null;
1548             }
1549         }
1550     }
1551
1552     final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1553
1554     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1555     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1556
1557     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1558     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1559
1560     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1561     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1562
1563     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1564     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1565
1566     OomAdjObserver mCurOomAdjObserver;
1567     int mCurOomAdjUid;
1568
1569     interface OomAdjObserver {
1570         void onOomAdjMessage(String msg);
1571     }
1572
1573     /**
1574      * Runtime CPU use collection thread.  This object's lock is used to
1575      * perform synchronization with the thread (notifying it to run).
1576      */
1577     final Thread mProcessCpuThread;
1578
1579     /**
1580      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1581      * Must acquire this object's lock when accessing it.
1582      * NOTE: this lock will be held while doing long operations (trawling
1583      * through all processes in /proc), so it should never be acquired by
1584      * any critical paths such as when holding the main activity manager lock.
1585      */
1586     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1587             MONITOR_THREAD_CPU_USAGE);
1588     final AtomicLong mLastCpuTime = new AtomicLong(0);
1589     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1590     final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1591
1592     long mLastWriteTime = 0;
1593
1594     /**
1595      * Used to retain an update lock when the foreground activity is in
1596      * immersive mode.
1597      */
1598     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1599
1600     /**
1601      * Set to true after the system has finished booting.
1602      */
1603     boolean mBooted = false;
1604
1605     WindowManagerService mWindowManager;
1606     final ActivityThread mSystemThread;
1607
1608     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1609         final ProcessRecord mApp;
1610         final int mPid;
1611         final IApplicationThread mAppThread;
1612
1613         AppDeathRecipient(ProcessRecord app, int pid,
1614                 IApplicationThread thread) {
1615             if (DEBUG_ALL) Slog.v(
1616                 TAG, "New death recipient " + this
1617                 + " for thread " + thread.asBinder());
1618             mApp = app;
1619             mPid = pid;
1620             mAppThread = thread;
1621         }
1622
1623         @Override
1624         public void binderDied() {
1625             if (DEBUG_ALL) Slog.v(
1626                 TAG, "Death received in " + this
1627                 + " for thread " + mAppThread.asBinder());
1628             synchronized(ActivityManagerService.this) {
1629                 appDiedLocked(mApp, mPid, mAppThread, true);
1630             }
1631         }
1632     }
1633
1634     static final int SHOW_ERROR_UI_MSG = 1;
1635     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1636     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1637     static final int UPDATE_CONFIGURATION_MSG = 4;
1638     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1639     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1640     static final int SERVICE_TIMEOUT_MSG = 12;
1641     static final int UPDATE_TIME_ZONE = 13;
1642     static final int SHOW_UID_ERROR_UI_MSG = 14;
1643     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1644     static final int PROC_START_TIMEOUT_MSG = 20;
1645     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1646     static final int KILL_APPLICATION_MSG = 22;
1647     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1648     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1649     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1650     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1651     static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1652     static final int CLEAR_DNS_CACHE_MSG = 28;
1653     static final int UPDATE_HTTP_PROXY_MSG = 29;
1654     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1655     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1656     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1657     static final int REPORT_MEM_USAGE_MSG = 33;
1658     static final int REPORT_USER_SWITCH_MSG = 34;
1659     static final int CONTINUE_USER_SWITCH_MSG = 35;
1660     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1661     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1662     static final int PERSIST_URI_GRANTS_MSG = 38;
1663     static final int REQUEST_ALL_PSS_MSG = 39;
1664     static final int START_PROFILES_MSG = 40;
1665     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1666     static final int SYSTEM_USER_START_MSG = 42;
1667     static final int SYSTEM_USER_CURRENT_MSG = 43;
1668     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1669     static final int FINISH_BOOTING_MSG = 45;
1670     static final int START_USER_SWITCH_UI_MSG = 46;
1671     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1672     static final int DISMISS_DIALOG_UI_MSG = 48;
1673     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1674     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1675     static final int DELETE_DUMPHEAP_MSG = 51;
1676     static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1677     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1678     static final int REPORT_TIME_TRACKER_MSG = 54;
1679     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1680     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1681     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1682     static final int IDLE_UIDS_MSG = 58;
1683     static final int SYSTEM_USER_UNLOCK_MSG = 59;
1684     static final int LOG_STACK_STATE = 60;
1685     static final int VR_MODE_CHANGE_MSG = 61;
1686     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1687     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1688     static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1689     static final int NOTIFY_VR_SLEEPING_MSG = 65;
1690     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1691     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1692     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1693     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1694     static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1695     static final int DISPATCH_SCREEN_AWAKE_MSG = 71;
1696     static final int DISPATCH_SCREEN_KEYGUARD_MSG = 72;
1697     static final int START_USER_SWITCH_FG_MSG = 712;
1698     static final int NOTIFY_VR_KEYGUARD_MSG = 74;
1699
1700     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1701     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1702     static final int FIRST_COMPAT_MODE_MSG = 300;
1703     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1704
1705     static ServiceThread sKillThread = null;
1706     static KillHandler sKillHandler = null;
1707
1708     CompatModeDialog mCompatModeDialog;
1709     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1710     long mLastMemUsageReportTime = 0;
1711
1712     /**
1713      * Flag whether the current user is a "monkey", i.e. whether
1714      * the UI is driven by a UI automation tool.
1715      */
1716     private boolean mUserIsMonkey;
1717
1718     /** Flag whether the device has a Recents UI */
1719     boolean mHasRecents;
1720
1721     /** The dimensions of the thumbnails in the Recents UI. */
1722     int mThumbnailWidth;
1723     int mThumbnailHeight;
1724     float mFullscreenThumbnailScale;
1725
1726     final ServiceThread mHandlerThread;
1727     final MainHandler mHandler;
1728     final Handler mUiHandler;
1729
1730     final ActivityManagerConstants mConstants;
1731
1732     PackageManagerInternal mPackageManagerInt;
1733
1734     // VoiceInteraction session ID that changes for each new request except when
1735     // being called for multiwindow assist in a single session.
1736     private int mViSessionId = 1000;
1737
1738     final boolean mPermissionReviewRequired;
1739
1740     private static String sTheRealBuildSerial = Build.UNKNOWN;
1741
1742     /**
1743      * Current global configuration information. Contains general settings for the entire system,
1744      * also corresponds to the merged configuration of the default display.
1745      */
1746     Configuration getGlobalConfiguration() {
1747         return mStackSupervisor.getConfiguration();
1748     }
1749
1750     final class KillHandler extends Handler {
1751         static final int KILL_PROCESS_GROUP_MSG = 4000;
1752
1753         public KillHandler(Looper looper) {
1754             super(looper, null, true);
1755         }
1756
1757         @Override
1758         public void handleMessage(Message msg) {
1759             switch (msg.what) {
1760                 case KILL_PROCESS_GROUP_MSG:
1761                 {
1762                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1763                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1764                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1765                 }
1766                 break;
1767
1768                 default:
1769                     super.handleMessage(msg);
1770             }
1771         }
1772     }
1773
1774     final class UiHandler extends Handler {
1775         public UiHandler() {
1776             super(com.android.server.UiThread.get().getLooper(), null, true);
1777         }
1778
1779         @Override
1780         public void handleMessage(Message msg) {
1781             switch (msg.what) {
1782             case SHOW_ERROR_UI_MSG: {
1783                 mAppErrors.handleShowAppErrorUi(msg);
1784                 ensureBootCompleted();
1785             } break;
1786             case SHOW_NOT_RESPONDING_UI_MSG: {
1787                 mAppErrors.handleShowAnrUi(msg);
1788                 ensureBootCompleted();
1789             } break;
1790             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1791                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1792                 synchronized (ActivityManagerService.this) {
1793                     ProcessRecord proc = (ProcessRecord) data.get("app");
1794                     if (proc == null) {
1795                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1796                         break;
1797                     }
1798                     if (proc.crashDialog != null) {
1799                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1800                         return;
1801                     }
1802                     AppErrorResult res = (AppErrorResult) data.get("result");
1803                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1804                         Dialog d = new StrictModeViolationDialog(mUiContext,
1805                                 ActivityManagerService.this, res, proc);
1806                         d.show();
1807                         proc.crashDialog = d;
1808                     } else {
1809                         // The device is asleep, so just pretend that the user
1810                         // saw a crash dialog and hit "force quit".
1811                         res.set(0);
1812                     }
1813                 }
1814                 ensureBootCompleted();
1815             } break;
1816             case SHOW_FACTORY_ERROR_UI_MSG: {
1817                 Dialog d = new FactoryErrorDialog(
1818                         mUiContext, msg.getData().getCharSequence("msg"));
1819                 d.show();
1820                 ensureBootCompleted();
1821             } break;
1822             case WAIT_FOR_DEBUGGER_UI_MSG: {
1823                 synchronized (ActivityManagerService.this) {
1824                     ProcessRecord app = (ProcessRecord)msg.obj;
1825                     if (msg.arg1 != 0) {
1826                         if (!app.waitedForDebugger) {
1827                             Dialog d = new AppWaitingForDebuggerDialog(
1828                                     ActivityManagerService.this,
1829                                     mUiContext, app);
1830                             app.waitDialog = d;
1831                             app.waitedForDebugger = true;
1832                             d.show();
1833                         }
1834                     } else {
1835                         if (app.waitDialog != null) {
1836                             app.waitDialog.dismiss();
1837                             app.waitDialog = null;
1838                         }
1839                     }
1840                 }
1841             } break;
1842             case SHOW_UID_ERROR_UI_MSG: {
1843                 if (mShowDialogs) {
1844                     AlertDialog d = new BaseErrorDialog(mUiContext);
1845                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1846                     d.setCancelable(false);
1847                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1848                     d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1849                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1850                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1851                     d.show();
1852                 }
1853             } break;
1854             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1855                 if (mShowDialogs) {
1856                     AlertDialog d = new BaseErrorDialog(mUiContext);
1857                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1858                     d.setCancelable(false);
1859                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1860                     d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1861                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1862                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1863                     d.show();
1864                 }
1865             } break;
1866             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1867                 synchronized (ActivityManagerService.this) {
1868                     ActivityRecord ar = (ActivityRecord) msg.obj;
1869                     if (mCompatModeDialog != null) {
1870                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1871                                 ar.info.applicationInfo.packageName)) {
1872                             return;
1873                         }
1874                         mCompatModeDialog.dismiss();
1875                         mCompatModeDialog = null;
1876                     }
1877                     if (ar != null && false) {
1878                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1879                                 ar.packageName)) {
1880                             int mode = mCompatModePackages.computeCompatModeLocked(
1881                                     ar.info.applicationInfo);
1882                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1883                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1884                                 mCompatModeDialog = new CompatModeDialog(
1885                                         ActivityManagerService.this, mUiContext,
1886                                         ar.info.applicationInfo);
1887                                 mCompatModeDialog.show();
1888                             }
1889                         }
1890                     }
1891                 }
1892                 break;
1893             }
1894             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1895                 synchronized (ActivityManagerService.this) {
1896                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1897                     if (mUnsupportedDisplaySizeDialog != null) {
1898                         mUnsupportedDisplaySizeDialog.dismiss();
1899                         mUnsupportedDisplaySizeDialog = null;
1900                     }
1901                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1902                             ar.packageName)) {
1903                         // TODO(multi-display): Show dialog on appropriate display.
1904                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1905                                 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1906                         mUnsupportedDisplaySizeDialog.show();
1907                     }
1908                 }
1909                 break;
1910             }
1911             case START_USER_SWITCH_UI_MSG: {
1912                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1913                 break;
1914             }
1915             case DISMISS_DIALOG_UI_MSG: {
1916                 final Dialog d = (Dialog) msg.obj;
1917                 d.dismiss();
1918                 break;
1919             }
1920             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1921                 dispatchProcessesChanged();
1922                 break;
1923             }
1924             case DISPATCH_PROCESS_DIED_UI_MSG: {
1925                 final int pid = msg.arg1;
1926                 final int uid = msg.arg2;
1927                 dispatchProcessDied(pid, uid);
1928                 break;
1929             }
1930             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1931                 dispatchUidsChanged();
1932             } break;
1933             case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1934                 dispatchOomAdjObserver((String)msg.obj);
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_POWER_USE_MSG: {
2126                 synchronized (ActivityManagerService.this) {
2127                     checkExcessivePowerUsageLocked();
2128                     removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2129                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2130                     sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
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 DISPATCH_SCREEN_AWAKE_MSG: {
2421                 final boolean isAwake = msg.arg1 != 0;
2422                 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2423                     mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2424                 }
2425             } break;
2426             case DISPATCH_SCREEN_KEYGUARD_MSG: {
2427                 final boolean isShowing = msg.arg1 != 0;
2428                 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2429                     mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2430                 }
2431             } break;
2432             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2433                 synchronized (ActivityManagerService.this) {
2434                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2435                         ProcessRecord r = mLruProcesses.get(i);
2436                         if (r.thread != null) {
2437                             try {
2438                                 r.thread.handleTrustStorageUpdate();
2439                             } catch (RemoteException ex) {
2440                                 Slog.w(TAG, "Failed to handle trust storage update for: " +
2441                                         r.info.processName);
2442                             }
2443                         }
2444                     }
2445                 }
2446             } break;
2447             }
2448         }
2449     };
2450
2451     static final int COLLECT_PSS_BG_MSG = 1;
2452
2453     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2454         @Override
2455         public void handleMessage(Message msg) {
2456             switch (msg.what) {
2457             case COLLECT_PSS_BG_MSG: {
2458                 long start = SystemClock.uptimeMillis();
2459                 MemInfoReader memInfo = null;
2460                 synchronized (ActivityManagerService.this) {
2461                     if (mFullPssPending) {
2462                         mFullPssPending = false;
2463                         memInfo = new MemInfoReader();
2464                     }
2465                 }
2466                 if (memInfo != null) {
2467                     updateCpuStatsNow();
2468                     long nativeTotalPss = 0;
2469                     final List<ProcessCpuTracker.Stats> stats;
2470                     synchronized (mProcessCpuTracker) {
2471                         stats = mProcessCpuTracker.getStats( (st)-> {
2472                             return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2473                         });
2474                     }
2475                     final int N = stats.size();
2476                     for (int j = 0; j < N; j++) {
2477                         synchronized (mPidsSelfLocked) {
2478                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2479                                 // This is one of our own processes; skip it.
2480                                 continue;
2481                             }
2482                         }
2483                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2484                     }
2485                     memInfo.readMemInfo();
2486                     synchronized (ActivityManagerService.this) {
2487                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2488                                 + (SystemClock.uptimeMillis()-start) + "ms");
2489                         final long cachedKb = memInfo.getCachedSizeKb();
2490                         final long freeKb = memInfo.getFreeSizeKb();
2491                         final long zramKb = memInfo.getZramTotalSizeKb();
2492                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2493                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2494                                 kernelKb*1024, nativeTotalPss*1024);
2495                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2496                                 nativeTotalPss);
2497                     }
2498                 }
2499
2500                 int num = 0;
2501                 long[] tmp = new long[2];
2502                 do {
2503                     ProcessRecord proc;
2504                     int procState;
2505                     int pid;
2506                     long lastPssTime;
2507                     synchronized (ActivityManagerService.this) {
2508                         if (mPendingPssProcesses.size() <= 0) {
2509                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2510                                     "Collected PSS of " + num + " processes in "
2511                                     + (SystemClock.uptimeMillis() - start) + "ms");
2512                             mPendingPssProcesses.clear();
2513                             return;
2514                         }
2515                         proc = mPendingPssProcesses.remove(0);
2516                         procState = proc.pssProcState;
2517                         lastPssTime = proc.lastPssTime;
2518                         if (proc.thread != null && procState == proc.setProcState
2519                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2520                                         < SystemClock.uptimeMillis()) {
2521                             pid = proc.pid;
2522                         } else {
2523                             proc = null;
2524                             pid = 0;
2525                         }
2526                     }
2527                     if (proc != null) {
2528                         long pss = Debug.getPss(pid, tmp, null);
2529                         synchronized (ActivityManagerService.this) {
2530                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2531                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2532                                 num++;
2533                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2534                                         SystemClock.uptimeMillis());
2535                             }
2536                         }
2537                     }
2538                 } while (true);
2539             }
2540             }
2541         }
2542     };
2543
2544     public void setSystemProcess() {
2545         try {
2546             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2547             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2548             ServiceManager.addService("meminfo", new MemBinder(this));
2549             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2550             ServiceManager.addService("dbinfo", new DbBinder(this));
2551             if (MONITOR_CPU_USAGE) {
2552                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2553             }
2554             ServiceManager.addService("permission", new PermissionController(this));
2555             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2556
2557             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2558                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2559             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2560
2561             synchronized (this) {
2562                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2563                 app.persistent = true;
2564                 app.pid = MY_PID;
2565                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2566                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2567                 synchronized (mPidsSelfLocked) {
2568                     mPidsSelfLocked.put(app.pid, app);
2569                 }
2570                 updateLruProcessLocked(app, false, null);
2571                 updateOomAdjLocked();
2572             }
2573         } catch (PackageManager.NameNotFoundException e) {
2574             throw new RuntimeException(
2575                     "Unable to find android system package", e);
2576         }
2577     }
2578
2579     public void setWindowManager(WindowManagerService wm) {
2580         mWindowManager = wm;
2581         mStackSupervisor.setWindowManager(wm);
2582         mActivityStarter.setWindowManager(wm);
2583     }
2584
2585     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2586         mUsageStatsService = usageStatsManager;
2587     }
2588
2589     public void startObservingNativeCrashes() {
2590         final NativeCrashListener ncl = new NativeCrashListener(this);
2591         ncl.start();
2592     }
2593
2594     public IAppOpsService getAppOpsService() {
2595         return mAppOpsService;
2596     }
2597
2598     static class MemBinder extends Binder {
2599         ActivityManagerService mActivityManagerService;
2600         MemBinder(ActivityManagerService activityManagerService) {
2601             mActivityManagerService = activityManagerService;
2602         }
2603
2604         @Override
2605         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2606             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2607                     "meminfo", pw)) return;
2608             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2609         }
2610     }
2611
2612     static class GraphicsBinder extends Binder {
2613         ActivityManagerService mActivityManagerService;
2614         GraphicsBinder(ActivityManagerService activityManagerService) {
2615             mActivityManagerService = activityManagerService;
2616         }
2617
2618         @Override
2619         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2620             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2621                     "gfxinfo", pw)) return;
2622             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2623         }
2624     }
2625
2626     static class DbBinder extends Binder {
2627         ActivityManagerService mActivityManagerService;
2628         DbBinder(ActivityManagerService activityManagerService) {
2629             mActivityManagerService = activityManagerService;
2630         }
2631
2632         @Override
2633         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2634             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2635                     "dbinfo", pw)) return;
2636             mActivityManagerService.dumpDbInfo(fd, pw, args);
2637         }
2638     }
2639
2640     static class CpuBinder extends Binder {
2641         ActivityManagerService mActivityManagerService;
2642         CpuBinder(ActivityManagerService activityManagerService) {
2643             mActivityManagerService = activityManagerService;
2644         }
2645
2646         @Override
2647         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2648             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2649                     "cpuinfo", pw)) return;
2650             synchronized (mActivityManagerService.mProcessCpuTracker) {
2651                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2652                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2653                         SystemClock.uptimeMillis()));
2654             }
2655         }
2656     }
2657
2658     public static final class Lifecycle extends SystemService {
2659         private final ActivityManagerService mService;
2660
2661         public Lifecycle(Context context) {
2662             super(context);
2663             mService = new ActivityManagerService(context);
2664         }
2665
2666         @Override
2667         public void onStart() {
2668             mService.start();
2669         }
2670
2671         @Override
2672         public void onCleanupUser(int userId) {
2673             mService.mBatteryStatsService.onCleanupUser(userId);
2674         }
2675
2676         public ActivityManagerService getService() {
2677             return mService;
2678         }
2679     }
2680
2681     @VisibleForTesting
2682     public ActivityManagerService(Injector injector) {
2683         mInjector = injector;
2684         mContext = mInjector.getContext();
2685         mUiContext = null;
2686         GL_ES_VERSION = 0;
2687         mActivityStarter = null;
2688         mAppErrors = null;
2689         mAppOpsService = mInjector.getAppOpsService(null, null);
2690         mBatteryStatsService = null;
2691         mCompatModePackages = null;
2692         mConstants = null;
2693         mGrantFile = null;
2694         mHandler = null;
2695         mHandlerThread = null;
2696         mIntentFirewall = null;
2697         mKeyguardController = null;
2698         mPermissionReviewRequired = false;
2699         mProcessCpuThread = null;
2700         mProcessStats = null;
2701         mProviderMap = null;
2702         mRecentTasks = null;
2703         mServices = null;
2704         mStackSupervisor = null;
2705         mSystemThread = null;
2706         mTaskChangeNotificationController = null;
2707         mUiHandler = injector.getUiHandler(null);
2708         mUserController = null;
2709         mVrController = null;
2710     }
2711
2712     // Note: This method is invoked on the main thread but may need to attach various
2713     // handlers to other threads.  So take care to be explicit about the looper.
2714     public ActivityManagerService(Context systemContext) {
2715         LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2716         mInjector = new Injector();
2717         mContext = systemContext;
2718
2719         mFactoryTest = FactoryTest.getMode();
2720         mSystemThread = ActivityThread.currentActivityThread();
2721         mUiContext = mSystemThread.getSystemUiContext();
2722
2723         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2724
2725         mPermissionReviewRequired = mContext.getResources().getBoolean(
2726                 com.android.internal.R.bool.config_permissionReviewRequired);
2727
2728         mHandlerThread = new ServiceThread(TAG,
2729                 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2730         mHandlerThread.start();
2731         mHandler = new MainHandler(mHandlerThread.getLooper());
2732         mUiHandler = mInjector.getUiHandler(this);
2733
2734         mConstants = new ActivityManagerConstants(this, mHandler);
2735
2736         /* static; one-time init here */
2737         if (sKillHandler == null) {
2738             sKillThread = new ServiceThread(TAG + ":kill",
2739                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2740             sKillThread.start();
2741             sKillHandler = new KillHandler(sKillThread.getLooper());
2742         }
2743
2744         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2745                 "foreground", BROADCAST_FG_TIMEOUT, false);
2746         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2747                 "background", BROADCAST_BG_TIMEOUT, true);
2748         mBroadcastQueues[0] = mFgBroadcastQueue;
2749         mBroadcastQueues[1] = mBgBroadcastQueue;
2750
2751         mServices = new ActiveServices(this);
2752         mProviderMap = new ProviderMap(this);
2753         mAppErrors = new AppErrors(mUiContext, this);
2754
2755         // TODO: Move creation of battery stats service outside of activity manager service.
2756         File dataDir = Environment.getDataDirectory();
2757         File systemDir = new File(dataDir, "system");
2758         systemDir.mkdirs();
2759         mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2760         mBatteryStatsService.getActiveStatistics().readLocked();
2761         mBatteryStatsService.scheduleWriteToDisk();
2762         mOnBattery = DEBUG_POWER ? true
2763                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2764         mBatteryStatsService.getActiveStatistics().setCallback(this);
2765
2766         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2767
2768         mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2769         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2770                 new IAppOpsCallback.Stub() {
2771                     @Override public void opChanged(int op, int uid, String packageName) {
2772                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2773                             if (mAppOpsService.checkOperation(op, uid, packageName)
2774                                     != AppOpsManager.MODE_ALLOWED) {
2775                                 runInBackgroundDisabled(uid);
2776                             }
2777                         }
2778                     }
2779                 });
2780
2781         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2782
2783         mUserController = new UserController(this);
2784
2785         mVrController = new VrController(this);
2786
2787         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2788             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2789
2790         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2791             mUseFifoUiScheduling = true;
2792         }
2793
2794         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2795         mTempConfig.setToDefaults();
2796         mTempConfig.setLocales(LocaleList.getDefault());
2797         mConfigurationSeq = mTempConfig.seq = 1;
2798         mStackSupervisor = createStackSupervisor();
2799         mStackSupervisor.onConfigurationChanged(mTempConfig);
2800         mKeyguardController = mStackSupervisor.mKeyguardController;
2801         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2802         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2803         mTaskChangeNotificationController =
2804                 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2805         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2806         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2807
2808         mProcessCpuThread = new Thread("CpuTracker") {
2809             @Override
2810             public void run() {
2811                 synchronized (mProcessCpuTracker) {
2812                     mProcessCpuInitLatch.countDown();
2813                     mProcessCpuTracker.init();
2814                 }
2815                 while (true) {
2816                     try {
2817                         try {
2818                             synchronized(this) {
2819                                 final long now = SystemClock.uptimeMillis();
2820                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2821                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2822                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2823                                 //        + ", write delay=" + nextWriteDelay);
2824                                 if (nextWriteDelay < nextCpuDelay) {
2825                                     nextCpuDelay = nextWriteDelay;
2826                                 }
2827                                 if (nextCpuDelay > 0) {
2828                                     mProcessCpuMutexFree.set(true);
2829                                     this.wait(nextCpuDelay);
2830                                 }
2831                             }
2832                         } catch (InterruptedException e) {
2833                         }
2834                         updateCpuStatsNow();
2835                     } catch (Exception e) {
2836                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2837                     }
2838                 }
2839             }
2840         };
2841
2842         Watchdog.getInstance().addMonitor(this);
2843         Watchdog.getInstance().addThread(mHandler);
2844     }
2845
2846     protected ActivityStackSupervisor createStackSupervisor() {
2847         return new ActivityStackSupervisor(this, mHandler.getLooper());
2848     }
2849
2850     public void setSystemServiceManager(SystemServiceManager mgr) {
2851         mSystemServiceManager = mgr;
2852     }
2853
2854     public void setInstaller(Installer installer) {
2855         mInstaller = installer;
2856     }
2857
2858     private void start() {
2859         removeAllProcessGroups();
2860         mProcessCpuThread.start();
2861
2862         mBatteryStatsService.publish();
2863         mAppOpsService.publish(mContext);
2864         Slog.d("AppOps", "AppOpsService published");
2865         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2866         // Wait for the synchronized block started in mProcessCpuThread,
2867         // so that any other acccess to mProcessCpuTracker from main thread
2868         // will be blocked during mProcessCpuTracker initialization.
2869         try {
2870             mProcessCpuInitLatch.await();
2871         } catch (InterruptedException e) {
2872             Slog.wtf(TAG, "Interrupted wait during start", e);
2873             Thread.currentThread().interrupt();
2874             throw new IllegalStateException("Interrupted wait during start");
2875         }
2876     }
2877
2878     void onUserStoppedLocked(int userId) {
2879         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2880     }
2881
2882     public void initPowerManagement() {
2883         mStackSupervisor.initPowerManagement();
2884         mBatteryStatsService.initPowerManagement();
2885         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2886         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2887         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2888         mVoiceWakeLock.setReferenceCounted(false);
2889     }
2890
2891     private ArraySet<String> getBackgroundLaunchBroadcasts() {
2892         if (mBackgroundLaunchBroadcasts == null) {
2893             mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2894         }
2895         return mBackgroundLaunchBroadcasts;
2896     }
2897
2898     @Override
2899     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2900             throws RemoteException {
2901         if (code == SYSPROPS_TRANSACTION) {
2902             // We need to tell all apps about the system property change.
2903             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2904             synchronized(this) {
2905                 final int NP = mProcessNames.getMap().size();
2906                 for (int ip=0; ip<NP; ip++) {
2907                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2908                     final int NA = apps.size();
2909                     for (int ia=0; ia<NA; ia++) {
2910                         ProcessRecord app = apps.valueAt(ia);
2911                         if (app.thread != null) {
2912                             procs.add(app.thread.asBinder());
2913                         }
2914                     }
2915                 }
2916             }
2917
2918             int N = procs.size();
2919             for (int i=0; i<N; i++) {
2920                 Parcel data2 = Parcel.obtain();
2921                 try {
2922                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2923                             Binder.FLAG_ONEWAY);
2924                 } catch (RemoteException e) {
2925                 }
2926                 data2.recycle();
2927             }
2928         }
2929         try {
2930             return super.onTransact(code, data, reply, flags);
2931         } catch (RuntimeException e) {
2932             // The activity manager only throws security exceptions, so let's
2933             // log all others.
2934             if (!(e instanceof SecurityException)) {
2935                 Slog.wtf(TAG, "Activity Manager Crash."
2936                         + " UID:" + Binder.getCallingUid()
2937                         + " PID:" + Binder.getCallingPid()
2938                         + " TRANS:" + code, e);
2939             }
2940             throw e;
2941         }
2942     }
2943
2944     void updateCpuStats() {
2945         final long now = SystemClock.uptimeMillis();
2946         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2947             return;
2948         }
2949         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2950             synchronized (mProcessCpuThread) {
2951                 mProcessCpuThread.notify();
2952             }
2953         }
2954     }
2955
2956     void updateCpuStatsNow() {
2957         synchronized (mProcessCpuTracker) {
2958             mProcessCpuMutexFree.set(false);
2959             final long now = SystemClock.uptimeMillis();
2960             boolean haveNewCpuStats = false;
2961
2962             if (MONITOR_CPU_USAGE &&
2963                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2964                 mLastCpuTime.set(now);
2965                 mProcessCpuTracker.update();
2966                 if (mProcessCpuTracker.hasGoodLastStats()) {
2967                     haveNewCpuStats = true;
2968                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2969                     //Slog.i(TAG, "Total CPU usage: "
2970                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2971
2972                     // Slog the cpu usage if the property is set.
2973                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2974                         int user = mProcessCpuTracker.getLastUserTime();
2975                         int system = mProcessCpuTracker.getLastSystemTime();
2976                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2977                         int irq = mProcessCpuTracker.getLastIrqTime();
2978                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2979                         int idle = mProcessCpuTracker.getLastIdleTime();
2980
2981                         int total = user + system + iowait + irq + softIrq + idle;
2982                         if (total == 0) total = 1;
2983
2984                         EventLog.writeEvent(EventLogTags.CPU,
2985                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2986                                 (user * 100) / total,
2987                                 (system * 100) / total,
2988                                 (iowait * 100) / total,
2989                                 (irq * 100) / total,
2990                                 (softIrq * 100) / total);
2991                     }
2992                 }
2993             }
2994
2995             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2996             synchronized(bstats) {
2997                 synchronized(mPidsSelfLocked) {
2998                     if (haveNewCpuStats) {
2999                         if (bstats.startAddingCpuLocked()) {
3000                             int totalUTime = 0;
3001                             int totalSTime = 0;
3002                             final int N = mProcessCpuTracker.countStats();
3003                             for (int i=0; i<N; i++) {
3004                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3005                                 if (!st.working) {
3006                                     continue;
3007                                 }
3008                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3009                                 totalUTime += st.rel_utime;
3010                                 totalSTime += st.rel_stime;
3011                                 if (pr != null) {
3012                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3013                                     if (ps == null || !ps.isActive()) {
3014                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3015                                                 pr.info.uid, pr.processName);
3016                                     }
3017                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3018                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
3019                                     if (pr.lastCpuTime == 0) {
3020                                         pr.lastCpuTime = pr.curCpuTime;
3021                                     }
3022                                 } else {
3023                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3024                                     if (ps == null || !ps.isActive()) {
3025                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
3026                                                 bstats.mapUid(st.uid), st.name);
3027                                     }
3028                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3029                                 }
3030                             }
3031                             final int userTime = mProcessCpuTracker.getLastUserTime();
3032                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
3033                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3034                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
3035                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3036                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
3037                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3038                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3039                         }
3040                     }
3041                 }
3042
3043                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3044                     mLastWriteTime = now;
3045                     mBatteryStatsService.scheduleWriteToDisk();
3046                 }
3047             }
3048         }
3049     }
3050
3051     @Override
3052     public void batteryNeedsCpuUpdate() {
3053         updateCpuStatsNow();
3054     }
3055
3056     @Override
3057     public void batteryPowerChanged(boolean onBattery) {
3058         // When plugging in, update the CPU stats first before changing
3059         // the plug state.
3060         updateCpuStatsNow();
3061         synchronized (this) {
3062             synchronized(mPidsSelfLocked) {
3063                 mOnBattery = DEBUG_POWER ? true : onBattery;
3064             }
3065         }
3066     }
3067
3068     @Override
3069     public void batterySendBroadcast(Intent intent) {
3070         synchronized (this) {
3071             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3072                     AppOpsManager.OP_NONE, null, false, false,
3073                     -1, SYSTEM_UID, UserHandle.USER_ALL);
3074         }
3075     }
3076
3077     /**
3078      * Initialize the application bind args. These are passed to each
3079      * process when the bindApplication() IPC is sent to the process. They're
3080      * lazily setup to make sure the services are running when they're asked for.
3081      */
3082     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3083         // Isolated processes won't get this optimization, so that we don't
3084         // violate the rules about which services they have access to.
3085         if (isolated) {
3086             if (mIsolatedAppBindArgs == null) {
3087                 mIsolatedAppBindArgs = new HashMap<>();
3088                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3089             }
3090             return mIsolatedAppBindArgs;
3091         }
3092
3093         if (mAppBindArgs == null) {
3094             mAppBindArgs = new HashMap<>();
3095
3096             // Setup the application init args
3097             mAppBindArgs.put("package", ServiceManager.getService("package"));
3098             mAppBindArgs.put("window", ServiceManager.getService("window"));
3099             mAppBindArgs.put(Context.ALARM_SERVICE,
3100                     ServiceManager.getService(Context.ALARM_SERVICE));
3101         }
3102         return mAppBindArgs;
3103     }
3104
3105     /**
3106      * Update AMS states when an activity is resumed. This should only be called by
3107      * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3108      */
3109     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3110         final TaskRecord task = r.getTask();
3111         if (task.isApplicationTask()) {
3112             if (mCurAppTimeTracker != r.appTimeTracker) {
3113                 // We are switching app tracking.  Complete the current one.
3114                 if (mCurAppTimeTracker != null) {
3115                     mCurAppTimeTracker.stop();
3116                     mHandler.obtainMessage(
3117                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3118                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3119                     mCurAppTimeTracker = null;
3120                 }
3121                 if (r.appTimeTracker != null) {
3122                     mCurAppTimeTracker = r.appTimeTracker;
3123                     startTimeTrackingFocusedActivityLocked();
3124                 }
3125             } else {
3126                 startTimeTrackingFocusedActivityLocked();
3127             }
3128         } else {
3129             r.appTimeTracker = null;
3130         }
3131         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3132         // TODO: Probably not, because we don't want to resume voice on switching
3133         // back to this activity
3134         if (task.voiceInteractor != null) {
3135             startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3136         } else {
3137             finishRunningVoiceLocked();
3138
3139             if (mLastResumedActivity != null) {
3140                 final IVoiceInteractionSession session;
3141
3142                 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3143                 if (lastResumedActivityTask != null
3144                         && lastResumedActivityTask.voiceSession != null) {
3145                     session = lastResumedActivityTask.voiceSession;
3146                 } else {
3147                     session = mLastResumedActivity.voiceSession;
3148                 }
3149
3150                 if (session != null) {
3151                     // We had been in a voice interaction session, but now focused has
3152                     // move to something different.  Just finish the session, we can't
3153                     // return to it and retain the proper state and synchronization with
3154                     // the voice interaction service.
3155                     finishVoiceTask(session);
3156                 }
3157             }
3158         }
3159
3160         if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3161             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3162             mHandler.obtainMessage(
3163                     FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3164         }
3165         mLastResumedActivity = r;
3166
3167         mWindowManager.setFocusedApp(r.appToken, true);
3168
3169         applyUpdateLockStateLocked(r);
3170         applyUpdateVrModeLocked(r);
3171
3172         EventLogTags.writeAmSetResumedActivity(
3173                 r == null ? -1 : r.userId,
3174                 r == null ? "NULL" : r.shortComponentName,
3175                 reason);
3176     }
3177
3178     @Override
3179     public void setFocusedStack(int stackId) {
3180         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3181         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3182         final long callingId = Binder.clearCallingIdentity();
3183         try {
3184             synchronized (this) {
3185                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3186                 if (stack == null) {
3187                     return;
3188                 }
3189                 final ActivityRecord r = stack.topRunningActivityLocked();
3190                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3191                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3192                 }
3193             }
3194         } finally {
3195             Binder.restoreCallingIdentity(callingId);
3196         }
3197     }
3198
3199     @Override
3200     public void setFocusedTask(int taskId) {
3201         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3202         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3203         final long callingId = Binder.clearCallingIdentity();
3204         try {
3205             synchronized (this) {
3206                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3207                 if (task == null) {
3208                     return;
3209                 }
3210                 final ActivityRecord r = task.topRunningActivityLocked();
3211                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3212                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3213                 }
3214             }
3215         } finally {
3216             Binder.restoreCallingIdentity(callingId);
3217         }
3218     }
3219
3220     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3221     @Override
3222     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3223         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3224         mTaskChangeNotificationController.registerTaskStackListener(listener);
3225     }
3226
3227     /**
3228      * Unregister a task stack listener so that it stops receiving callbacks.
3229      */
3230     @Override
3231     public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3232          enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3233          mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3234      }
3235
3236     @Override
3237     public void notifyActivityDrawn(IBinder token) {
3238         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3239         synchronized (this) {
3240             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3241             if (r != null) {
3242                 r.getStack().notifyActivityDrawnLocked(r);
3243             }
3244         }
3245     }
3246
3247     final void applyUpdateLockStateLocked(ActivityRecord r) {
3248         // Modifications to the UpdateLock state are done on our handler, outside
3249         // the activity manager's locks.  The new state is determined based on the
3250         // state *now* of the relevant activity record.  The object is passed to
3251         // the handler solely for logging detail, not to be consulted/modified.
3252         final boolean nextState = r != null && r.immersive;
3253         mHandler.sendMessage(
3254                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3255     }
3256
3257     final void applyUpdateVrModeLocked(ActivityRecord r) {
3258         // VR apps are expected to run in a main display. If an app is turning on VR for
3259         // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3260         // fullscreen stack before enabling VR Mode.
3261         // TODO: The goal of this code is to keep the VR app on the main display. When the
3262         // stack implementation changes in the future, keep in mind that the use of the fullscreen
3263         // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3264         // option would be a better choice here.
3265         if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3266             Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3267                     + " to main stack for VR");
3268             moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3269         }
3270         mHandler.sendMessage(
3271                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3272     }
3273
3274     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3275         Message msg = Message.obtain();
3276         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3277         msg.obj = r.getTask().askedCompatMode ? null : r;
3278         mUiHandler.sendMessage(msg);
3279     }
3280
3281     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3282         final Configuration globalConfig = getGlobalConfiguration();
3283         if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3284                 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3285             final Message msg = Message.obtain();
3286             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3287             msg.obj = r;
3288             mUiHandler.sendMessage(msg);
3289         }
3290     }
3291
3292     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3293             String what, Object obj, ProcessRecord srcApp) {
3294         app.lastActivityTime = now;
3295
3296         if (app.activities.size() > 0) {
3297             // Don't want to touch dependent processes that are hosting activities.
3298             return index;
3299         }
3300
3301         int lrui = mLruProcesses.lastIndexOf(app);
3302         if (lrui < 0) {
3303             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3304                     + what + " " + obj + " from " + srcApp);
3305             return index;
3306         }
3307
3308         if (lrui >= index) {
3309             // Don't want to cause this to move dependent processes *back* in the
3310             // list as if they were less frequently used.
3311             return index;
3312         }
3313
3314         if (lrui >= mLruProcessActivityStart) {
3315             // Don't want to touch dependent processes that are hosting activities.
3316             return index;
3317         }
3318
3319         mLruProcesses.remove(lrui);
3320         if (index > 0) {
3321             index--;
3322         }
3323         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3324                 + " in LRU list: " + app);
3325         mLruProcesses.add(index, app);
3326         return index;
3327     }
3328
3329     static void killProcessGroup(int uid, int pid) {
3330         if (sKillHandler != null) {
3331             sKillHandler.sendMessage(
3332                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3333         } else {
3334             Slog.w(TAG, "Asked to kill process group before system bringup!");
3335             Process.killProcessGroup(uid, pid);
3336         }
3337     }
3338
3339     final void removeLruProcessLocked(ProcessRecord app) {
3340         int lrui = mLruProcesses.lastIndexOf(app);
3341         if (lrui >= 0) {
3342             if (!app.killed) {
3343                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3344                 killProcessQuiet(app.pid);
3345                 killProcessGroup(app.uid, app.pid);
3346             }
3347             if (lrui <= mLruProcessActivityStart) {
3348                 mLruProcessActivityStart--;
3349             }
3350             if (lrui <= mLruProcessServiceStart) {
3351                 mLruProcessServiceStart--;
3352             }
3353             mLruProcesses.remove(lrui);
3354         }
3355     }
3356
3357     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3358             ProcessRecord client) {
3359         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3360                 || app.treatLikeActivity;
3361         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3362         if (!activityChange && hasActivity) {
3363             // The process has activities, so we are only allowing activity-based adjustments
3364             // to move it.  It should be kept in the front of the list with other
3365             // processes that have activities, and we don't want those to change their
3366             // order except due to activity operations.
3367             return;
3368         }
3369
3370         mLruSeq++;
3371         final long now = SystemClock.uptimeMillis();
3372         app.lastActivityTime = now;
3373
3374         // First a quick reject: if the app is already at the position we will
3375         // put it, then there is nothing to do.
3376         if (hasActivity) {
3377             final int N = mLruProcesses.size();
3378             if (N > 0 && mLruProcesses.get(N-1) == app) {
3379                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3380                 return;
3381             }
3382         } else {
3383             if (mLruProcessServiceStart > 0
3384                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3385                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3386                 return;
3387             }
3388         }
3389
3390         int lrui = mLruProcesses.lastIndexOf(app);
3391
3392         if (app.persistent && lrui >= 0) {
3393             // We don't care about the position of persistent processes, as long as
3394             // they are in the list.
3395             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3396             return;
3397         }
3398
3399         /* In progress: compute new position first, so we can avoid doing work
3400            if the process is not actually going to move.  Not yet working.
3401         int addIndex;
3402         int nextIndex;
3403         boolean inActivity = false, inService = false;
3404         if (hasActivity) {
3405             // Process has activities, put it at the very tipsy-top.
3406             addIndex = mLruProcesses.size();
3407             nextIndex = mLruProcessServiceStart;
3408             inActivity = true;
3409         } else if (hasService) {
3410             // Process has services, put it at the top of the service list.
3411             addIndex = mLruProcessActivityStart;
3412             nextIndex = mLruProcessServiceStart;
3413             inActivity = true;
3414             inService = true;
3415         } else  {
3416             // Process not otherwise of interest, it goes to the top of the non-service area.
3417             addIndex = mLruProcessServiceStart;
3418             if (client != null) {
3419                 int clientIndex = mLruProcesses.lastIndexOf(client);
3420                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3421                         + app);
3422                 if (clientIndex >= 0 && addIndex > clientIndex) {
3423                     addIndex = clientIndex;
3424                 }
3425             }
3426             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3427         }
3428
3429         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3430                 + mLruProcessActivityStart + "): " + app);
3431         */
3432
3433         if (lrui >= 0) {
3434             if (lrui < mLruProcessActivityStart) {
3435                 mLruProcessActivityStart--;
3436             }
3437             if (lrui < mLruProcessServiceStart) {
3438                 mLruProcessServiceStart--;
3439             }
3440             /*
3441             if (addIndex > lrui) {
3442                 addIndex--;
3443             }
3444             if (nextIndex > lrui) {
3445                 nextIndex--;
3446             }
3447             */
3448             mLruProcesses.remove(lrui);
3449         }
3450
3451         /*
3452         mLruProcesses.add(addIndex, app);
3453         if (inActivity) {
3454             mLruProcessActivityStart++;
3455         }
3456         if (inService) {
3457             mLruProcessActivityStart++;
3458         }
3459         */
3460
3461         int nextIndex;
3462         if (hasActivity) {
3463             final int N = mLruProcesses.size();
3464             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3465                 // Process doesn't have activities, but has clients with
3466                 // activities...  move it up, but one below the top (the top
3467                 // should always have a real activity).
3468                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3469                         "Adding to second-top of LRU activity list: " + app);
3470                 mLruProcesses.add(N - 1, app);
3471                 // To keep it from spamming the LRU list (by making a bunch of clients),
3472                 // we will push down any other entries owned by the app.
3473                 final int uid = app.info.uid;
3474                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3475                     ProcessRecord subProc = mLruProcesses.get(i);
3476                     if (subProc.info.uid == uid) {
3477                         // We want to push this one down the list.  If the process after
3478                         // it is for the same uid, however, don't do so, because we don't
3479                         // want them internally to be re-ordered.
3480                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3481                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3482                                     "Pushing uid " + uid + " swapping at " + i + ": "
3483                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3484                             ProcessRecord tmp = mLruProcesses.get(i);
3485                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3486                             mLruProcesses.set(i - 1, tmp);
3487                             i--;
3488                         }
3489                     } else {
3490                         // A gap, we can stop here.
3491                         break;
3492                     }
3493                 }
3494             } else {
3495                 // Process has activities, put it at the very tipsy-top.
3496                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3497                 mLruProcesses.add(app);
3498             }
3499             nextIndex = mLruProcessServiceStart;
3500         } else if (hasService) {
3501             // Process has services, put it at the top of the service list.
3502             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3503             mLruProcesses.add(mLruProcessActivityStart, app);
3504             nextIndex = mLruProcessServiceStart;
3505             mLruProcessActivityStart++;
3506         } else  {
3507             // Process not otherwise of interest, it goes to the top of the non-service area.
3508             int index = mLruProcessServiceStart;
3509             if (client != null) {
3510                 // If there is a client, don't allow the process to be moved up higher
3511                 // in the list than that client.
3512                 int clientIndex = mLruProcesses.lastIndexOf(client);
3513                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3514                         + " when updating " + app);
3515                 if (clientIndex <= lrui) {
3516                     // Don't allow the client index restriction to push it down farther in the
3517                     // list than it already is.
3518                     clientIndex = lrui;
3519                 }
3520                 if (clientIndex >= 0 && index > clientIndex) {
3521                     index = clientIndex;
3522                 }
3523             }
3524             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3525             mLruProcesses.add(index, app);
3526             nextIndex = index-1;
3527             mLruProcessActivityStart++;
3528             mLruProcessServiceStart++;
3529         }
3530
3531         // If the app is currently using a content provider or service,
3532         // bump those processes as well.
3533         for (int j=app.connections.size()-1; j>=0; j--) {
3534             ConnectionRecord cr = app.connections.valueAt(j);
3535             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3536                     && cr.binding.service.app != null
3537                     && cr.binding.service.app.lruSeq != mLruSeq
3538                     && !cr.binding.service.app.persistent) {
3539                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3540                         "service connection", cr, app);
3541             }
3542         }
3543         for (int j=app.conProviders.size()-1; j>=0; j--) {
3544             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3545             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3546                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3547                         "provider reference", cpr, app);
3548             }
3549         }
3550     }
3551
3552     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3553         if (uid == SYSTEM_UID) {
3554             // The system gets to run in any process.  If there are multiple
3555             // processes with the same uid, just pick the first (this
3556             // should never happen).
3557             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3558             if (procs == null) return null;
3559             final int procCount = procs.size();
3560             for (int i = 0; i < procCount; i++) {
3561                 final int procUid = procs.keyAt(i);
3562                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3563                     // Don't use an app process or different user process for system component.
3564                     continue;
3565                 }
3566                 return procs.valueAt(i);
3567             }
3568         }
3569         ProcessRecord proc = mProcessNames.get(processName, uid);
3570         if (false && proc != null && !keepIfLarge
3571                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3572                 && proc.lastCachedPss >= 4000) {
3573             // Turn this condition on to cause killing to happen regularly, for testing.
3574             if (proc.baseProcessTracker != null) {
3575                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3576             }
3577             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3578         } else if (proc != null && !keepIfLarge
3579                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3580                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3581             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3582             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3583                 if (proc.baseProcessTracker != null) {
3584                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3585                 }
3586                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3587             }
3588         }
3589         return proc;
3590     }
3591
3592     void notifyPackageUse(String packageName, int reason) {
3593         synchronized(this) {
3594             getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3595         }
3596     }
3597
3598     boolean isNextTransitionForward() {
3599         int transit = mWindowManager.getPendingAppTransition();
3600         return transit == TRANSIT_ACTIVITY_OPEN
3601                 || transit == TRANSIT_TASK_OPEN
3602                 || transit == TRANSIT_TASK_TO_FRONT;
3603     }
3604
3605     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3606             String processName, String abiOverride, int uid, Runnable crashHandler) {
3607         synchronized(this) {
3608             ApplicationInfo info = new ApplicationInfo();
3609             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3610             // For isolated processes, the former contains the parent's uid and the latter the
3611             // actual uid of the isolated process.
3612             // In the special case introduced by this method (which is, starting an isolated
3613             // process directly from the SystemServer without an actual parent app process) the
3614             // closest thing to a parent's uid is SYSTEM_UID.
3615             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3616             // the |isolated| logic in the ProcessRecord constructor.
3617             info.uid = SYSTEM_UID;
3618             info.processName = processName;
3619             info.className = entryPoint;
3620             info.packageName = "android";
3621             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3622             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3623                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3624                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3625                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3626                     crashHandler);
3627             return proc != null ? proc.pid : 0;
3628         }
3629     }
3630
3631     final ProcessRecord startProcessLocked(String processName,
3632             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3633             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3634             boolean isolated, boolean keepIfLarge) {
3635         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3636                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3637                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3638                 null /* crashHandler */);
3639     }
3640
3641     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3642             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3643             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3644             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3645         long startTime = SystemClock.elapsedRealtime();
3646         ProcessRecord app;
3647         if (!isolated) {
3648             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3649             checkTime(startTime, "startProcess: after getProcessRecord");
3650
3651             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3652                 // If we are in the background, then check to see if this process
3653                 // is bad.  If so, we will just silently fail.
3654                 if (mAppErrors.isBadProcessLocked(info)) {
3655                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3656                             + "/" + info.processName);
3657                     return null;
3658                 }
3659             } else {
3660                 // When the user is explicitly starting a process, then clear its
3661                 // crash count so that we won't make it bad until they see at
3662                 // least one crash dialog again, and make the process good again
3663                 // if it had been bad.
3664                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3665                         + "/" + info.processName);
3666                 mAppErrors.resetProcessCrashTimeLocked(info);
3667                 if (mAppErrors.isBadProcessLocked(info)) {
3668                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3669                             UserHandle.getUserId(info.uid), info.uid,
3670                             info.processName);
3671                     mAppErrors.clearBadProcessLocked(info);
3672                     if (app != null) {
3673                         app.bad = false;
3674                     }
3675                 }
3676             }
3677         } else {
3678             // If this is an isolated process, it can't re-use an existing process.
3679             app = null;
3680         }
3681
3682         // We don't have to do anything more if:
3683         // (1) There is an existing application record; and
3684         // (2) The caller doesn't think it is dead, OR there is no thread
3685         //     object attached to it so we know it couldn't have crashed; and
3686         // (3) There is a pid assigned to it, so it is either starting or
3687         //     already running.
3688         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3689                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3690                 + " thread=" + (app != null ? app.thread : null)
3691                 + " pid=" + (app != null ? app.pid : -1));
3692         if (app != null && app.pid > 0) {
3693             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3694                 // We already have the app running, or are waiting for it to
3695                 // come up (we have a pid but not yet its thread), so keep it.
3696                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3697                 // If this is a new package in the process, add the package to the list
3698                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3699                 checkTime(startTime, "startProcess: done, added package to proc");
3700                 return app;
3701             }
3702
3703             // An application record is attached to a previous process,
3704             // clean it up now.
3705             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3706             checkTime(startTime, "startProcess: bad proc running, killing");
3707             killProcessGroup(app.uid, app.pid);
3708             handleAppDiedLocked(app, true, true);
3709             checkTime(startTime, "startProcess: done killing old proc");
3710         }
3711
3712         String hostingNameStr = hostingName != null
3713                 ? hostingName.flattenToShortString() : null;
3714
3715         if (app == null) {
3716             checkTime(startTime, "startProcess: creating new process record");
3717             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3718             if (app == null) {
3719                 Slog.w(TAG, "Failed making new process record for "
3720                         + processName + "/" + info.uid + " isolated=" + isolated);
3721                 return null;
3722             }
3723             app.crashHandler = crashHandler;
3724             checkTime(startTime, "startProcess: done creating new process record");
3725         } else {
3726             // If this is a new package in the process, add the package to the list
3727             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3728             checkTime(startTime, "startProcess: added package to existing proc");
3729         }
3730
3731         // If the system is not ready yet, then hold off on starting this
3732         // process until it is.
3733         if (!mProcessesReady
3734                 && !isAllowedWhileBooting(info)
3735                 && !allowWhileBooting) {
3736             if (!mProcessesOnHold.contains(app)) {
3737                 mProcessesOnHold.add(app);
3738             }
3739             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3740                     "System not ready, putting on hold: " + app);
3741             checkTime(startTime, "startProcess: returning with proc on hold");
3742             return app;
3743         }
3744
3745         checkTime(startTime, "startProcess: stepping in to startProcess");
3746         startProcessLocked(
3747                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3748         checkTime(startTime, "startProcess: done starting proc!");
3749         return (app.pid != 0) ? app : null;
3750     }
3751
3752     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3753         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3754     }
3755
3756     private final void startProcessLocked(ProcessRecord app,
3757             String hostingType, String hostingNameStr) {
3758         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3759                 null /* entryPoint */, null /* entryPointArgs */);
3760     }
3761
3762     private final void startProcessLocked(ProcessRecord app, String hostingType,
3763             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3764         long startTime = SystemClock.elapsedRealtime();
3765         if (app.pid > 0 && app.pid != MY_PID) {
3766             checkTime(startTime, "startProcess: removing from pids map");
3767             synchronized (mPidsSelfLocked) {
3768                 mPidsSelfLocked.remove(app.pid);
3769                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3770             }
3771             checkTime(startTime, "startProcess: done removing from pids map");
3772             app.setPid(0);
3773         }
3774
3775         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3776                 "startProcessLocked removing on hold: " + app);
3777         mProcessesOnHold.remove(app);
3778
3779         checkTime(startTime, "startProcess: starting to update cpu stats");
3780         updateCpuStats();
3781         checkTime(startTime, "startProcess: done updating cpu stats");
3782
3783         try {
3784             try {
3785                 final int userId = UserHandle.getUserId(app.uid);
3786                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3787             } catch (RemoteException e) {
3788                 throw e.rethrowAsRuntimeException();
3789             }
3790
3791             int uid = app.uid;
3792             int[] gids = null;
3793             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3794             if (!app.isolated) {
3795                 int[] permGids = null;
3796                 try {
3797                     checkTime(startTime, "startProcess: getting gids from package manager");
3798                     final IPackageManager pm = AppGlobals.getPackageManager();
3799                     permGids = pm.getPackageGids(app.info.packageName,
3800                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3801                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
3802                             StorageManagerInternal.class);
3803                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3804                             app.info.packageName);
3805                 } catch (RemoteException e) {
3806                     throw e.rethrowAsRuntimeException();
3807                 }
3808
3809                 /*
3810                  * Add shared application and profile GIDs so applications can share some
3811                  * resources like shared libraries and access user-wide resources
3812                  */
3813                 if (ArrayUtils.isEmpty(permGids)) {
3814                     gids = new int[3];
3815                 } else {
3816                     gids = new int[permGids.length + 3];
3817                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
3818                 }
3819                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3820                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3821                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3822
3823                 // Replace any invalid GIDs
3824                 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
3825                 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
3826             }
3827             checkTime(startTime, "startProcess: building args");
3828             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3829                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3830                         && mTopComponent != null
3831                         && app.processName.equals(mTopComponent.getPackageName())) {
3832                     uid = 0;
3833                 }
3834                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3835                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3836                     uid = 0;
3837                 }
3838             }
3839             int runtimeFlags = 0;
3840             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3841                 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
3842                 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3843                 // Also turn on CheckJNI for debuggable apps. It's quite
3844                 // awkward to turn on otherwise.
3845                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3846             }
3847             // Run the app in safe mode if its manifest requests so or the
3848             // system is booted in safe mode.
3849             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3850                 mSafeMode == true) {
3851                 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3852             }
3853             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3854                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3855             }
3856             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3857             if ("true".equals(genDebugInfoProperty)) {
3858                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3859             }
3860             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3861                 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3862             }
3863             if ("1".equals(SystemProperties.get("debug.assert"))) {
3864                 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3865             }
3866             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3867                 // Enable all debug flags required by the native debugger.
3868                 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3869                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3870                 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3871                 mNativeDebuggingApp = null;
3872             }
3873
3874             if (app.info.isPrivilegedApp() &&
3875                     !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
3876                 runtimeFlags |= Zygote.DISABLE_VERIFIER;
3877                 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
3878             }
3879
3880             String invokeWith = null;
3881             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3882                 // Debuggable apps may include a wrapper script with their library directory.
3883                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3884                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3885                 try {
3886                     if (new File(wrapperFileName).exists()) {
3887                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3888                     }
3889                 } finally {
3890                     StrictMode.setThreadPolicy(oldPolicy);
3891                 }
3892             }
3893
3894             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3895             if (requiredAbi == null) {
3896                 requiredAbi = Build.SUPPORTED_ABIS[0];
3897             }
3898
3899             String instructionSet = null;
3900             if (app.info.primaryCpuAbi != null) {
3901                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3902             }
3903
3904             app.gids = gids;
3905             app.requiredAbi = requiredAbi;
3906             app.instructionSet = instructionSet;
3907
3908             // the per-user SELinux context must be set
3909             if (TextUtils.isEmpty(app.info.seInfoUser)) {
3910                 Slog.wtf(TAG, "SELinux tag not defined",
3911                         new IllegalStateException("SELinux tag not defined for "
3912                         + app.info.packageName + " (uid " + app.uid + ")"));
3913             }
3914             final String seInfo = app.info.seInfo
3915                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3916             // Start the process.  It will either succeed and return a result containing
3917             // the PID of the new process, or else throw a RuntimeException.
3918             boolean isActivityProcess = (entryPoint == null);
3919             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3920             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3921                     app.processName);
3922             checkTime(startTime, "startProcess: asking zygote to start proc");
3923             ProcessStartResult startResult;
3924             if (hostingType.equals("webview_service")) {
3925                 startResult = startWebView(entryPoint,
3926                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3927                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3928                         app.info.dataDir, null, entryPointArgs);
3929             } else {
3930                 startResult = Process.start(entryPoint,
3931                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3932                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3933                         app.info.dataDir, invokeWith, entryPointArgs);
3934             }
3935             checkTime(startTime, "startProcess: returned from zygote!");
3936             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3937
3938             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3939             checkTime(startTime, "startProcess: done updating battery stats");
3940
3941             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3942                     UserHandle.getUserId(uid), startResult.pid, uid,
3943                     app.processName, hostingType,
3944                     hostingNameStr != null ? hostingNameStr : "");
3945
3946             try {
3947                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3948                         seInfo, app.info.sourceDir, startResult.pid);
3949             } catch (RemoteException ex) {
3950                 // Ignore
3951             }
3952
3953             if (app.persistent) {
3954                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3955             }
3956
3957             checkTime(startTime, "startProcess: building log message");
3958             StringBuilder buf = mStringBuilder;
3959             buf.setLength(0);
3960             buf.append("Start proc ");
3961             buf.append(startResult.pid);
3962             buf.append(':');
3963             buf.append(app.processName);
3964             buf.append('/');
3965             UserHandle.formatUid(buf, uid);
3966             if (!isActivityProcess) {
3967                 buf.append(" [");
3968                 buf.append(entryPoint);
3969                 buf.append("]");
3970             }
3971             buf.append(" for ");
3972             buf.append(hostingType);
3973             if (hostingNameStr != null) {
3974                 buf.append(" ");
3975                 buf.append(hostingNameStr);
3976             }
3977             Slog.i(TAG, buf.toString());
3978             app.setPid(startResult.pid);
3979             app.usingWrapper = startResult.usingWrapper;
3980             app.removed = false;
3981             app.killed = false;
3982             app.killedByAm = false;
3983             checkTime(startTime, "startProcess: starting to update pids map");
3984             ProcessRecord oldApp;
3985             synchronized (mPidsSelfLocked) {
3986                 oldApp = mPidsSelfLocked.get(startResult.pid);
3987             }
3988             // If there is already an app occupying that pid that hasn't been cleaned up
3989             if (oldApp != null && !app.isolated) {
3990                 // Clean up anything relating to this pid first
3991                 Slog.w(TAG, "Reusing pid " + startResult.pid
3992                         + " while app is still mapped to it");
3993                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3994                         true /*replacingPid*/);
3995             }
3996             synchronized (mPidsSelfLocked) {
3997                 this.mPidsSelfLocked.put(startResult.pid, app);
3998                 if (isActivityProcess) {
3999                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4000                     msg.obj = app;
4001                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4002                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4003                 }
4004             }
4005             checkTime(startTime, "startProcess: done updating pids map");
4006         } catch (RuntimeException e) {
4007             Slog.e(TAG, "Failure starting process " + app.processName, e);
4008
4009             // Something went very wrong while trying to start this process; one
4010             // common case is when the package is frozen due to an active
4011             // upgrade. To recover, clean up any active bookkeeping related to
4012             // starting this process. (We already invoked this method once when
4013             // the package was initially frozen through KILL_APPLICATION_MSG, so
4014             // it doesn't hurt to use it again.)
4015             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4016                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4017         }
4018     }
4019
4020     void updateUsageStats(ActivityRecord component, boolean resumed) {
4021         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4022                 "updateUsageStats: comp=" + component + "res=" + resumed);
4023         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4024         if (resumed) {
4025             if (mUsageStatsService != null) {
4026                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4027                         UsageEvents.Event.MOVE_TO_FOREGROUND);
4028             }
4029             synchronized (stats) {
4030                 stats.noteActivityResumedLocked(component.app.uid);
4031             }
4032         } else {
4033             if (mUsageStatsService != null) {
4034                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4035                         UsageEvents.Event.MOVE_TO_BACKGROUND);
4036             }
4037             synchronized (stats) {
4038                 stats.noteActivityPausedLocked(component.app.uid);
4039             }
4040         }
4041     }
4042
4043     Intent getHomeIntent() {
4044         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4045         intent.setComponent(mTopComponent);
4046         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4047         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4048             intent.addCategory(Intent.CATEGORY_HOME);
4049         }
4050         return intent;
4051     }
4052
4053     boolean startHomeActivityLocked(int userId, String reason) {
4054         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4055                 && mTopAction == null) {
4056             // We are running in factory test mode, but unable to find
4057             // the factory test app, so just sit around displaying the
4058             // error message and don't try to start anything.
4059             return false;
4060         }
4061         Intent intent = getHomeIntent();
4062         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4063         if (aInfo != null) {
4064             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4065             // Don't do this if the home app is currently being
4066             // instrumented.
4067             aInfo = new ActivityInfo(aInfo);
4068             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4069             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4070                     aInfo.applicationInfo.uid, true);
4071             if (app == null || app.instr == null) {
4072                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4073                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4074                 // For ANR debugging to verify if the user activity is the one that actually
4075                 // launched.
4076                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4077                 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4078             }
4079         } else {
4080             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4081         }
4082
4083         return true;
4084     }
4085
4086     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4087         ActivityInfo ai = null;
4088         ComponentName comp = intent.getComponent();
4089         try {
4090             if (comp != null) {
4091                 // Factory test.
4092                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4093             } else {
4094                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4095                         intent,
4096                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4097                         flags, userId);
4098
4099                 if (info != null) {
4100                     ai = info.activityInfo;
4101                 }
4102             }
4103         } catch (RemoteException e) {
4104             // ignore
4105         }
4106
4107         return ai;
4108     }
4109
4110     /**
4111      * Starts the "new version setup screen" if appropriate.
4112      */
4113     void startSetupActivityLocked() {
4114         // Only do this once per boot.
4115         if (mCheckedForSetup) {
4116             return;
4117         }
4118
4119         // We will show this screen if the current one is a different
4120         // version than the last one shown, and we are not running in
4121         // low-level factory test mode.
4122         final ContentResolver resolver = mContext.getContentResolver();
4123         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4124                 Settings.Global.getInt(resolver,
4125                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4126             mCheckedForSetup = true;
4127
4128             // See if we should be showing the platform update setup UI.
4129             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4130             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4131                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4132             if (!ris.isEmpty()) {
4133                 final ResolveInfo ri = ris.get(0);
4134                 String vers = ri.activityInfo.metaData != null
4135                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4136                         : null;
4137                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4138                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4139                             Intent.METADATA_SETUP_VERSION);
4140                 }
4141                 String lastVers = Settings.Secure.getString(
4142                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4143                 if (vers != null && !vers.equals(lastVers)) {
4144                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4145                     intent.setComponent(new ComponentName(
4146                             ri.activityInfo.packageName, ri.activityInfo.name));
4147                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4148                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4149                             null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4150                 }
4151             }
4152         }
4153     }
4154
4155     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4156         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4157     }
4158
4159     void enforceNotIsolatedCaller(String caller) {
4160         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4161             throw new SecurityException("Isolated process not allowed to call " + caller);
4162         }
4163     }
4164
4165     void enforceShellRestriction(String restriction, int userHandle) {
4166         if (Binder.getCallingUid() == SHELL_UID) {
4167             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4168                 throw new SecurityException("Shell does not have permission to access user "
4169                         + userHandle);
4170             }
4171         }
4172     }
4173
4174     @Override
4175     public int getFrontActivityScreenCompatMode() {
4176         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4177         synchronized (this) {
4178             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4179         }
4180     }
4181
4182     @Override
4183     public void setFrontActivityScreenCompatMode(int mode) {
4184         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4185                 "setFrontActivityScreenCompatMode");
4186         synchronized (this) {
4187             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4188         }
4189     }
4190
4191     @Override
4192     public int getPackageScreenCompatMode(String packageName) {
4193         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4194         synchronized (this) {
4195             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4196         }
4197     }
4198
4199     @Override
4200     public void setPackageScreenCompatMode(String packageName, int mode) {
4201         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4202                 "setPackageScreenCompatMode");
4203         synchronized (this) {
4204             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4205         }
4206     }
4207
4208     @Override
4209     public boolean getPackageAskScreenCompat(String packageName) {
4210         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4211         synchronized (this) {
4212             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4213         }
4214     }
4215
4216     @Override
4217     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4218         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4219                 "setPackageAskScreenCompat");
4220         synchronized (this) {
4221             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4222         }
4223     }
4224
4225     private boolean hasUsageStatsPermission(String callingPackage) {
4226         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4227                 Binder.getCallingUid(), callingPackage);
4228         if (mode == AppOpsManager.MODE_DEFAULT) {
4229             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4230                     == PackageManager.PERMISSION_GRANTED;
4231         }
4232         return mode == AppOpsManager.MODE_ALLOWED;
4233     }
4234
4235     @Override
4236     public int getPackageProcessState(String packageName, String callingPackage) {
4237         if (!hasUsageStatsPermission(callingPackage)) {
4238             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4239                     "getPackageProcessState");
4240         }
4241
4242         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4243         synchronized (this) {
4244             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4245                 final ProcessRecord proc = mLruProcesses.get(i);
4246                 if (procState > proc.setProcState) {
4247                     if (proc.pkgList.containsKey(packageName) ||
4248                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4249                         procState = proc.setProcState;
4250                     }
4251                 }
4252             }
4253         }
4254         return procState;
4255     }
4256
4257     @Override
4258     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4259             throws RemoteException {
4260         synchronized (this) {
4261             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4262             if (app == null) {
4263                 throw new IllegalArgumentException("Unknown process: " + process);
4264             }
4265             if (app.thread == null) {
4266                 throw new IllegalArgumentException("Process has no app thread");
4267             }
4268             if (app.trimMemoryLevel >= level) {
4269                 throw new IllegalArgumentException(
4270                         "Unable to set a higher trim level than current level");
4271             }
4272             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4273                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4274                 throw new IllegalArgumentException("Unable to set a background trim level "
4275                     + "on a foreground process");
4276             }
4277             app.thread.scheduleTrimMemory(level);
4278             app.trimMemoryLevel = level;
4279             return true;
4280         }
4281     }
4282
4283     private void dispatchProcessesChanged() {
4284         int N;
4285         synchronized (this) {
4286             N = mPendingProcessChanges.size();
4287             if (mActiveProcessChanges.length < N) {
4288                 mActiveProcessChanges = new ProcessChangeItem[N];
4289             }
4290             mPendingProcessChanges.toArray(mActiveProcessChanges);
4291             mPendingProcessChanges.clear();
4292             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4293                     "*** Delivering " + N + " process changes");
4294         }
4295
4296         int i = mProcessObservers.beginBroadcast();
4297         while (i > 0) {
4298             i--;
4299             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4300             if (observer != null) {
4301                 try {
4302                     for (int j=0; j<N; j++) {
4303                         ProcessChangeItem item = mActiveProcessChanges[j];
4304                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4305                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4306                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4307                                     + item.uid + ": " + item.foregroundActivities);
4308                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4309                                     item.foregroundActivities);
4310                         }
4311                     }
4312                 } catch (RemoteException e) {
4313                 }
4314             }
4315         }
4316         mProcessObservers.finishBroadcast();
4317
4318         synchronized (this) {
4319             for (int j=0; j<N; j++) {
4320                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4321             }
4322         }
4323     }
4324
4325     private void dispatchProcessDied(int pid, int uid) {
4326         int i = mProcessObservers.beginBroadcast();
4327         while (i > 0) {
4328             i--;
4329             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4330             if (observer != null) {
4331                 try {
4332                     observer.onProcessDied(pid, uid);
4333                 } catch (RemoteException e) {
4334                 }
4335             }
4336         }
4337         mProcessObservers.finishBroadcast();
4338     }
4339
4340     @VisibleForTesting
4341     void dispatchUidsChanged() {
4342         int N;
4343         synchronized (this) {
4344             N = mPendingUidChanges.size();
4345             if (mActiveUidChanges.length < N) {
4346                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4347             }
4348             for (int i=0; i<N; i++) {
4349                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4350                 mActiveUidChanges[i] = change;
4351                 if (change.uidRecord != null) {
4352                     change.uidRecord.pendingChange = null;
4353                     change.uidRecord = null;
4354                 }
4355             }
4356             mPendingUidChanges.clear();
4357             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4358                     "*** Delivering " + N + " uid changes");
4359         }
4360
4361         int i = mUidObservers.beginBroadcast();
4362         while (i > 0) {
4363             i--;
4364             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4365                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4366         }
4367         mUidObservers.finishBroadcast();
4368
4369         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4370             for (int j = 0; j < N; ++j) {
4371                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4372                 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4373                     mValidateUids.remove(item.uid);
4374                 } else {
4375                     UidRecord validateUid = mValidateUids.get(item.uid);
4376                     if (validateUid == null) {
4377                         validateUid = new UidRecord(item.uid);
4378                         mValidateUids.put(item.uid, validateUid);
4379                     }
4380                     if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4381                         validateUid.idle = true;
4382                     } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4383                         validateUid.idle = false;
4384                     }
4385                     validateUid.curProcState = validateUid.setProcState = item.processState;
4386                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4387                 }
4388             }
4389         }
4390
4391         synchronized (this) {
4392             for (int j = 0; j < N; j++) {
4393                 mAvailUidChanges.add(mActiveUidChanges[j]);
4394             }
4395         }
4396     }
4397
4398     private void dispatchUidsChangedForObserver(IUidObserver observer,
4399             UidObserverRegistration reg, int changesSize) {
4400         if (observer == null) {
4401             return;
4402         }
4403         try {
4404             for (int j = 0; j < changesSize; j++) {
4405                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4406                 final int change = item.change;
4407                 if (change == UidRecord.CHANGE_PROCSTATE &&
4408                         (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4409                     // No-op common case: no significant change, the observer is not
4410                     // interested in all proc state changes.
4411                     continue;
4412                 }
4413                 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4414                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4415                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4416                                 "UID idle uid=" + item.uid);
4417                         observer.onUidIdle(item.uid, item.ephemeral);
4418                     }
4419                 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4420                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4421                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422                                 "UID active uid=" + item.uid);
4423                         observer.onUidActive(item.uid);
4424                     }
4425                 }
4426                 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4427                     if ((change & UidRecord.CHANGE_CACHED) != 0) {
4428                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4429                                 "UID cached uid=" + item.uid);
4430                         observer.onUidCachedChanged(item.uid, true);
4431                     } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4432                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4433                                 "UID active uid=" + item.uid);
4434                         observer.onUidCachedChanged(item.uid, false);
4435                     }
4436                 }
4437                 if ((change & UidRecord.CHANGE_GONE) != 0) {
4438                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4439                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4440                                 "UID gone uid=" + item.uid);
4441                         observer.onUidGone(item.uid, item.ephemeral);
4442                     }
4443                     if (reg.lastProcStates != null) {
4444                         reg.lastProcStates.delete(item.uid);
4445                     }
4446                 } else {
4447                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4448                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4449                                 "UID CHANGED uid=" + item.uid
4450                                         + ": " + item.processState);
4451                         boolean doReport = true;
4452                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4453                             final int lastState = reg.lastProcStates.get(item.uid,
4454                                     ActivityManager.PROCESS_STATE_UNKNOWN);
4455                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4456                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
4457                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
4458                                 doReport = lastAboveCut != newAboveCut;
4459                             } else {
4460                                 doReport = item.processState
4461                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
4462                             }
4463                         }
4464                         if (doReport) {
4465                             if (reg.lastProcStates != null) {
4466                                 reg.lastProcStates.put(item.uid, item.processState);
4467                             }
4468                             observer.onUidStateChanged(item.uid, item.processState,
4469                                     item.procStateSeq);
4470                         }
4471                     }
4472                 }
4473             }
4474         } catch (RemoteException e) {
4475         }
4476     }
4477
4478     void dispatchOomAdjObserver(String msg) {
4479         OomAdjObserver observer;
4480         synchronized (this) {
4481             observer = mCurOomAdjObserver;
4482         }
4483
4484         if (observer != null) {
4485             observer.onOomAdjMessage(msg);
4486         }
4487     }
4488
4489     void setOomAdjObserver(int uid, OomAdjObserver observer) {
4490         synchronized (this) {
4491             mCurOomAdjUid = uid;
4492             mCurOomAdjObserver = observer;
4493         }
4494     }
4495
4496     void clearOomAdjObserver() {
4497         synchronized (this) {
4498             mCurOomAdjUid = -1;
4499             mCurOomAdjObserver = null;
4500         }
4501     }
4502
4503     void reportOomAdjMessageLocked(String tag, String msg) {
4504         Slog.d(tag, msg);
4505         if (mCurOomAdjObserver != null) {
4506             mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4507         }
4508     }
4509
4510     @Override
4511     public final int startActivity(IApplicationThread caller, String callingPackage,
4512             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4513             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4514         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4515                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4516                 UserHandle.getCallingUserId());
4517     }
4518
4519     @Override
4520     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4521             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4522             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4523         enforceNotIsolatedCaller("startActivity");
4524         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4525                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4526         // TODO: Switch to user app stacks here.
4527         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4528                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4529                 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4530     }
4531
4532     @Override
4533     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4534             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4535             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4536             int userId) {
4537
4538         // This is very dangerous -- it allows you to perform a start activity (including
4539         // permission grants) as any app that may launch one of your own activities.  So
4540         // we will only allow this to be done from activities that are part of the core framework,
4541         // and then only when they are running as the system.
4542         final ActivityRecord sourceRecord;
4543         final int targetUid;
4544         final String targetPackage;
4545         synchronized (this) {
4546             if (resultTo == null) {
4547                 throw new SecurityException("Must be called from an activity");
4548             }
4549             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4550             if (sourceRecord == null) {
4551                 throw new SecurityException("Called with bad activity token: " + resultTo);
4552             }
4553             if (!sourceRecord.info.packageName.equals("android")) {
4554                 throw new SecurityException(
4555                         "Must be called from an activity that is declared in the android package");
4556             }
4557             if (sourceRecord.app == null) {
4558                 throw new SecurityException("Called without a process attached to activity");
4559             }
4560             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4561                 // This is still okay, as long as this activity is running under the
4562                 // uid of the original calling activity.
4563                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4564                     throw new SecurityException(
4565                             "Calling activity in uid " + sourceRecord.app.uid
4566                                     + " must be system uid or original calling uid "
4567                                     + sourceRecord.launchedFromUid);
4568                 }
4569             }
4570             if (ignoreTargetSecurity) {
4571                 if (intent.getComponent() == null) {
4572                     throw new SecurityException(
4573                             "Component must be specified with ignoreTargetSecurity");
4574                 }
4575                 if (intent.getSelector() != null) {
4576                     throw new SecurityException(
4577                             "Selector not allowed with ignoreTargetSecurity");
4578                 }
4579             }
4580             targetUid = sourceRecord.launchedFromUid;
4581             targetPackage = sourceRecord.launchedFromPackage;
4582         }
4583
4584         if (userId == UserHandle.USER_NULL) {
4585             userId = UserHandle.getUserId(sourceRecord.app.uid);
4586         }
4587
4588         // TODO: Switch to user app stacks here.
4589         try {
4590             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4591                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4592                     null, null, bOptions, ignoreTargetSecurity, userId, null,
4593                     "startActivityAsCaller");
4594             return ret;
4595         } catch (SecurityException e) {
4596             // XXX need to figure out how to propagate to original app.
4597             // A SecurityException here is generally actually a fault of the original
4598             // calling activity (such as a fairly granting permissions), so propagate it
4599             // back to them.
4600             /*
4601             StringBuilder msg = new StringBuilder();
4602             msg.append("While launching");
4603             msg.append(intent.toString());
4604             msg.append(": ");
4605             msg.append(e.getMessage());
4606             */
4607             throw e;
4608         }
4609     }
4610
4611     @Override
4612     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4613             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4614             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4615         enforceNotIsolatedCaller("startActivityAndWait");
4616         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4617                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4618         WaitResult res = new WaitResult();
4619         // TODO: Switch to user app stacks here.
4620         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4621                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4622                 bOptions, false, userId, null, "startActivityAndWait");
4623         return res;
4624     }
4625
4626     @Override
4627     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4628             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4629             int startFlags, Configuration config, Bundle bOptions, int userId) {
4630         enforceNotIsolatedCaller("startActivityWithConfig");
4631         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4632                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4633         // TODO: Switch to user app stacks here.
4634         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4635                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4636                 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4637         return ret;
4638     }
4639
4640     @Override
4641     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4642             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4643             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4644             throws TransactionTooLargeException {
4645         enforceNotIsolatedCaller("startActivityIntentSender");
4646         // Refuse possible leaked file descriptors
4647         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4648             throw new IllegalArgumentException("File descriptors passed in Intent");
4649         }
4650
4651         if (!(target instanceof PendingIntentRecord)) {
4652             throw new IllegalArgumentException("Bad PendingIntent object");
4653         }
4654
4655         PendingIntentRecord pir = (PendingIntentRecord)target;
4656
4657         synchronized (this) {
4658             // If this is coming from the currently resumed activity, it is
4659             // effectively saying that app switches are allowed at this point.
4660             final ActivityStack stack = getFocusedStack();
4661             if (stack.mResumedActivity != null &&
4662                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4663                 mAppSwitchesAllowedTime = 0;
4664             }
4665         }
4666         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4667                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4668         return ret;
4669     }
4670
4671     @Override
4672     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4673             Intent intent, String resolvedType, IVoiceInteractionSession session,
4674             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4675             Bundle bOptions, int userId) {
4676         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4677                 != PackageManager.PERMISSION_GRANTED) {
4678             String msg = "Permission Denial: startVoiceActivity() from pid="
4679                     + Binder.getCallingPid()
4680                     + ", uid=" + Binder.getCallingUid()
4681                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4682             Slog.w(TAG, msg);
4683             throw new SecurityException(msg);
4684         }
4685         if (session == null || interactor == null) {
4686             throw new NullPointerException("null session or interactor");
4687         }
4688         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4689                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4690         // TODO: Switch to user app stacks here.
4691         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4692                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4693                 null, bOptions, false, userId, null, "startVoiceActivity");
4694     }
4695
4696     @Override
4697     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4698             Intent intent, String resolvedType, Bundle bOptions, int userId) {
4699         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4700                 != PackageManager.PERMISSION_GRANTED) {
4701             final String msg = "Permission Denial: startAssistantActivity() from pid="
4702                     + Binder.getCallingPid()
4703                     + ", uid=" + Binder.getCallingUid()
4704                     + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4705             Slog.w(TAG, msg);
4706             throw new SecurityException(msg);
4707         }
4708         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4709                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4710         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4711                 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4712                 userId, null, "startAssistantActivity");
4713     }
4714
4715     @Override
4716     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4717             throws RemoteException {
4718         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4719         synchronized (this) {
4720             ActivityRecord activity = getFocusedStack().topActivity();
4721             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4722                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4723             }
4724             if (mRunningVoice != null || activity.getTask().voiceSession != null
4725                     || activity.voiceSession != null) {
4726                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4727                 return;
4728             }
4729             if (activity.pendingVoiceInteractionStart) {
4730                 Slog.w(TAG, "Pending start of voice interaction already.");
4731                 return;
4732             }
4733             activity.pendingVoiceInteractionStart = true;
4734         }
4735         LocalServices.getService(VoiceInteractionManagerInternal.class)
4736                 .startLocalVoiceInteraction(callingActivity, options);
4737     }
4738
4739     @Override
4740     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4741         LocalServices.getService(VoiceInteractionManagerInternal.class)
4742                 .stopLocalVoiceInteraction(callingActivity);
4743     }
4744
4745     @Override
4746     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4747         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4748                 .supportsLocalVoiceInteraction();
4749     }
4750
4751     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4752             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4753         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4754         if (activityToCallback == null) return;
4755         activityToCallback.setVoiceSessionLocked(voiceSession);
4756
4757         // Inform the activity
4758         try {
4759             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4760                     voiceInteractor);
4761             long token = Binder.clearCallingIdentity();
4762             try {
4763                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4764             } finally {
4765                 Binder.restoreCallingIdentity(token);
4766             }
4767             // TODO: VI Should we cache the activity so that it's easier to find later
4768             // rather than scan through all the stacks and activities?
4769         } catch (RemoteException re) {
4770             activityToCallback.clearVoiceSessionLocked();
4771             // TODO: VI Should this terminate the voice session?
4772         }
4773     }
4774
4775     @Override
4776     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4777         synchronized (this) {
4778             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4779                 if (keepAwake) {
4780                     mVoiceWakeLock.acquire();
4781                 } else {
4782                     mVoiceWakeLock.release();
4783                 }
4784             }
4785         }
4786     }
4787
4788     @Override
4789     public boolean startNextMatchingActivity(IBinder callingActivity,
4790             Intent intent, Bundle bOptions) {
4791         // Refuse possible leaked file descriptors
4792         if (intent != null && intent.hasFileDescriptors() == true) {
4793             throw new IllegalArgumentException("File descriptors passed in Intent");
4794         }
4795         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4796
4797         synchronized (this) {
4798             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4799             if (r == null) {
4800                 ActivityOptions.abort(options);
4801                 return false;
4802             }
4803             if (r.app == null || r.app.thread == null) {
4804                 // The caller is not running...  d'oh!
4805                 ActivityOptions.abort(options);
4806                 return false;
4807             }
4808             intent = new Intent(intent);
4809             // The caller is not allowed to change the data.
4810             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4811             // And we are resetting to find the next component...
4812             intent.setComponent(null);
4813
4814             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4815
4816             ActivityInfo aInfo = null;
4817             try {
4818                 List<ResolveInfo> resolves =
4819                     AppGlobals.getPackageManager().queryIntentActivities(
4820                             intent, r.resolvedType,
4821                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4822                             UserHandle.getCallingUserId()).getList();
4823
4824                 // Look for the original activity in the list...
4825                 final int N = resolves != null ? resolves.size() : 0;
4826                 for (int i=0; i<N; i++) {
4827                     ResolveInfo rInfo = resolves.get(i);
4828                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4829                             && rInfo.activityInfo.name.equals(r.info.name)) {
4830                         // We found the current one...  the next matching is
4831                         // after it.
4832                         i++;
4833                         if (i<N) {
4834                             aInfo = resolves.get(i).activityInfo;
4835                         }
4836                         if (debug) {
4837                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4838                                     + "/" + r.info.name);
4839                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4840                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4841                         }
4842                         break;
4843                     }
4844                 }
4845             } catch (RemoteException e) {
4846             }
4847
4848             if (aInfo == null) {
4849                 // Nobody who is next!
4850                 ActivityOptions.abort(options);
4851                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4852                 return false;
4853             }
4854
4855             intent.setComponent(new ComponentName(
4856                     aInfo.applicationInfo.packageName, aInfo.name));
4857             intent.setFlags(intent.getFlags()&~(
4858                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4859                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4860                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4861                     Intent.FLAG_ACTIVITY_NEW_TASK));
4862
4863             // Okay now we need to start the new activity, replacing the
4864             // currently running activity.  This is a little tricky because
4865             // we want to start the new one as if the current one is finished,
4866             // but not finish the current one first so that there is no flicker.
4867             // And thus...
4868             final boolean wasFinishing = r.finishing;
4869             r.finishing = true;
4870
4871             // Propagate reply information over to the new activity.
4872             final ActivityRecord resultTo = r.resultTo;
4873             final String resultWho = r.resultWho;
4874             final int requestCode = r.requestCode;
4875             r.resultTo = null;
4876             if (resultTo != null) {
4877                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4878             }
4879
4880             final long origId = Binder.clearCallingIdentity();
4881             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4882                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4883                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4884                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4885                     false, false, null, null, "startNextMatchingActivity");
4886             Binder.restoreCallingIdentity(origId);
4887
4888             r.finishing = wasFinishing;
4889             if (res != ActivityManager.START_SUCCESS) {
4890                 return false;
4891             }
4892             return true;
4893         }
4894     }
4895
4896     @Override
4897     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4898         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4899             String msg = "Permission Denial: startActivityFromRecents called without " +
4900                     START_TASKS_FROM_RECENTS;
4901             Slog.w(TAG, msg);
4902             throw new SecurityException(msg);
4903         }
4904         final long origId = Binder.clearCallingIdentity();
4905         try {
4906             synchronized (this) {
4907                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4908             }
4909         } finally {
4910             Binder.restoreCallingIdentity(origId);
4911         }
4912     }
4913
4914     final int startActivityInPackage(int uid, String callingPackage,
4915             Intent intent, String resolvedType, IBinder resultTo,
4916             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4917             TaskRecord inTask, String reason) {
4918
4919         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4920                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4921
4922         // TODO: Switch to user app stacks here.
4923         return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4924                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4925                 null, null, null, bOptions, false, userId, inTask, reason);
4926     }
4927
4928     @Override
4929     public final int startActivities(IApplicationThread caller, String callingPackage,
4930             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4931             int userId) {
4932         final String reason = "startActivities";
4933         enforceNotIsolatedCaller(reason);
4934         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4935                 userId, false, ALLOW_FULL_ONLY, reason, null);
4936         // TODO: Switch to user app stacks here.
4937         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4938                 resolvedTypes, resultTo, bOptions, userId, reason);
4939         return ret;
4940     }
4941
4942     final int startActivitiesInPackage(int uid, String callingPackage,
4943             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4944             Bundle bOptions, int userId) {
4945
4946         final String reason = "startActivityInPackage";
4947         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4948                 userId, false, ALLOW_FULL_ONLY, reason, null);
4949         // TODO: Switch to user app stacks here.
4950         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4951                 resultTo, bOptions, userId, reason);
4952         return ret;
4953     }
4954
4955     @Override
4956     public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4957         synchronized (this) {
4958             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4959             if (r == null) {
4960                 return;
4961             }
4962             r.reportFullyDrawnLocked(restoredFromBundle);
4963         }
4964     }
4965
4966     @Override
4967     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4968         synchronized (this) {
4969             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4970             if (r == null) {
4971                 return;
4972             }
4973             final long origId = Binder.clearCallingIdentity();
4974             try {
4975                 r.setRequestedOrientation(requestedOrientation);
4976             } finally {
4977                 Binder.restoreCallingIdentity(origId);
4978             }
4979         }
4980     }
4981
4982     @Override
4983     public int getRequestedOrientation(IBinder token) {
4984         synchronized (this) {
4985             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4986             if (r == null) {
4987                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4988             }
4989             return r.getRequestedOrientation();
4990         }
4991     }
4992
4993     @Override
4994     public final void requestActivityRelaunch(IBinder token) {
4995         synchronized(this) {
4996             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4997             if (r == null) {
4998                 return;
4999             }
5000             final long origId = Binder.clearCallingIdentity();
5001             try {
5002                 r.forceNewConfig = true;
5003                 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5004                         true /* preserveWindow */);
5005             } finally {
5006                 Binder.restoreCallingIdentity(origId);
5007             }
5008         }
5009     }
5010
5011     /**
5012      * This is the internal entry point for handling Activity.finish().
5013      *
5014      * @param token The Binder token referencing the Activity we want to finish.
5015      * @param resultCode Result code, if any, from this Activity.
5016      * @param resultData Result data (Intent), if any, from this Activity.
5017      * @param finishTask Whether to finish the task associated with this Activity.
5018      *
5019      * @return Returns true if the activity successfully finished, or false if it is still running.
5020      */
5021     @Override
5022     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5023             int finishTask) {
5024         // Refuse possible leaked file descriptors
5025         if (resultData != null && resultData.hasFileDescriptors() == true) {
5026             throw new IllegalArgumentException("File descriptors passed in Intent");
5027         }
5028
5029         synchronized(this) {
5030             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5031             if (r == null) {
5032                 return true;
5033             }
5034             // Keep track of the root activity of the task before we finish it
5035             TaskRecord tr = r.getTask();
5036             ActivityRecord rootR = tr.getRootActivity();
5037             if (rootR == null) {
5038                 Slog.w(TAG, "Finishing task with all activities already finished");
5039             }
5040             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5041             // finish.
5042             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5043                     mStackSupervisor.isLastLockedTask(tr)) {
5044                 Slog.i(TAG, "Not finishing task in lock task mode");
5045                 mStackSupervisor.showLockTaskToast();
5046                 return false;
5047             }
5048             if (mController != null) {
5049                 // Find the first activity that is not finishing.
5050                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5051                 if (next != null) {
5052                     // ask watcher if this is allowed
5053                     boolean resumeOK = true;
5054                     try {
5055                         resumeOK = mController.activityResuming(next.packageName);
5056                     } catch (RemoteException e) {
5057                         mController = null;
5058                         Watchdog.getInstance().setActivityController(null);
5059                     }
5060
5061                     if (!resumeOK) {
5062                         Slog.i(TAG, "Not finishing activity because controller resumed");
5063                         return false;
5064                     }
5065                 }
5066             }
5067             final long origId = Binder.clearCallingIdentity();
5068             try {
5069                 boolean res;
5070                 final boolean finishWithRootActivity =
5071                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5072                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5073                         || (finishWithRootActivity && r == rootR)) {
5074                     // If requested, remove the task that is associated to this activity only if it
5075                     // was the root activity in the task. The result code and data is ignored
5076                     // because we don't support returning them across task boundaries. Also, to
5077                     // keep backwards compatibility we remove the task from recents when finishing
5078                     // task with root activity.
5079                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5080                     if (!res) {
5081                         Slog.i(TAG, "Removing task failed to finish activity");
5082                     }
5083                 } else {
5084                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5085                             resultData, "app-request", true);
5086                     if (!res) {
5087                         Slog.i(TAG, "Failed to finish by app-request");
5088                     }
5089                 }
5090                 return res;
5091             } finally {
5092                 Binder.restoreCallingIdentity(origId);
5093             }
5094         }
5095     }
5096
5097     @Override
5098     public final void finishHeavyWeightApp() {
5099         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5100                 != PackageManager.PERMISSION_GRANTED) {
5101             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5102                     + Binder.getCallingPid()
5103                     + ", uid=" + Binder.getCallingUid()
5104                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5105             Slog.w(TAG, msg);
5106             throw new SecurityException(msg);
5107         }
5108
5109         synchronized(this) {
5110             if (mHeavyWeightProcess == null) {
5111                 return;
5112             }
5113
5114             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5115             for (int i = 0; i < activities.size(); i++) {
5116                 ActivityRecord r = activities.get(i);
5117                 if (!r.finishing && r.isInStackLocked()) {
5118                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5119                             null, "finish-heavy", true);
5120                 }
5121             }
5122
5123             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5124                     mHeavyWeightProcess.userId, 0));
5125             mHeavyWeightProcess = null;
5126         }
5127     }
5128
5129     @Override
5130     public void crashApplication(int uid, int initialPid, String packageName, int userId,
5131             String message) {
5132         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5133                 != PackageManager.PERMISSION_GRANTED) {
5134             String msg = "Permission Denial: crashApplication() from pid="
5135                     + Binder.getCallingPid()
5136                     + ", uid=" + Binder.getCallingUid()
5137                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5138             Slog.w(TAG, msg);
5139             throw new SecurityException(msg);
5140         }
5141
5142         synchronized(this) {
5143             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5144         }
5145     }
5146
5147     @Override
5148     public final void finishSubActivity(IBinder token, String resultWho,
5149             int requestCode) {
5150         synchronized(this) {
5151             final long origId = Binder.clearCallingIdentity();
5152             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5153             if (r != null) {
5154                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5155             }
5156             Binder.restoreCallingIdentity(origId);
5157         }
5158     }
5159
5160     @Override
5161     public boolean finishActivityAffinity(IBinder token) {
5162         synchronized(this) {
5163             final long origId = Binder.clearCallingIdentity();
5164             try {
5165                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5166                 if (r == null) {
5167                     return false;
5168                 }
5169
5170                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5171                 // can finish.
5172                 final TaskRecord task = r.getTask();
5173                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5174                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5175                     mStackSupervisor.showLockTaskToast();
5176                     return false;
5177                 }
5178                 return task.getStack().finishActivityAffinityLocked(r);
5179             } finally {
5180                 Binder.restoreCallingIdentity(origId);
5181             }
5182         }
5183     }
5184
5185     @Override
5186     public void finishVoiceTask(IVoiceInteractionSession session) {
5187         synchronized (this) {
5188             final long origId = Binder.clearCallingIdentity();
5189             try {
5190                 // TODO: VI Consider treating local voice interactions and voice tasks
5191                 // differently here
5192                 mStackSupervisor.finishVoiceTask(session);
5193             } finally {
5194                 Binder.restoreCallingIdentity(origId);
5195             }
5196         }
5197
5198     }
5199
5200     @Override
5201     public boolean releaseActivityInstance(IBinder token) {
5202         synchronized(this) {
5203             final long origId = Binder.clearCallingIdentity();
5204             try {
5205                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5206                 if (r == null) {
5207                     return false;
5208                 }
5209                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5210             } finally {
5211                 Binder.restoreCallingIdentity(origId);
5212             }
5213         }
5214     }
5215
5216     @Override
5217     public void releaseSomeActivities(IApplicationThread appInt) {
5218         synchronized(this) {
5219             final long origId = Binder.clearCallingIdentity();
5220             try {
5221                 ProcessRecord app = getRecordForAppLocked(appInt);
5222                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5223             } finally {
5224                 Binder.restoreCallingIdentity(origId);
5225             }
5226         }
5227     }
5228
5229     @Override
5230     public boolean willActivityBeVisible(IBinder token) {
5231         synchronized(this) {
5232             ActivityStack stack = ActivityRecord.getStackLocked(token);
5233             if (stack != null) {
5234                 return stack.willActivityBeVisibleLocked(token);
5235             }
5236             return false;
5237         }
5238     }
5239
5240     @Override
5241     public void overridePendingTransition(IBinder token, String packageName,
5242             int enterAnim, int exitAnim) {
5243         synchronized(this) {
5244             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5245             if (self == null) {
5246                 return;
5247             }
5248
5249             final long origId = Binder.clearCallingIdentity();
5250
5251             if (self.state == ActivityState.RESUMED
5252                     || self.state == ActivityState.PAUSING) {
5253                 mWindowManager.overridePendingAppTransition(packageName,
5254                         enterAnim, exitAnim, null);
5255             }
5256
5257             Binder.restoreCallingIdentity(origId);
5258         }
5259     }
5260
5261     /**
5262      * Main function for removing an existing process from the activity manager
5263      * as a result of that process going away.  Clears out all connections
5264      * to the process.
5265      */
5266     private final void handleAppDiedLocked(ProcessRecord app,
5267             boolean restarting, boolean allowRestart) {
5268         int pid = app.pid;
5269         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5270                 false /*replacingPid*/);
5271         if (!kept && !restarting) {
5272             removeLruProcessLocked(app);
5273             if (pid > 0) {
5274                 ProcessList.remove(pid);
5275             }
5276         }
5277
5278         if (mProfileProc == app) {
5279             clearProfilerLocked();
5280         }
5281
5282         // Remove this application's activities from active lists.
5283         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5284
5285         app.activities.clear();
5286
5287         if (app.instr != null) {
5288             Slog.w(TAG, "Crash of app " + app.processName
5289                   + " running instrumentation " + app.instr.mClass);
5290             Bundle info = new Bundle();
5291             info.putString("shortMsg", "Process crashed.");
5292             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5293         }
5294
5295         mWindowManager.deferSurfaceLayout();
5296         try {
5297             if (!restarting && hasVisibleActivities
5298                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5299                 // If there was nothing to resume, and we are not already restarting this process, but
5300                 // there is a visible activity that is hosted by the process...  then make sure all
5301                 // visible activities are running, taking care of restarting this process.
5302                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5303             }
5304         } finally {
5305             mWindowManager.continueSurfaceLayout();
5306         }
5307     }
5308
5309     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5310         final IBinder threadBinder = thread.asBinder();
5311         // Find the application record.
5312         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5313             final ProcessRecord rec = mLruProcesses.get(i);
5314             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5315                 return i;
5316             }
5317         }
5318         return -1;
5319     }
5320
5321     final ProcessRecord getRecordForAppLocked(
5322             IApplicationThread thread) {
5323         if (thread == null) {
5324             return null;
5325         }
5326
5327         int appIndex = getLRURecordIndexForAppLocked(thread);
5328         if (appIndex >= 0) {
5329             return mLruProcesses.get(appIndex);
5330         }
5331
5332         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5333         // double-check that.
5334         final IBinder threadBinder = thread.asBinder();
5335         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5336         for (int i = pmap.size()-1; i >= 0; i--) {
5337             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5338             for (int j = procs.size()-1; j >= 0; j--) {
5339                 final ProcessRecord proc = procs.valueAt(j);
5340                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5341                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5342                             + proc);
5343                     return proc;
5344                 }
5345             }
5346         }
5347
5348         return null;
5349     }
5350
5351     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5352         // If there are no longer any background processes running,
5353         // and the app that died was not running instrumentation,
5354         // then tell everyone we are now low on memory.
5355         boolean haveBg = false;
5356         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5357             ProcessRecord rec = mLruProcesses.get(i);
5358             if (rec.thread != null
5359                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5360                 haveBg = true;
5361                 break;
5362             }
5363         }
5364
5365         if (!haveBg) {
5366             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5367             if (doReport) {
5368                 long now = SystemClock.uptimeMillis();
5369                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5370                     doReport = false;
5371                 } else {
5372                     mLastMemUsageReportTime = now;
5373                 }
5374             }
5375             final ArrayList<ProcessMemInfo> memInfos
5376                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5377             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5378             long now = SystemClock.uptimeMillis();
5379             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5380                 ProcessRecord rec = mLruProcesses.get(i);
5381                 if (rec == dyingProc || rec.thread == null) {
5382                     continue;
5383                 }
5384                 if (doReport) {
5385                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5386                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5387                 }
5388                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5389                     // The low memory report is overriding any current
5390                     // state for a GC request.  Make sure to do
5391                     // heavy/important/visible/foreground processes first.
5392                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5393                         rec.lastRequestedGc = 0;
5394                     } else {
5395                         rec.lastRequestedGc = rec.lastLowMemory;
5396                     }
5397                     rec.reportLowMemory = true;
5398                     rec.lastLowMemory = now;
5399                     mProcessesToGc.remove(rec);
5400                     addProcessToGcListLocked(rec);
5401                 }
5402             }
5403             if (doReport) {
5404                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5405                 mHandler.sendMessage(msg);
5406             }
5407             scheduleAppGcsLocked();
5408         }
5409     }
5410
5411     final void appDiedLocked(ProcessRecord app) {
5412        appDiedLocked(app, app.pid, app.thread, false);
5413     }
5414
5415     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5416             boolean fromBinderDied) {
5417         // First check if this ProcessRecord is actually active for the pid.
5418         synchronized (mPidsSelfLocked) {
5419             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5420             if (curProc != app) {
5421                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5422                 return;
5423             }
5424         }
5425
5426         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5427         synchronized (stats) {
5428             stats.noteProcessDiedLocked(app.info.uid, pid);
5429         }
5430
5431         if (!app.killed) {
5432             if (!fromBinderDied) {
5433                 killProcessQuiet(pid);
5434             }
5435             killProcessGroup(app.uid, pid);
5436             app.killed = true;
5437         }
5438
5439         // Clean up already done if the process has been re-started.
5440         if (app.pid == pid && app.thread != null &&
5441                 app.thread.asBinder() == thread.asBinder()) {
5442             boolean doLowMem = app.instr == null;
5443             boolean doOomAdj = doLowMem;
5444             if (!app.killedByAm) {
5445                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5446                         + ProcessList.makeOomAdjString(app.setAdj)
5447                         + ProcessList.makeProcStateString(app.setProcState));
5448                 mAllowLowerMemLevel = true;
5449             } else {
5450                 // Note that we always want to do oom adj to update our state with the
5451                 // new number of procs.
5452                 mAllowLowerMemLevel = false;
5453                 doLowMem = false;
5454             }
5455             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5456                     app.setAdj, app.setProcState);
5457             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5458                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5459             handleAppDiedLocked(app, false, true);
5460
5461             if (doOomAdj) {
5462                 updateOomAdjLocked();
5463             }
5464             if (doLowMem) {
5465                 doLowMemReportIfNeededLocked(app);
5466             }
5467         } else if (app.pid != pid) {
5468             // A new process has already been started.
5469             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5470                     + ") has died and restarted (pid " + app.pid + ").");
5471             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5472         } else if (DEBUG_PROCESSES) {
5473             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5474                     + thread.asBinder());
5475         }
5476     }
5477
5478     /**
5479      * If a stack trace dump file is configured, dump process stack traces.
5480      * @param clearTraces causes the dump file to be erased prior to the new
5481      *    traces being written, if true; when false, the new traces will be
5482      *    appended to any existing file content.
5483      * @param firstPids of dalvik VM processes to dump stack traces for first
5484      * @param lastPids of dalvik VM processes to dump stack traces for last
5485      * @param nativePids optional list of native pids to dump stack crawls
5486      */
5487     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5488             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5489             ArrayList<Integer> nativePids) {
5490         ArrayList<Integer> extraPids = null;
5491
5492         // Measure CPU usage as soon as we're called in order to get a realistic sampling
5493         // of the top users at the time of the request.
5494         if (processCpuTracker != null) {
5495             processCpuTracker.init();
5496             try {
5497                 Thread.sleep(200);
5498             } catch (InterruptedException ignored) {
5499             }
5500
5501             processCpuTracker.update();
5502
5503             // We'll take the stack crawls of just the top apps using CPU.
5504             final int N = processCpuTracker.countWorkingStats();
5505             extraPids = new ArrayList<>();
5506             for (int i = 0; i < N && extraPids.size() < 5; i++) {
5507                 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5508                 if (lastPids.indexOfKey(stats.pid) >= 0) {
5509                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5510
5511                     extraPids.add(stats.pid);
5512                 } else if (DEBUG_ANR) {
5513                     Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5514                             + stats.pid);
5515                 }
5516             }
5517         }
5518
5519         boolean useTombstonedForJavaTraces = false;
5520         File tracesFile;
5521
5522         final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5523         if (tracesDirProp.isEmpty()) {
5524             // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5525             // dumping scheme. All traces are written to a global trace file (usually
5526             // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5527             // the file if requested.
5528             //
5529             // This mode of operation will be removed in the near future.
5530
5531
5532             String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5533             if (globalTracesPath.isEmpty()) {
5534                 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5535                 return null;
5536             }
5537
5538             tracesFile = new File(globalTracesPath);
5539             try {
5540                 if (clearTraces && tracesFile.exists()) {
5541                     tracesFile.delete();
5542                 }
5543
5544                 tracesFile.createNewFile();
5545                 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5546             } catch (IOException e) {
5547                 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5548                 return null;
5549             }
5550         } else {
5551             File tracesDir = new File(tracesDirProp);
5552             // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5553             // Each set of ANR traces is written to a separate file and dumpstate will process
5554             // all such files and add them to a captured bug report if they're recent enough.
5555             maybePruneOldTraces(tracesDir);
5556
5557             // NOTE: We should consider creating the file in native code atomically once we've
5558             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5559             // can be removed.
5560             tracesFile = createAnrDumpFile(tracesDir);
5561             if (tracesFile == null) {
5562                 return null;
5563             }
5564
5565             useTombstonedForJavaTraces = true;
5566         }
5567
5568         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5569                 useTombstonedForJavaTraces);
5570         return tracesFile;
5571     }
5572
5573     @GuardedBy("ActivityManagerService.class")
5574     private static SimpleDateFormat sAnrFileDateFormat;
5575
5576     private static synchronized File createAnrDumpFile(File tracesDir) {
5577         if (sAnrFileDateFormat == null) {
5578             sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5579         }
5580
5581         final String formattedDate = sAnrFileDateFormat.format(new Date());
5582         final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5583
5584         try {
5585             if (anrFile.createNewFile()) {
5586                 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5587                 return anrFile;
5588             } else {
5589                 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5590             }
5591         } catch (IOException ioe) {
5592             Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5593         }
5594
5595         return null;
5596     }
5597
5598     /**
5599      * Prune all trace files that are more than a day old.
5600      *
5601      * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5602      * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5603      * since it's the system_server that creates trace files for most ANRs.
5604      */
5605     private static void maybePruneOldTraces(File tracesDir) {
5606         final long now = System.currentTimeMillis();
5607         final File[] traceFiles = tracesDir.listFiles();
5608
5609         if (traceFiles != null) {
5610             for (File file : traceFiles) {
5611                 if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5612                     if (!file.delete()) {
5613                         Slog.w(TAG, "Unable to prune stale trace file: " + file);
5614                     }
5615                 }
5616             }
5617         }
5618     }
5619
5620     /**
5621      * Legacy code, do not use. Existing users will be deleted.
5622      *
5623      * @deprecated
5624      */
5625     @Deprecated
5626     public static class DumpStackFileObserver extends FileObserver {
5627         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5628         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5629
5630         private final String mTracesPath;
5631         private boolean mClosed;
5632
5633         public DumpStackFileObserver(String tracesPath) {
5634             super(tracesPath, FileObserver.CLOSE_WRITE);
5635             mTracesPath = tracesPath;
5636         }
5637
5638         @Override
5639         public synchronized void onEvent(int event, String path) {
5640             mClosed = true;
5641             notify();
5642         }
5643
5644         public long dumpWithTimeout(int pid, long timeout) {
5645             sendSignal(pid, SIGNAL_QUIT);
5646             final long start = SystemClock.elapsedRealtime();
5647
5648             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5649             synchronized (this) {
5650                 try {
5651                     wait(waitTime); // Wait for traces file to be closed.
5652                 } catch (InterruptedException e) {
5653                     Slog.wtf(TAG, e);
5654                 }
5655             }
5656
5657             // This avoids a corner case of passing a negative time to the native
5658             // trace in case we've already hit the overall timeout.
5659             final long timeWaited = SystemClock.elapsedRealtime() - start;
5660             if (timeWaited >= timeout) {
5661                 return timeWaited;
5662             }
5663
5664             if (!mClosed) {
5665                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5666                        ". Attempting native stack collection.");
5667
5668                 final long nativeDumpTimeoutMs = Math.min(
5669                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5670
5671                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5672                         (int) (nativeDumpTimeoutMs / 1000));
5673             }
5674
5675             final long end = SystemClock.elapsedRealtime();
5676             mClosed = false;
5677
5678             return (end - start);
5679         }
5680     }
5681
5682     /**
5683      * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5684      * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5685      * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5686      * attempting to obtain native traces in the case of a failure. Returns the total time spent
5687      * capturing traces.
5688      */
5689     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5690         final long timeStart = SystemClock.elapsedRealtime();
5691         if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5692             Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5693                     (NATIVE_DUMP_TIMEOUT_MS / 1000));
5694         }
5695
5696         return SystemClock.elapsedRealtime() - timeStart;
5697     }
5698
5699     private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5700             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5701             boolean useTombstonedForJavaTraces) {
5702
5703         // We don't need any sort of inotify based monitoring when we're dumping traces via
5704         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5705         // control of all writes to the file in question.
5706         final DumpStackFileObserver observer;
5707         if (useTombstonedForJavaTraces) {
5708             observer = null;
5709         } else {
5710             // Use a FileObserver to detect when traces finish writing.
5711             // The order of traces is considered important to maintain for legibility.
5712             observer = new DumpStackFileObserver(tracesFile);
5713         }
5714
5715         // We must complete all stack dumps within 20 seconds.
5716         long remainingTime = 20 * 1000;
5717         try {
5718             if (observer != null) {
5719                 observer.startWatching();
5720             }
5721
5722             // First collect all of the stacks of the most important pids.
5723             if (firstPids != null) {
5724                 int num = firstPids.size();
5725                 for (int i = 0; i < num; i++) {
5726                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5727                             + firstPids.get(i));
5728                     final long timeTaken;
5729                     if (useTombstonedForJavaTraces) {
5730                         timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5731                     } else {
5732                         timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5733                     }
5734
5735                     remainingTime -= timeTaken;
5736                     if (remainingTime <= 0) {
5737                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5738                             "); deadline exceeded.");
5739                         return;
5740                     }
5741
5742                     if (DEBUG_ANR) {
5743                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5744                     }
5745                 }
5746             }
5747
5748             // Next collect the stacks of the native pids
5749             if (nativePids != null) {
5750                 for (int pid : nativePids) {
5751                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5752                     final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5753
5754                     final long start = SystemClock.elapsedRealtime();
5755                     Debug.dumpNativeBacktraceToFileTimeout(
5756                             pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5757                     final long timeTaken = SystemClock.elapsedRealtime() - start;
5758
5759                     remainingTime -= timeTaken;
5760                     if (remainingTime <= 0) {
5761                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5762                             "); deadline exceeded.");
5763                         return;
5764                     }
5765
5766                     if (DEBUG_ANR) {
5767                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5768                     }
5769                 }
5770             }
5771
5772             // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5773             if (extraPids != null) {
5774                 for (int pid : extraPids) {
5775                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5776
5777                     final long timeTaken;
5778                     if (useTombstonedForJavaTraces) {
5779                         timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5780                     } else {
5781                         timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5782                     }
5783
5784                     remainingTime -= timeTaken;
5785                     if (remainingTime <= 0) {
5786                         Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5787                                 "); deadline exceeded.");
5788                         return;
5789                     }
5790
5791                     if (DEBUG_ANR) {
5792                         Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5793                     }
5794                 }
5795             }
5796         } finally {
5797             if (observer != null) {
5798                 observer.stopWatching();
5799             }
5800         }
5801     }
5802
5803     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5804         if (true || Build.IS_USER) {
5805             return;
5806         }
5807         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5808         if (tracesPath == null || tracesPath.length() == 0) {
5809             return;
5810         }
5811
5812         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5813         StrictMode.allowThreadDiskWrites();
5814         try {
5815             final File tracesFile = new File(tracesPath);
5816             final File tracesDir = tracesFile.getParentFile();
5817             final File tracesTmp = new File(tracesDir, "__tmp__");
5818             try {
5819                 if (tracesFile.exists()) {
5820                     tracesTmp.delete();
5821                     tracesFile.renameTo(tracesTmp);
5822                 }
5823                 StringBuilder sb = new StringBuilder();
5824                 Time tobj = new Time();
5825                 tobj.set(System.currentTimeMillis());
5826                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5827                 sb.append(": ");
5828                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5829                 sb.append(" since ");
5830                 sb.append(msg);
5831                 FileOutputStream fos = new FileOutputStream(tracesFile);
5832                 fos.write(sb.toString().getBytes());
5833                 if (app == null) {
5834                     fos.write("\n*** No application process!".getBytes());
5835                 }
5836                 fos.close();
5837                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5838             } catch (IOException e) {
5839                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5840                 return;
5841             }
5842
5843             if (app != null) {
5844                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5845                 firstPids.add(app.pid);
5846                 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5847             }
5848
5849             File lastTracesFile = null;
5850             File curTracesFile = null;
5851             for (int i=9; i>=0; i--) {
5852                 String name = String.format(Locale.US, "slow%02d.txt", i);
5853                 curTracesFile = new File(tracesDir, name);
5854                 if (curTracesFile.exists()) {
5855                     if (lastTracesFile != null) {
5856                         curTracesFile.renameTo(lastTracesFile);
5857                     } else {
5858                         curTracesFile.delete();
5859                     }
5860                 }
5861                 lastTracesFile = curTracesFile;
5862             }
5863             tracesFile.renameTo(curTracesFile);
5864             if (tracesTmp.exists()) {
5865                 tracesTmp.renameTo(tracesFile);
5866             }
5867         } finally {
5868             StrictMode.setThreadPolicy(oldPolicy);
5869         }
5870     }
5871
5872     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5873         if (!mLaunchWarningShown) {
5874             mLaunchWarningShown = true;
5875             mUiHandler.post(new Runnable() {
5876                 @Override
5877                 public void run() {
5878                     synchronized (ActivityManagerService.this) {
5879                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5880                         d.show();
5881                         mUiHandler.postDelayed(new Runnable() {
5882                             @Override
5883                             public void run() {
5884                                 synchronized (ActivityManagerService.this) {
5885                                     d.dismiss();
5886                                     mLaunchWarningShown = false;
5887                                 }
5888                             }
5889                         }, 4000);
5890                     }
5891                 }
5892             });
5893         }
5894     }
5895
5896     @Override
5897     public boolean clearApplicationUserData(final String packageName,
5898             final IPackageDataObserver observer, int userId) {
5899         enforceNotIsolatedCaller("clearApplicationUserData");
5900         int uid = Binder.getCallingUid();
5901         int pid = Binder.getCallingPid();
5902         final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5903                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5904
5905         final ApplicationInfo appInfo;
5906         final boolean isInstantApp;
5907
5908         long callingId = Binder.clearCallingIdentity();
5909         try {
5910             IPackageManager pm = AppGlobals.getPackageManager();
5911             synchronized(this) {
5912                 // Instant packages are not protected
5913                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5914                         resolvedUserId, packageName)) {
5915                     throw new SecurityException(
5916                             "Cannot clear data for a protected package: " + packageName);
5917                 }
5918
5919                 ApplicationInfo applicationInfo = null;
5920                 try {
5921                     applicationInfo = pm.getApplicationInfo(packageName,
5922                             MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5923                 } catch (RemoteException e) {
5924                     /* ignore */
5925                 }
5926                 appInfo = applicationInfo;
5927
5928                 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5929
5930                 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5931                         pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5932                     throw new SecurityException("PID " + pid + " does not have permission "
5933                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5934                             + " of package " + packageName);
5935                 }
5936
5937                 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5938                         .hasInstantApplicationMetadata(packageName, resolvedUserId);
5939                 final boolean isUninstalledAppWithoutInstantMetadata =
5940                         (appInfo == null && !hasInstantMetadata);
5941                 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5942                         || hasInstantMetadata;
5943                 final boolean canAccessInstantApps = checkComponentPermission(
5944                         permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5945                         == PackageManager.PERMISSION_GRANTED;
5946
5947                 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5948                         && !canAccessInstantApps)) {
5949                     Slog.w(TAG, "Invalid packageName: " + packageName);
5950                     if (observer != null) {
5951                         try {
5952                             observer.onRemoveCompleted(packageName, false);
5953                         } catch (RemoteException e) {
5954                             Slog.i(TAG, "Observer no longer exists.");
5955                         }
5956                     }
5957                     return false;
5958                 }
5959
5960                 if (appInfo != null) {
5961                     forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5962                     // Remove all tasks match the cleared application package and user
5963                     for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5964                         final TaskRecord tr = mRecentTasks.get(i);
5965                         final String taskPackageName =
5966                                 tr.getBaseIntent().getComponent().getPackageName();
5967                         if (tr.userId != resolvedUserId) continue;
5968                         if (!taskPackageName.equals(packageName)) continue;
5969                         mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5970                                 REMOVE_FROM_RECENTS);
5971                     }
5972                 }
5973             }
5974
5975             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5976                 @Override
5977                 public void onRemoveCompleted(String packageName, boolean succeeded)
5978                         throws RemoteException {
5979                     if (appInfo != null) {
5980                         synchronized (ActivityManagerService.this) {
5981                             finishForceStopPackageLocked(packageName, appInfo.uid);
5982                         }
5983                     }
5984                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5985                             Uri.fromParts("package", packageName, null));
5986                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5987                     intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5988                     intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5989                     if (isInstantApp) {
5990                         intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5991                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5992                                 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
5993                                 resolvedUserId);
5994                     } else {
5995                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5996                                 null, null, null, null, false, false, resolvedUserId);
5997                     }
5998
5999                     if (observer != null) {
6000                         observer.onRemoveCompleted(packageName, succeeded);
6001                     }
6002                 }
6003             };
6004
6005             try {
6006                 // Clear application user data
6007                 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6008
6009                 if (appInfo != null) {
6010                     synchronized (this) {
6011                         // Remove all permissions granted from/to this package
6012                         removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6013                     }
6014
6015                     // Reset notification settings.
6016                     INotificationManager inm = NotificationManager.getService();
6017                     inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6018                 }
6019             } catch (RemoteException e) {
6020             }
6021         } finally {
6022             Binder.restoreCallingIdentity(callingId);
6023         }
6024         return true;
6025     }
6026
6027     @Override
6028     public void killBackgroundProcesses(final String packageName, int userId) {
6029         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6030                 != PackageManager.PERMISSION_GRANTED &&
6031                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6032                         != PackageManager.PERMISSION_GRANTED) {
6033             String msg = "Permission Denial: killBackgroundProcesses() from pid="
6034                     + Binder.getCallingPid()
6035                     + ", uid=" + Binder.getCallingUid()
6036                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6037             Slog.w(TAG, msg);
6038             throw new SecurityException(msg);
6039         }
6040
6041         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6042                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6043         long callingId = Binder.clearCallingIdentity();
6044         try {
6045             IPackageManager pm = AppGlobals.getPackageManager();
6046             synchronized(this) {
6047                 int appId = -1;
6048                 try {
6049                     appId = UserHandle.getAppId(
6050                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6051                 } catch (RemoteException e) {
6052                 }
6053                 if (appId == -1) {
6054                     Slog.w(TAG, "Invalid packageName: " + packageName);
6055                     return;
6056                 }
6057                 killPackageProcessesLocked(packageName, appId, userId,
6058                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6059             }
6060         } finally {
6061             Binder.restoreCallingIdentity(callingId);
6062         }
6063     }
6064
6065     @Override
6066     public void killAllBackgroundProcesses() {
6067         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6068                 != PackageManager.PERMISSION_GRANTED) {
6069             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6070                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6071                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6072             Slog.w(TAG, msg);
6073             throw new SecurityException(msg);
6074         }
6075
6076         final long callingId = Binder.clearCallingIdentity();
6077         try {
6078             synchronized (this) {
6079                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6080                 final int NP = mProcessNames.getMap().size();
6081                 for (int ip = 0; ip < NP; ip++) {
6082                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6083                     final int NA = apps.size();
6084                     for (int ia = 0; ia < NA; ia++) {
6085                         final ProcessRecord app = apps.valueAt(ia);
6086                         if (app.persistent) {
6087                             // We don't kill persistent processes.
6088                             continue;
6089                         }
6090                         if (app.removed) {
6091                             procs.add(app);
6092                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6093                             app.removed = true;
6094                             procs.add(app);
6095                         }
6096                     }
6097                 }
6098
6099                 final int N = procs.size();
6100                 for (int i = 0; i < N; i++) {
6101                     removeProcessLocked(procs.get(i), false, true, "kill all background");
6102                 }
6103
6104                 mAllowLowerMemLevel = true;
6105
6106                 updateOomAdjLocked();
6107                 doLowMemReportIfNeededLocked(null);
6108             }
6109         } finally {
6110             Binder.restoreCallingIdentity(callingId);
6111         }
6112     }
6113
6114     /**
6115      * Kills all background processes, except those matching any of the
6116      * specified properties.
6117      *
6118      * @param minTargetSdk the target SDK version at or above which to preserve
6119      *                     processes, or {@code -1} to ignore the target SDK
6120      * @param maxProcState the process state at or below which to preserve
6121      *                     processes, or {@code -1} to ignore the process state
6122      */
6123     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6124         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6125                 != PackageManager.PERMISSION_GRANTED) {
6126             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6127                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6128                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6129             Slog.w(TAG, msg);
6130             throw new SecurityException(msg);
6131         }
6132
6133         final long callingId = Binder.clearCallingIdentity();
6134         try {
6135             synchronized (this) {
6136                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6137                 final int NP = mProcessNames.getMap().size();
6138                 for (int ip = 0; ip < NP; ip++) {
6139                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6140                     final int NA = apps.size();
6141                     for (int ia = 0; ia < NA; ia++) {
6142                         final ProcessRecord app = apps.valueAt(ia);
6143                         if (app.removed) {
6144                             procs.add(app);
6145                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6146                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6147                             app.removed = true;
6148                             procs.add(app);
6149                         }
6150                     }
6151                 }
6152
6153                 final int N = procs.size();
6154                 for (int i = 0; i < N; i++) {
6155                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
6156                 }
6157             }
6158         } finally {
6159             Binder.restoreCallingIdentity(callingId);
6160         }
6161     }
6162
6163     @Override
6164     public void forceStopPackage(final String packageName, int userId) {
6165         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6166                 != PackageManager.PERMISSION_GRANTED) {
6167             String msg = "Permission Denial: forceStopPackage() from pid="
6168                     + Binder.getCallingPid()
6169                     + ", uid=" + Binder.getCallingUid()
6170                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6171             Slog.w(TAG, msg);
6172             throw new SecurityException(msg);
6173         }
6174         final int callingPid = Binder.getCallingPid();
6175         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6176                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6177         long callingId = Binder.clearCallingIdentity();
6178         try {
6179             IPackageManager pm = AppGlobals.getPackageManager();
6180             synchronized(this) {
6181                 int[] users = userId == UserHandle.USER_ALL
6182                         ? mUserController.getUsers() : new int[] { userId };
6183                 for (int user : users) {
6184                     int pkgUid = -1;
6185                     try {
6186                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6187                                 user);
6188                     } catch (RemoteException e) {
6189                     }
6190                     if (pkgUid == -1) {
6191                         Slog.w(TAG, "Invalid packageName: " + packageName);
6192                         continue;
6193                     }
6194                     try {
6195                         pm.setPackageStoppedState(packageName, true, user);
6196                     } catch (RemoteException e) {
6197                     } catch (IllegalArgumentException e) {
6198                         Slog.w(TAG, "Failed trying to unstop package "
6199                                 + packageName + ": " + e);
6200                     }
6201                     if (mUserController.isUserRunningLocked(user, 0)) {
6202                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6203                         finishForceStopPackageLocked(packageName, pkgUid);
6204                     }
6205                 }
6206             }
6207         } finally {
6208             Binder.restoreCallingIdentity(callingId);
6209         }
6210     }
6211
6212     @Override
6213     public void addPackageDependency(String packageName) {
6214         synchronized (this) {
6215             int callingPid = Binder.getCallingPid();
6216             if (callingPid == myPid()) {
6217                 //  Yeah, um, no.
6218                 return;
6219             }
6220             ProcessRecord proc;
6221             synchronized (mPidsSelfLocked) {
6222                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6223             }
6224             if (proc != null) {
6225                 if (proc.pkgDeps == null) {
6226                     proc.pkgDeps = new ArraySet<String>(1);
6227                 }
6228                 proc.pkgDeps.add(packageName);
6229             }
6230         }
6231     }
6232
6233     /*
6234      * The pkg name and app id have to be specified.
6235      */
6236     @Override
6237     public void killApplication(String pkg, int appId, int userId, String reason) {
6238         if (pkg == null) {
6239             return;
6240         }
6241         // Make sure the uid is valid.
6242         if (appId < 0) {
6243             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6244             return;
6245         }
6246         int callerUid = Binder.getCallingUid();
6247         // Only the system server can kill an application
6248         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6249             // Post an aysnc message to kill the application
6250             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6251             msg.arg1 = appId;
6252             msg.arg2 = userId;
6253             Bundle bundle = new Bundle();
6254             bundle.putString("pkg", pkg);
6255             bundle.putString("reason", reason);
6256             msg.obj = bundle;
6257             mHandler.sendMessage(msg);
6258         } else {
6259             throw new SecurityException(callerUid + " cannot kill pkg: " +
6260                     pkg);
6261         }
6262     }
6263
6264     @Override
6265     public void closeSystemDialogs(String reason) {
6266         enforceNotIsolatedCaller("closeSystemDialogs");
6267
6268         final int pid = Binder.getCallingPid();
6269         final int uid = Binder.getCallingUid();
6270         final long origId = Binder.clearCallingIdentity();
6271         try {
6272             synchronized (this) {
6273                 // Only allow this from foreground processes, so that background
6274                 // applications can't abuse it to prevent system UI from being shown.
6275                 if (uid >= FIRST_APPLICATION_UID) {
6276                     ProcessRecord proc;
6277                     synchronized (mPidsSelfLocked) {
6278                         proc = mPidsSelfLocked.get(pid);
6279                     }
6280                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6281                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6282                                 + " from background process " + proc);
6283                         return;
6284                     }
6285                 }
6286                 closeSystemDialogsLocked(reason);
6287             }
6288         } finally {
6289             Binder.restoreCallingIdentity(origId);
6290         }
6291     }
6292
6293     void closeSystemDialogsLocked(String reason) {
6294         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6295         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6296                 | Intent.FLAG_RECEIVER_FOREGROUND);
6297         if (reason != null) {
6298             intent.putExtra("reason", reason);
6299         }
6300         mWindowManager.closeSystemDialogs(reason);
6301
6302         mStackSupervisor.closeSystemDialogsLocked();
6303
6304         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6305                 AppOpsManager.OP_NONE, null, false, false,
6306                 -1, SYSTEM_UID, UserHandle.USER_ALL);
6307     }
6308
6309     @Override
6310     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6311         enforceNotIsolatedCaller("getProcessMemoryInfo");
6312         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6313         for (int i=pids.length-1; i>=0; i--) {
6314             ProcessRecord proc;
6315             int oomAdj;
6316             synchronized (this) {
6317                 synchronized (mPidsSelfLocked) {
6318                     proc = mPidsSelfLocked.get(pids[i]);
6319                     oomAdj = proc != null ? proc.setAdj : 0;
6320                 }
6321             }
6322             infos[i] = new Debug.MemoryInfo();
6323             Debug.getMemoryInfo(pids[i], infos[i]);
6324             if (proc != null) {
6325                 synchronized (this) {
6326                     if (proc.thread != null && proc.setAdj == oomAdj) {
6327                         // Record this for posterity if the process has been stable.
6328                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6329                                 infos[i].getTotalUss(), false, proc.pkgList);
6330                     }
6331                 }
6332             }
6333         }
6334         return infos;
6335     }
6336
6337     @Override
6338     public long[] getProcessPss(int[] pids) {
6339         enforceNotIsolatedCaller("getProcessPss");
6340         long[] pss = new long[pids.length];
6341         for (int i=pids.length-1; i>=0; i--) {
6342             ProcessRecord proc;
6343             int oomAdj;
6344             synchronized (this) {
6345                 synchronized (mPidsSelfLocked) {
6346                     proc = mPidsSelfLocked.get(pids[i]);
6347                     oomAdj = proc != null ? proc.setAdj : 0;
6348                 }
6349             }
6350             long[] tmpUss = new long[1];
6351             pss[i] = Debug.getPss(pids[i], tmpUss, null);
6352             if (proc != null) {
6353                 synchronized (this) {
6354                     if (proc.thread != null && proc.setAdj == oomAdj) {
6355                         // Record this for posterity if the process has been stable.
6356                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6357                     }
6358                 }
6359             }
6360         }
6361         return pss;
6362     }
6363
6364     @Override
6365     public void killApplicationProcess(String processName, int uid) {
6366         if (processName == null) {
6367             return;
6368         }
6369
6370         int callerUid = Binder.getCallingUid();
6371         // Only the system server can kill an application
6372         if (callerUid == SYSTEM_UID) {
6373             synchronized (this) {
6374                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6375                 if (app != null && app.thread != null) {
6376                     try {
6377                         app.thread.scheduleSuicide();
6378                     } catch (RemoteException e) {
6379                         // If the other end already died, then our work here is done.
6380                     }
6381                 } else {
6382                     Slog.w(TAG, "Process/uid not found attempting kill of "
6383                             + processName + " / " + uid);
6384                 }
6385             }
6386         } else {
6387             throw new SecurityException(callerUid + " cannot kill app process: " +
6388                     processName);
6389         }
6390     }
6391
6392     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6393         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6394                 false, true, false, false, UserHandle.getUserId(uid), reason);
6395     }
6396
6397     private void finishForceStopPackageLocked(final String packageName, int uid) {
6398         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6399                 Uri.fromParts("package", packageName, null));
6400         if (!mProcessesReady) {
6401             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6402                     | Intent.FLAG_RECEIVER_FOREGROUND);
6403         }
6404         intent.putExtra(Intent.EXTRA_UID, uid);
6405         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6406         broadcastIntentLocked(null, null, intent,
6407                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6408                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6409     }
6410
6411
6412     private final boolean killPackageProcessesLocked(String packageName, int appId,
6413             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6414             boolean doit, boolean evenPersistent, String reason) {
6415         ArrayList<ProcessRecord> procs = new ArrayList<>();
6416
6417         // Remove all processes this package may have touched: all with the
6418         // same UID (except for the system or root user), and all whose name
6419         // matches the package name.
6420         final int NP = mProcessNames.getMap().size();
6421         for (int ip=0; ip<NP; ip++) {
6422             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6423             final int NA = apps.size();
6424             for (int ia=0; ia<NA; ia++) {
6425                 ProcessRecord app = apps.valueAt(ia);
6426                 if (app.persistent && !evenPersistent) {
6427                     // we don't kill persistent processes
6428                     continue;
6429                 }
6430                 if (app.removed) {
6431                     if (doit) {
6432                         procs.add(app);
6433                     }
6434                     continue;
6435                 }
6436
6437                 // Skip process if it doesn't meet our oom adj requirement.
6438                 if (app.setAdj < minOomAdj) {
6439                     continue;
6440                 }
6441
6442                 // If no package is specified, we call all processes under the
6443                 // give user id.
6444                 if (packageName == null) {
6445                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6446                         continue;
6447                     }
6448                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6449                         continue;
6450                     }
6451                 // Package has been specified, we want to hit all processes
6452                 // that match it.  We need to qualify this by the processes
6453                 // that are running under the specified app and user ID.
6454                 } else {
6455                     final boolean isDep = app.pkgDeps != null
6456                             && app.pkgDeps.contains(packageName);
6457                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6458                         continue;
6459                     }
6460                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6461                         continue;
6462                     }
6463                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6464                         continue;
6465                     }
6466                 }
6467
6468                 // Process has passed all conditions, kill it!
6469                 if (!doit) {
6470                     return true;
6471                 }
6472                 app.removed = true;
6473                 procs.add(app);
6474             }
6475         }
6476
6477         int N = procs.size();
6478         for (int i=0; i<N; i++) {
6479             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6480         }
6481         updateOomAdjLocked();
6482         return N > 0;
6483     }
6484
6485     private void cleanupDisabledPackageComponentsLocked(
6486             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6487
6488         Set<String> disabledClasses = null;
6489         boolean packageDisabled = false;
6490         IPackageManager pm = AppGlobals.getPackageManager();
6491
6492         if (changedClasses == null) {
6493             // Nothing changed...
6494             return;
6495         }
6496
6497         // Determine enable/disable state of the package and its components.
6498         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6499         for (int i = changedClasses.length - 1; i >= 0; i--) {
6500             final String changedClass = changedClasses[i];
6501
6502             if (changedClass.equals(packageName)) {
6503                 try {
6504                     // Entire package setting changed
6505                     enabled = pm.getApplicationEnabledSetting(packageName,
6506                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6507                 } catch (Exception e) {
6508                     // No such package/component; probably racing with uninstall.  In any
6509                     // event it means we have nothing further to do here.
6510                     return;
6511                 }
6512                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6513                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6514                 if (packageDisabled) {
6515                     // Entire package is disabled.
6516                     // No need to continue to check component states.
6517                     disabledClasses = null;
6518                     break;
6519                 }
6520             } else {
6521                 try {
6522                     enabled = pm.getComponentEnabledSetting(
6523                             new ComponentName(packageName, changedClass),
6524                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6525                 } catch (Exception e) {
6526                     // As above, probably racing with uninstall.
6527                     return;
6528                 }
6529                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6530                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6531                     if (disabledClasses == null) {
6532                         disabledClasses = new ArraySet<>(changedClasses.length);
6533                     }
6534                     disabledClasses.add(changedClass);
6535                 }
6536             }
6537         }
6538
6539         if (!packageDisabled && disabledClasses == null) {
6540             // Nothing to do here...
6541             return;
6542         }
6543
6544         // Clean-up disabled activities.
6545         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6546                 packageName, disabledClasses, true, false, userId) && mBooted) {
6547             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6548             mStackSupervisor.scheduleIdleLocked();
6549         }
6550
6551         // Clean-up disabled tasks
6552         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6553
6554         // Clean-up disabled services.
6555         mServices.bringDownDisabledPackageServicesLocked(
6556                 packageName, disabledClasses, userId, false, killProcess, true);
6557
6558         // Clean-up disabled providers.
6559         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6560         mProviderMap.collectPackageProvidersLocked(
6561                 packageName, disabledClasses, true, false, userId, providers);
6562         for (int i = providers.size() - 1; i >= 0; i--) {
6563             removeDyingProviderLocked(null, providers.get(i), true);
6564         }
6565
6566         // Clean-up disabled broadcast receivers.
6567         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6568             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6569                     packageName, disabledClasses, userId, true);
6570         }
6571
6572     }
6573
6574     final boolean clearBroadcastQueueForUserLocked(int userId) {
6575         boolean didSomething = false;
6576         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6577             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6578                     null, null, userId, true);
6579         }
6580         return didSomething;
6581     }
6582
6583     final boolean forceStopPackageLocked(String packageName, int appId,
6584             boolean callerWillRestart, boolean purgeCache, boolean doit,
6585             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6586         int i;
6587
6588         if (userId == UserHandle.USER_ALL && packageName == null) {
6589             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6590         }
6591
6592         if (appId < 0 && packageName != null) {
6593             try {
6594                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6595                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6596             } catch (RemoteException e) {
6597             }
6598         }
6599
6600         if (doit) {
6601             if (packageName != null) {
6602                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6603                         + " user=" + userId + ": " + reason);
6604             } else {
6605                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6606             }
6607
6608             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6609         }
6610
6611         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6612                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6613                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6614
6615         didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6616
6617         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6618                 packageName, null, doit, evenPersistent, userId)) {
6619             if (!doit) {
6620                 return true;
6621             }
6622             didSomething = true;
6623         }
6624
6625         if (mServices.bringDownDisabledPackageServicesLocked(
6626                 packageName, null, userId, evenPersistent, true, doit)) {
6627             if (!doit) {
6628                 return true;
6629             }
6630             didSomething = true;
6631         }
6632
6633         if (packageName == null) {
6634             // Remove all sticky broadcasts from this user.
6635             mStickyBroadcasts.remove(userId);
6636         }
6637
6638         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6639         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6640                 userId, providers)) {
6641             if (!doit) {
6642                 return true;
6643             }
6644             didSomething = true;
6645         }
6646         for (i = providers.size() - 1; i >= 0; i--) {
6647             removeDyingProviderLocked(null, providers.get(i), true);
6648         }
6649
6650         // Remove transient permissions granted from/to this package/user
6651         removeUriPermissionsForPackageLocked(packageName, userId, false);
6652
6653         if (doit) {
6654             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6655                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6656                         packageName, null, userId, doit);
6657             }
6658         }
6659
6660         if (packageName == null || uninstalling) {
6661             // Remove pending intents.  For now we only do this when force
6662             // stopping users, because we have some problems when doing this
6663             // for packages -- app widgets are not currently cleaned up for
6664             // such packages, so they can be left with bad pending intents.
6665             if (mIntentSenderRecords.size() > 0) {
6666                 Iterator<WeakReference<PendingIntentRecord>> it
6667                         = mIntentSenderRecords.values().iterator();
6668                 while (it.hasNext()) {
6669                     WeakReference<PendingIntentRecord> wpir = it.next();
6670                     if (wpir == null) {
6671                         it.remove();
6672                         continue;
6673                     }
6674                     PendingIntentRecord pir = wpir.get();
6675                     if (pir == null) {
6676                         it.remove();
6677                         continue;
6678                     }
6679                     if (packageName == null) {
6680                         // Stopping user, remove all objects for the user.
6681                         if (pir.key.userId != userId) {
6682                             // Not the same user, skip it.
6683                             continue;
6684                         }
6685                     } else {
6686                         if (UserHandle.getAppId(pir.uid) != appId) {
6687                             // Different app id, skip it.
6688                             continue;
6689                         }
6690                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6691                             // Different user, skip it.
6692                             continue;
6693                         }
6694                         if (!pir.key.packageName.equals(packageName)) {
6695                             // Different package, skip it.
6696                             continue;
6697                         }
6698                     }
6699                     if (!doit) {
6700                         return true;
6701                     }
6702                     didSomething = true;
6703                     it.remove();
6704                     makeIntentSenderCanceledLocked(pir);
6705                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6706                         pir.key.activity.pendingResults.remove(pir.ref);
6707                     }
6708                 }
6709             }
6710         }
6711
6712         if (doit) {
6713             if (purgeCache && packageName != null) {
6714                 AttributeCache ac = AttributeCache.instance();
6715                 if (ac != null) {
6716                     ac.removePackage(packageName);
6717                 }
6718             }
6719             if (mBooted) {
6720                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6721                 mStackSupervisor.scheduleIdleLocked();
6722             }
6723         }
6724
6725         return didSomething;
6726     }
6727
6728     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6729         return removeProcessNameLocked(name, uid, null);
6730     }
6731
6732     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6733             final ProcessRecord expecting) {
6734         ProcessRecord old = mProcessNames.get(name, uid);
6735         // Only actually remove when the currently recorded value matches the
6736         // record that we expected; if it doesn't match then we raced with a
6737         // newly created process and we don't want to destroy the new one.
6738         if ((expecting == null) || (old == expecting)) {
6739             mProcessNames.remove(name, uid);
6740         }
6741         if (old != null && old.uidRecord != null) {
6742             old.uidRecord.numProcs--;
6743             if (old.uidRecord.numProcs == 0) {
6744                 // No more processes using this uid, tell clients it is gone.
6745                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6746                         "No more processes in " + old.uidRecord);
6747                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6748                 EventLogTags.writeAmUidStopped(uid);
6749                 mActiveUids.remove(uid);
6750                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6751             }
6752             old.uidRecord = null;
6753         }
6754         mIsolatedProcesses.remove(uid);
6755         return old;
6756     }
6757
6758     private final void addProcessNameLocked(ProcessRecord proc) {
6759         // We shouldn't already have a process under this name, but just in case we
6760         // need to clean up whatever may be there now.
6761         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6762         if (old == proc && proc.persistent) {
6763             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6764             Slog.w(TAG, "Re-adding persistent process " + proc);
6765         } else if (old != null) {
6766             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6767         }
6768         UidRecord uidRec = mActiveUids.get(proc.uid);
6769         if (uidRec == null) {
6770             uidRec = new UidRecord(proc.uid);
6771             // This is the first appearance of the uid, report it now!
6772             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6773                     "Creating new process uid: " + uidRec);
6774             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6775                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6776                 uidRec.setWhitelist = uidRec.curWhitelist = true;
6777             }
6778             uidRec.updateHasInternetPermission();
6779             mActiveUids.put(proc.uid, uidRec);
6780             EventLogTags.writeAmUidRunning(uidRec.uid);
6781             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6782         }
6783         proc.uidRecord = uidRec;
6784
6785         // Reset render thread tid if it was already set, so new process can set it again.
6786         proc.renderThreadTid = 0;
6787         uidRec.numProcs++;
6788         mProcessNames.put(proc.processName, proc.uid, proc);
6789         if (proc.isolated) {
6790             mIsolatedProcesses.put(proc.uid, proc);
6791         }
6792     }
6793
6794     boolean removeProcessLocked(ProcessRecord app,
6795             boolean callerWillRestart, boolean allowRestart, String reason) {
6796         final String name = app.processName;
6797         final int uid = app.uid;
6798         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6799             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6800
6801         ProcessRecord old = mProcessNames.get(name, uid);
6802         if (old != app) {
6803             // This process is no longer active, so nothing to do.
6804             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6805             return false;
6806         }
6807         removeProcessNameLocked(name, uid);
6808         if (mHeavyWeightProcess == app) {
6809             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6810                     mHeavyWeightProcess.userId, 0));
6811             mHeavyWeightProcess = null;
6812         }
6813         boolean needRestart = false;
6814         if (app.pid > 0 && app.pid != MY_PID) {
6815             int pid = app.pid;
6816             synchronized (mPidsSelfLocked) {
6817                 mPidsSelfLocked.remove(pid);
6818                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6819             }
6820             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6821             boolean willRestart = false;
6822             if (app.persistent && !app.isolated) {
6823                 if (!callerWillRestart) {
6824                     willRestart = true;
6825                 } else {
6826                     needRestart = true;
6827                 }
6828             }
6829             app.kill(reason, true);
6830             if (app.isolated) {
6831                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6832                 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6833             }
6834             handleAppDiedLocked(app, willRestart, allowRestart);
6835             if (willRestart) {
6836                 removeLruProcessLocked(app);
6837                 addAppLocked(app.info, null, false, null /* ABI override */);
6838             }
6839         } else {
6840             mRemovedProcesses.add(app);
6841         }
6842
6843         return needRestart;
6844     }
6845
6846     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6847         cleanupAppInLaunchingProvidersLocked(app, true);
6848         removeProcessLocked(app, false, true, "timeout publishing content providers");
6849     }
6850
6851     private final void processStartTimedOutLocked(ProcessRecord app) {
6852         final int pid = app.pid;
6853         boolean gone = false;
6854         synchronized (mPidsSelfLocked) {
6855             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6856             if (knownApp != null && knownApp.thread == null) {
6857                 mPidsSelfLocked.remove(pid);
6858                 gone = true;
6859             }
6860         }
6861
6862         if (gone) {
6863             Slog.w(TAG, "Process " + app + " failed to attach");
6864             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6865                     pid, app.uid, app.processName);
6866             removeProcessNameLocked(app.processName, app.uid);
6867             if (mHeavyWeightProcess == app) {
6868                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6869                         mHeavyWeightProcess.userId, 0));
6870                 mHeavyWeightProcess = null;
6871             }
6872             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6873             // Take care of any launching providers waiting for this process.
6874             cleanupAppInLaunchingProvidersLocked(app, true);
6875             // Take care of any services that are waiting for the process.
6876             mServices.processStartTimedOutLocked(app);
6877             app.kill("start timeout", true);
6878             if (app.isolated) {
6879                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6880             }
6881             removeLruProcessLocked(app);
6882             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6883                 Slog.w(TAG, "Unattached app died before backup, skipping");
6884                 mHandler.post(new Runnable() {
6885                 @Override
6886                     public void run(){
6887                         try {
6888                             IBackupManager bm = IBackupManager.Stub.asInterface(
6889                                     ServiceManager.getService(Context.BACKUP_SERVICE));
6890                             bm.agentDisconnected(app.info.packageName);
6891                         } catch (RemoteException e) {
6892                             // Can't happen; the backup manager is local
6893                         }
6894                     }
6895                 });
6896             }
6897             if (isPendingBroadcastProcessLocked(pid)) {
6898                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6899                 skipPendingBroadcastLocked(pid);
6900             }
6901         } else {
6902             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6903         }
6904     }
6905
6906     private final boolean attachApplicationLocked(IApplicationThread thread,
6907             int pid) {
6908
6909         // Find the application record that is being attached...  either via
6910         // the pid if we are running in multiple processes, or just pull the
6911         // next app record if we are emulating process with anonymous threads.
6912         ProcessRecord app;
6913         long startTime = SystemClock.uptimeMillis();
6914         if (pid != MY_PID && pid >= 0) {
6915             synchronized (mPidsSelfLocked) {
6916                 app = mPidsSelfLocked.get(pid);
6917             }
6918         } else {
6919             app = null;
6920         }
6921
6922         if (app == null) {
6923             Slog.w(TAG, "No pending application record for pid " + pid
6924                     + " (IApplicationThread " + thread + "); dropping process");
6925             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6926             if (pid > 0 && pid != MY_PID) {
6927                 killProcessQuiet(pid);
6928                 //TODO: killProcessGroup(app.info.uid, pid);
6929             } else {
6930                 try {
6931                     thread.scheduleExit();
6932                 } catch (Exception e) {
6933                     // Ignore exceptions.
6934                 }
6935             }
6936             return false;
6937         }
6938
6939         // If this application record is still attached to a previous
6940         // process, clean it up now.
6941         if (app.thread != null) {
6942             handleAppDiedLocked(app, true, true);
6943         }
6944
6945         // Tell the process all about itself.
6946
6947         if (DEBUG_ALL) Slog.v(
6948                 TAG, "Binding process pid " + pid + " to record " + app);
6949
6950         final String processName = app.processName;
6951         try {
6952             AppDeathRecipient adr = new AppDeathRecipient(
6953                     app, pid, thread);
6954             thread.asBinder().linkToDeath(adr, 0);
6955             app.deathRecipient = adr;
6956         } catch (RemoteException e) {
6957             app.resetPackageList(mProcessStats);
6958             startProcessLocked(app, "link fail", processName);
6959             return false;
6960         }
6961
6962         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6963
6964         app.makeActive(thread, mProcessStats);
6965         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6966         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6967         app.forcingToImportant = null;
6968         updateProcessForegroundLocked(app, false, false);
6969         app.hasShownUi = false;
6970         app.debugging = false;
6971         app.cached = false;
6972         app.killedByAm = false;
6973         app.killed = false;
6974
6975
6976         // We carefully use the same state that PackageManager uses for
6977         // filtering, since we use this flag to decide if we need to install
6978         // providers when user is unlocked later
6979         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6980
6981         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6982
6983         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6984         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6985
6986         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6987             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6988             msg.obj = app;
6989             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6990         }
6991
6992         checkTime(startTime, "attachApplicationLocked: before bindApplication");
6993
6994         if (!normalMode) {
6995             Slog.i(TAG, "Launching preboot mode app: " + app);
6996         }
6997
6998         if (DEBUG_ALL) Slog.v(
6999             TAG, "New app record " + app
7000             + " thread=" + thread.asBinder() + " pid=" + pid);
7001         try {
7002             int testMode = ApplicationThreadConstants.DEBUG_OFF;
7003             if (mDebugApp != null && mDebugApp.equals(processName)) {
7004                 testMode = mWaitForDebugger
7005                     ? ApplicationThreadConstants.DEBUG_WAIT
7006                     : ApplicationThreadConstants.DEBUG_ON;
7007                 app.debugging = true;
7008                 if (mDebugTransient) {
7009                     mDebugApp = mOrigDebugApp;
7010                     mWaitForDebugger = mOrigWaitForDebugger;
7011                 }
7012             }
7013
7014             ProfilerInfo profilerInfo = null;
7015             String agent = null;
7016             if (mProfileApp != null && mProfileApp.equals(processName)) {
7017                 mProfileProc = app;
7018                 profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ?
7019                         new ProfilerInfo(mProfilerInfo) : null;
7020                 agent = mProfilerInfo != null ? mProfilerInfo.agent : null;
7021             } else if (app.instr != null && app.instr.mProfileFile != null) {
7022                 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7023                         null);
7024             }
7025
7026             boolean enableTrackAllocation = false;
7027             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7028                 enableTrackAllocation = true;
7029                 mTrackAllocationApp = null;
7030             }
7031
7032             // If the app is being launched for restore or full backup, set it up specially
7033             boolean isRestrictedBackupMode = false;
7034             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7035                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7036                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7037                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7038                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7039             }
7040
7041             if (app.instr != null) {
7042                 notifyPackageUse(app.instr.mClass.getPackageName(),
7043                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7044             }
7045             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7046                     + processName + " with config " + getGlobalConfiguration());
7047             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7048             app.compat = compatibilityInfoForPackageLocked(appInfo);
7049
7050             if (profilerInfo != null && profilerInfo.profileFd != null) {
7051                 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7052             }
7053
7054             // We deprecated Build.SERIAL and it is not accessible to
7055             // apps that target the v2 security sandbox. Since access to
7056             // the serial is now behind a permission we push down the value.
7057             String buildSerial = appInfo.targetSandboxVersion < 2
7058                     ? sTheRealBuildSerial : Build.UNKNOWN;
7059
7060             // Check if this is a secondary process that should be incorporated into some
7061             // currently active instrumentation.  (Note we do this AFTER all of the profiling
7062             // stuff above because profiling can currently happen only in the primary
7063             // instrumentation process.)
7064             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7065                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7066                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7067                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7068                         if (aInstr.mTargetProcesses.length == 0) {
7069                             // This is the wildcard mode, where every process brought up for
7070                             // the target instrumentation should be included.
7071                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7072                                 app.instr = aInstr;
7073                                 aInstr.mRunningProcesses.add(app);
7074                             }
7075                         } else {
7076                             for (String proc : aInstr.mTargetProcesses) {
7077                                 if (proc.equals(app.processName)) {
7078                                     app.instr = aInstr;
7079                                     aInstr.mRunningProcesses.add(app);
7080                                     break;
7081                                 }
7082                             }
7083                         }
7084                     }
7085                 }
7086             }
7087
7088             // If we were asked to attach an agent on startup, do so now, before we're binding
7089             // application code.
7090             if (agent != null) {
7091                 thread.attachAgent(agent);
7092             }
7093
7094             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7095             mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7096             if (app.instr != null) {
7097                 thread.bindApplication(processName, appInfo, providers,
7098                         app.instr.mClass,
7099                         profilerInfo, app.instr.mArguments,
7100                         app.instr.mWatcher,
7101                         app.instr.mUiAutomationConnection, testMode,
7102                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7103                         isRestrictedBackupMode || !normalMode, app.persistent,
7104                         new Configuration(getGlobalConfiguration()), app.compat,
7105                         getCommonServicesLocked(app.isolated),
7106                         mCoreSettingsObserver.getCoreSettingsLocked(),
7107                         buildSerial);
7108             } else {
7109                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7110                         null, null, null, testMode,
7111                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7112                         isRestrictedBackupMode || !normalMode, app.persistent,
7113                         new Configuration(getGlobalConfiguration()), app.compat,
7114                         getCommonServicesLocked(app.isolated),
7115                         mCoreSettingsObserver.getCoreSettingsLocked(),
7116                         buildSerial);
7117             }
7118
7119             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7120             updateLruProcessLocked(app, false, null);
7121             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7122             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7123         } catch (Exception e) {
7124             // todo: Yikes!  What should we do?  For now we will try to
7125             // start another process, but that could easily get us in
7126             // an infinite loop of restarting processes...
7127             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7128
7129             app.resetPackageList(mProcessStats);
7130             app.unlinkDeathRecipient();
7131             startProcessLocked(app, "bind fail", processName);
7132             return false;
7133         }
7134
7135         // Remove this record from the list of starting applications.
7136         mPersistentStartingProcesses.remove(app);
7137         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7138                 "Attach application locked removing on hold: " + app);
7139         mProcessesOnHold.remove(app);
7140
7141         boolean badApp = false;
7142         boolean didSomething = false;
7143
7144         // See if the top visible activity is waiting to run in this process...
7145         if (normalMode) {
7146             try {
7147                 if (mStackSupervisor.attachApplicationLocked(app)) {
7148                     didSomething = true;
7149                 }
7150             } catch (Exception e) {
7151                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7152                 badApp = true;
7153             }
7154         }
7155
7156         // Find any services that should be running in this process...
7157         if (!badApp) {
7158             try {
7159                 didSomething |= mServices.attachApplicationLocked(app, processName);
7160                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7161             } catch (Exception e) {
7162                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7163                 badApp = true;
7164             }
7165         }
7166
7167         // Check if a next-broadcast receiver is in this process...
7168         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7169             try {
7170                 didSomething |= sendPendingBroadcastsLocked(app);
7171                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7172             } catch (Exception e) {
7173                 // If the app died trying to launch the receiver we declare it 'bad'
7174                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7175                 badApp = true;
7176             }
7177         }
7178
7179         // Check whether the next backup agent is in this process...
7180         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7181             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7182                     "New app is backup target, launching agent for " + app);
7183             notifyPackageUse(mBackupTarget.appInfo.packageName,
7184                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7185             try {
7186                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7187                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7188                         mBackupTarget.backupMode);
7189             } catch (Exception e) {
7190                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7191                 badApp = true;
7192             }
7193         }
7194
7195         if (badApp) {
7196             app.kill("error during init", true);
7197             handleAppDiedLocked(app, false, true);
7198             return false;
7199         }
7200
7201         if (!didSomething) {
7202             updateOomAdjLocked();
7203             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7204         }
7205
7206         return true;
7207     }
7208
7209     @Override
7210     public final void attachApplication(IApplicationThread thread) {
7211         synchronized (this) {
7212             int callingPid = Binder.getCallingPid();
7213             final long origId = Binder.clearCallingIdentity();
7214             attachApplicationLocked(thread, callingPid);
7215             Binder.restoreCallingIdentity(origId);
7216         }
7217     }
7218
7219     @Override
7220     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7221         final long origId = Binder.clearCallingIdentity();
7222         synchronized (this) {
7223             ActivityStack stack = ActivityRecord.getStackLocked(token);
7224             if (stack != null) {
7225                 ActivityRecord r =
7226                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7227                                 false /* processPausingActivities */, config);
7228                 if (stopProfiling) {
7229                     if ((mProfileProc == r.app) && mProfilerInfo != null) {
7230                         clearProfilerLocked();
7231                     }
7232                 }
7233             }
7234         }
7235         Binder.restoreCallingIdentity(origId);
7236     }
7237
7238     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7239         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7240                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7241     }
7242
7243     void enableScreenAfterBoot() {
7244         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7245                 SystemClock.uptimeMillis());
7246         mWindowManager.enableScreenAfterBoot();
7247
7248         synchronized (this) {
7249             updateEventDispatchingLocked();
7250         }
7251     }
7252
7253     @Override
7254     public void showBootMessage(final CharSequence msg, final boolean always) {
7255         if (Binder.getCallingUid() != myUid()) {
7256             throw new SecurityException();
7257         }
7258         mWindowManager.showBootMessage(msg, always);
7259     }
7260
7261     @Override
7262     public void keyguardGoingAway(int flags) {
7263         enforceNotIsolatedCaller("keyguardGoingAway");
7264         final long token = Binder.clearCallingIdentity();
7265         try {
7266             synchronized (this) {
7267                 mKeyguardController.keyguardGoingAway(flags);
7268             }
7269         } finally {
7270             Binder.restoreCallingIdentity(token);
7271         }
7272     }
7273
7274     /**
7275      * @return whther the keyguard is currently locked.
7276      */
7277     boolean isKeyguardLocked() {
7278         return mKeyguardController.isKeyguardLocked();
7279     }
7280
7281     final void finishBooting() {
7282         synchronized (this) {
7283             if (!mBootAnimationComplete) {
7284                 mCallFinishBooting = true;
7285                 return;
7286             }
7287             mCallFinishBooting = false;
7288         }
7289
7290         ArraySet<String> completedIsas = new ArraySet<String>();
7291         for (String abi : Build.SUPPORTED_ABIS) {
7292             zygoteProcess.establishZygoteConnectionForAbi(abi);
7293             final String instructionSet = VMRuntime.getInstructionSet(abi);
7294             if (!completedIsas.contains(instructionSet)) {
7295                 try {
7296                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7297                 } catch (InstallerException e) {
7298                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7299                             e.getMessage() +")");
7300                 }
7301                 completedIsas.add(instructionSet);
7302             }
7303         }
7304
7305         IntentFilter pkgFilter = new IntentFilter();
7306         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7307         pkgFilter.addDataScheme("package");
7308         mContext.registerReceiver(new BroadcastReceiver() {
7309             @Override
7310             public void onReceive(Context context, Intent intent) {
7311                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7312                 if (pkgs != null) {
7313                     for (String pkg : pkgs) {
7314                         synchronized (ActivityManagerService.this) {
7315                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7316                                     0, "query restart")) {
7317                                 setResultCode(Activity.RESULT_OK);
7318                                 return;
7319                             }
7320                         }
7321                     }
7322                 }
7323             }
7324         }, pkgFilter);
7325
7326         IntentFilter dumpheapFilter = new IntentFilter();
7327         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7328         mContext.registerReceiver(new BroadcastReceiver() {
7329             @Override
7330             public void onReceive(Context context, Intent intent) {
7331                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7332                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7333                 } else {
7334                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7335                 }
7336             }
7337         }, dumpheapFilter);
7338
7339         // Let system services know.
7340         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7341
7342         synchronized (this) {
7343             // Ensure that any processes we had put on hold are now started
7344             // up.
7345             final int NP = mProcessesOnHold.size();
7346             if (NP > 0) {
7347                 ArrayList<ProcessRecord> procs =
7348                     new ArrayList<ProcessRecord>(mProcessesOnHold);
7349                 for (int ip=0; ip<NP; ip++) {
7350                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7351                             + procs.get(ip));
7352                     startProcessLocked(procs.get(ip), "on-hold", null);
7353                 }
7354             }
7355
7356             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7357                 // Start looking for apps that are abusing wake locks.
7358                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7359                 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7360                 // Tell anyone interested that we are done booting!
7361                 SystemProperties.set("sys.boot_completed", "1");
7362
7363                 // And trigger dev.bootcomplete if we are not showing encryption progress
7364                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7365                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7366                     SystemProperties.set("dev.bootcomplete", "1");
7367                 }
7368                 mUserController.sendBootCompletedLocked(
7369                         new IIntentReceiver.Stub() {
7370                             @Override
7371                             public void performReceive(Intent intent, int resultCode,
7372                                     String data, Bundle extras, boolean ordered,
7373                                     boolean sticky, int sendingUser) {
7374                                 synchronized (ActivityManagerService.this) {
7375                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7376                                             true, false);
7377                                 }
7378                             }
7379                         });
7380                 scheduleStartProfilesLocked();
7381             }
7382         }
7383     }
7384
7385     @Override
7386     public void bootAnimationComplete() {
7387         final boolean callFinishBooting;
7388         synchronized (this) {
7389             callFinishBooting = mCallFinishBooting;
7390             mBootAnimationComplete = true;
7391         }
7392         if (callFinishBooting) {
7393             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7394             finishBooting();
7395             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7396         }
7397     }
7398
7399     final void ensureBootCompleted() {
7400         boolean booting;
7401         boolean enableScreen;
7402         synchronized (this) {
7403             booting = mBooting;
7404             mBooting = false;
7405             enableScreen = !mBooted;
7406             mBooted = true;
7407         }
7408
7409         if (booting) {
7410             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7411             finishBooting();
7412             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7413         }
7414
7415         if (enableScreen) {
7416             enableScreenAfterBoot();
7417         }
7418     }
7419
7420     @Override
7421     public final void activityResumed(IBinder token) {
7422         final long origId = Binder.clearCallingIdentity();
7423         synchronized(this) {
7424             ActivityRecord.activityResumedLocked(token);
7425             mWindowManager.notifyAppResumedFinished(token);
7426         }
7427         Binder.restoreCallingIdentity(origId);
7428     }
7429
7430     @Override
7431     public final void activityPaused(IBinder token) {
7432         final long origId = Binder.clearCallingIdentity();
7433         synchronized(this) {
7434             ActivityStack stack = ActivityRecord.getStackLocked(token);
7435             if (stack != null) {
7436                 stack.activityPausedLocked(token, false);
7437             }
7438         }
7439         Binder.restoreCallingIdentity(origId);
7440     }
7441
7442     @Override
7443     public final void activityStopped(IBinder token, Bundle icicle,
7444             PersistableBundle persistentState, CharSequence description) {
7445         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7446
7447         // Refuse possible leaked file descriptors
7448         if (icicle != null && icicle.hasFileDescriptors()) {
7449             throw new IllegalArgumentException("File descriptors passed in Bundle");
7450         }
7451
7452         final long origId = Binder.clearCallingIdentity();
7453
7454         synchronized (this) {
7455             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7456             if (r != null) {
7457                 r.activityStoppedLocked(icicle, persistentState, description);
7458             }
7459         }
7460
7461         trimApplications();
7462
7463         Binder.restoreCallingIdentity(origId);
7464     }
7465
7466     @Override
7467     public final void activityDestroyed(IBinder token) {
7468         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7469         synchronized (this) {
7470             ActivityStack stack = ActivityRecord.getStackLocked(token);
7471             if (stack != null) {
7472                 stack.activityDestroyedLocked(token, "activityDestroyed");
7473             }
7474         }
7475     }
7476
7477     @Override
7478     public final void activityRelaunched(IBinder token) {
7479         final long origId = Binder.clearCallingIdentity();
7480         synchronized (this) {
7481             mStackSupervisor.activityRelaunchedLocked(token);
7482         }
7483         Binder.restoreCallingIdentity(origId);
7484     }
7485
7486     @Override
7487     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7488             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7489         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7490                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7491         synchronized (this) {
7492             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7493             if (record == null) {
7494                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7495                         + "found for: " + token);
7496             }
7497             record.setSizeConfigurations(horizontalSizeConfiguration,
7498                     verticalSizeConfigurations, smallestSizeConfigurations);
7499         }
7500     }
7501
7502     @Override
7503     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7504         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7505     }
7506
7507     @Override
7508     public final void notifyEnterAnimationComplete(IBinder token) {
7509         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7510     }
7511
7512     @Override
7513     public String getCallingPackage(IBinder token) {
7514         synchronized (this) {
7515             ActivityRecord r = getCallingRecordLocked(token);
7516             return r != null ? r.info.packageName : null;
7517         }
7518     }
7519
7520     @Override
7521     public ComponentName getCallingActivity(IBinder token) {
7522         synchronized (this) {
7523             ActivityRecord r = getCallingRecordLocked(token);
7524             return r != null ? r.intent.getComponent() : null;
7525         }
7526     }
7527
7528     private ActivityRecord getCallingRecordLocked(IBinder token) {
7529         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7530         if (r == null) {
7531             return null;
7532         }
7533         return r.resultTo;
7534     }
7535
7536     @Override
7537     public ComponentName getActivityClassForToken(IBinder token) {
7538         synchronized(this) {
7539             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7540             if (r == null) {
7541                 return null;
7542             }
7543             return r.intent.getComponent();
7544         }
7545     }
7546
7547     @Override
7548     public String getPackageForToken(IBinder token) {
7549         synchronized(this) {
7550             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7551             if (r == null) {
7552                 return null;
7553             }
7554             return r.packageName;
7555         }
7556     }
7557
7558     @Override
7559     public boolean isRootVoiceInteraction(IBinder token) {
7560         synchronized(this) {
7561             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7562             if (r == null) {
7563                 return false;
7564             }
7565             return r.rootVoiceInteraction;
7566         }
7567     }
7568
7569     @Override
7570     public IIntentSender getIntentSender(int type,
7571             String packageName, IBinder token, String resultWho,
7572             int requestCode, Intent[] intents, String[] resolvedTypes,
7573             int flags, Bundle bOptions, int userId) {
7574         enforceNotIsolatedCaller("getIntentSender");
7575         // Refuse possible leaked file descriptors
7576         if (intents != null) {
7577             if (intents.length < 1) {
7578                 throw new IllegalArgumentException("Intents array length must be >= 1");
7579             }
7580             for (int i=0; i<intents.length; i++) {
7581                 Intent intent = intents[i];
7582                 if (intent != null) {
7583                     if (intent.hasFileDescriptors()) {
7584                         throw new IllegalArgumentException("File descriptors passed in Intent");
7585                     }
7586                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7587                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7588                         throw new IllegalArgumentException(
7589                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7590                     }
7591                     intents[i] = new Intent(intent);
7592                 }
7593             }
7594             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7595                 throw new IllegalArgumentException(
7596                         "Intent array length does not match resolvedTypes length");
7597             }
7598         }
7599         if (bOptions != null) {
7600             if (bOptions.hasFileDescriptors()) {
7601                 throw new IllegalArgumentException("File descriptors passed in options");
7602             }
7603         }
7604
7605         synchronized(this) {
7606             int callingUid = Binder.getCallingUid();
7607             int origUserId = userId;
7608             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7609                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7610                     ALLOW_NON_FULL, "getIntentSender", null);
7611             if (origUserId == UserHandle.USER_CURRENT) {
7612                 // We don't want to evaluate this until the pending intent is
7613                 // actually executed.  However, we do want to always do the
7614                 // security checking for it above.
7615                 userId = UserHandle.USER_CURRENT;
7616             }
7617             try {
7618                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7619                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7620                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7621                     if (!UserHandle.isSameApp(callingUid, uid)) {
7622                         String msg = "Permission Denial: getIntentSender() from pid="
7623                             + Binder.getCallingPid()
7624                             + ", uid=" + Binder.getCallingUid()
7625                             + ", (need uid=" + uid + ")"
7626                             + " is not allowed to send as package " + packageName;
7627                         Slog.w(TAG, msg);
7628                         throw new SecurityException(msg);
7629                     }
7630                 }
7631
7632                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7633                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7634
7635             } catch (RemoteException e) {
7636                 throw new SecurityException(e);
7637             }
7638         }
7639     }
7640
7641     IIntentSender getIntentSenderLocked(int type, String packageName,
7642             int callingUid, int userId, IBinder token, String resultWho,
7643             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7644             Bundle bOptions) {
7645         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7646         ActivityRecord activity = null;
7647         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7648             activity = ActivityRecord.isInStackLocked(token);
7649             if (activity == null) {
7650                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7651                 return null;
7652             }
7653             if (activity.finishing) {
7654                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7655                 return null;
7656             }
7657         }
7658
7659         // We're going to be splicing together extras before sending, so we're
7660         // okay poking into any contained extras.
7661         if (intents != null) {
7662             for (int i = 0; i < intents.length; i++) {
7663                 intents[i].setDefusable(true);
7664             }
7665         }
7666         Bundle.setDefusable(bOptions, true);
7667
7668         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7669         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7670         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7671         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7672                 |PendingIntent.FLAG_UPDATE_CURRENT);
7673
7674         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7675                 type, packageName, activity, resultWho,
7676                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7677         WeakReference<PendingIntentRecord> ref;
7678         ref = mIntentSenderRecords.get(key);
7679         PendingIntentRecord rec = ref != null ? ref.get() : null;
7680         if (rec != null) {
7681             if (!cancelCurrent) {
7682                 if (updateCurrent) {
7683                     if (rec.key.requestIntent != null) {
7684                         rec.key.requestIntent.replaceExtras(intents != null ?
7685                                 intents[intents.length - 1] : null);
7686                     }
7687                     if (intents != null) {
7688                         intents[intents.length-1] = rec.key.requestIntent;
7689                         rec.key.allIntents = intents;
7690                         rec.key.allResolvedTypes = resolvedTypes;
7691                     } else {
7692                         rec.key.allIntents = null;
7693                         rec.key.allResolvedTypes = null;
7694                     }
7695                 }
7696                 return rec;
7697             }
7698             makeIntentSenderCanceledLocked(rec);
7699             mIntentSenderRecords.remove(key);
7700         }
7701         if (noCreate) {
7702             return rec;
7703         }
7704         rec = new PendingIntentRecord(this, key, callingUid);
7705         mIntentSenderRecords.put(key, rec.ref);
7706         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7707             if (activity.pendingResults == null) {
7708                 activity.pendingResults
7709                         = new HashSet<WeakReference<PendingIntentRecord>>();
7710             }
7711             activity.pendingResults.add(rec.ref);
7712         }
7713         return rec;
7714     }
7715
7716     @Override
7717     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7718             Intent intent, String resolvedType,
7719             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7720         if (target instanceof PendingIntentRecord) {
7721             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7722                     whitelistToken, finishedReceiver, requiredPermission, options);
7723         } else {
7724             if (intent == null) {
7725                 // Weird case: someone has given us their own custom IIntentSender, and now
7726                 // they have someone else trying to send to it but of course this isn't
7727                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7728                 // supplying an Intent... but we never want to dispatch a null Intent to
7729                 // a receiver, so um...  let's make something up.
7730                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7731                 intent = new Intent(Intent.ACTION_MAIN);
7732             }
7733             try {
7734                 target.send(code, intent, resolvedType, whitelistToken, null,
7735                         requiredPermission, options);
7736             } catch (RemoteException e) {
7737             }
7738             // Platform code can rely on getting a result back when the send is done, but if
7739             // this intent sender is from outside of the system we can't rely on it doing that.
7740             // So instead we don't give it the result receiver, and instead just directly
7741             // report the finish immediately.
7742             if (finishedReceiver != null) {
7743                 try {
7744                     finishedReceiver.performReceive(intent, 0,
7745                             null, null, false, false, UserHandle.getCallingUserId());
7746                 } catch (RemoteException e) {
7747                 }
7748             }
7749             return 0;
7750         }
7751     }
7752
7753     @Override
7754     public void cancelIntentSender(IIntentSender sender) {
7755         if (!(sender instanceof PendingIntentRecord)) {
7756             return;
7757         }
7758         synchronized(this) {
7759             PendingIntentRecord rec = (PendingIntentRecord)sender;
7760             try {
7761                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7762                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7763                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7764                     String msg = "Permission Denial: cancelIntentSender() from pid="
7765                         + Binder.getCallingPid()
7766                         + ", uid=" + Binder.getCallingUid()
7767                         + " is not allowed to cancel package "
7768                         + rec.key.packageName;
7769                     Slog.w(TAG, msg);
7770                     throw new SecurityException(msg);
7771                 }
7772             } catch (RemoteException e) {
7773                 throw new SecurityException(e);
7774             }
7775             cancelIntentSenderLocked(rec, true);
7776         }
7777     }
7778
7779     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7780         makeIntentSenderCanceledLocked(rec);
7781         mIntentSenderRecords.remove(rec.key);
7782         if (cleanActivity && rec.key.activity != null) {
7783             rec.key.activity.pendingResults.remove(rec.ref);
7784         }
7785     }
7786
7787     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7788         rec.canceled = true;
7789         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7790         if (callbacks != null) {
7791             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7792         }
7793     }
7794
7795     @Override
7796     public String getPackageForIntentSender(IIntentSender pendingResult) {
7797         if (!(pendingResult instanceof PendingIntentRecord)) {
7798             return null;
7799         }
7800         try {
7801             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7802             return res.key.packageName;
7803         } catch (ClassCastException e) {
7804         }
7805         return null;
7806     }
7807
7808     @Override
7809     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7810         if (!(sender instanceof PendingIntentRecord)) {
7811             return;
7812         }
7813         synchronized(this) {
7814             ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7815         }
7816     }
7817
7818     @Override
7819     public void unregisterIntentSenderCancelListener(IIntentSender sender,
7820             IResultReceiver receiver) {
7821         if (!(sender instanceof PendingIntentRecord)) {
7822             return;
7823         }
7824         synchronized(this) {
7825             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7826         }
7827     }
7828
7829     @Override
7830     public int getUidForIntentSender(IIntentSender sender) {
7831         if (sender instanceof PendingIntentRecord) {
7832             try {
7833                 PendingIntentRecord res = (PendingIntentRecord)sender;
7834                 return res.uid;
7835             } catch (ClassCastException e) {
7836             }
7837         }
7838         return -1;
7839     }
7840
7841     @Override
7842     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7843         if (!(pendingResult instanceof PendingIntentRecord)) {
7844             return false;
7845         }
7846         try {
7847             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7848             if (res.key.allIntents == null) {
7849                 return false;
7850             }
7851             for (int i=0; i<res.key.allIntents.length; i++) {
7852                 Intent intent = res.key.allIntents[i];
7853                 if (intent.getPackage() != null && intent.getComponent() != null) {
7854                     return false;
7855                 }
7856             }
7857             return true;
7858         } catch (ClassCastException e) {
7859         }
7860         return false;
7861     }
7862
7863     @Override
7864     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7865         if (!(pendingResult instanceof PendingIntentRecord)) {
7866             return false;
7867         }
7868         try {
7869             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7870             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7871                 return true;
7872             }
7873             return false;
7874         } catch (ClassCastException e) {
7875         }
7876         return false;
7877     }
7878
7879     @Override
7880     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7881         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7882                 "getIntentForIntentSender()");
7883         if (!(pendingResult instanceof PendingIntentRecord)) {
7884             return null;
7885         }
7886         try {
7887             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7888             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7889         } catch (ClassCastException e) {
7890         }
7891         return null;
7892     }
7893
7894     @Override
7895     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7896         if (!(pendingResult instanceof PendingIntentRecord)) {
7897             return null;
7898         }
7899         try {
7900             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7901             synchronized (this) {
7902                 return getTagForIntentSenderLocked(res, prefix);
7903             }
7904         } catch (ClassCastException e) {
7905         }
7906         return null;
7907     }
7908
7909     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7910         final Intent intent = res.key.requestIntent;
7911         if (intent != null) {
7912             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7913                     || res.lastTagPrefix.equals(prefix))) {
7914                 return res.lastTag;
7915             }
7916             res.lastTagPrefix = prefix;
7917             final StringBuilder sb = new StringBuilder(128);
7918             if (prefix != null) {
7919                 sb.append(prefix);
7920             }
7921             if (intent.getAction() != null) {
7922                 sb.append(intent.getAction());
7923             } else if (intent.getComponent() != null) {
7924                 intent.getComponent().appendShortString(sb);
7925             } else {
7926                 sb.append("?");
7927             }
7928             return res.lastTag = sb.toString();
7929         }
7930         return null;
7931     }
7932
7933     @Override
7934     public void setProcessLimit(int max) {
7935         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7936                 "setProcessLimit()");
7937         synchronized (this) {
7938             mConstants.setOverrideMaxCachedProcesses(max);
7939         }
7940         trimApplications();
7941     }
7942
7943     @Override
7944     public int getProcessLimit() {
7945         synchronized (this) {
7946             return mConstants.getOverrideMaxCachedProcesses();
7947         }
7948     }
7949
7950     void importanceTokenDied(ImportanceToken token) {
7951         synchronized (ActivityManagerService.this) {
7952             synchronized (mPidsSelfLocked) {
7953                 ImportanceToken cur
7954                     = mImportantProcesses.get(token.pid);
7955                 if (cur != token) {
7956                     return;
7957                 }
7958                 mImportantProcesses.remove(token.pid);
7959                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7960                 if (pr == null) {
7961                     return;
7962                 }
7963                 pr.forcingToImportant = null;
7964                 updateProcessForegroundLocked(pr, false, false);
7965             }
7966             updateOomAdjLocked();
7967         }
7968     }
7969
7970     @Override
7971     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7972         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7973                 "setProcessImportant()");
7974         synchronized(this) {
7975             boolean changed = false;
7976
7977             synchronized (mPidsSelfLocked) {
7978                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7979                 if (pr == null && isForeground) {
7980                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7981                     return;
7982                 }
7983                 ImportanceToken oldToken = mImportantProcesses.get(pid);
7984                 if (oldToken != null) {
7985                     oldToken.token.unlinkToDeath(oldToken, 0);
7986                     mImportantProcesses.remove(pid);
7987                     if (pr != null) {
7988                         pr.forcingToImportant = null;
7989                     }
7990                     changed = true;
7991                 }
7992                 if (isForeground && token != null) {
7993                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7994                         @Override
7995                         public void binderDied() {
7996                             importanceTokenDied(this);
7997                         }
7998                     };
7999                     try {
8000                         token.linkToDeath(newToken, 0);
8001                         mImportantProcesses.put(pid, newToken);
8002                         pr.forcingToImportant = newToken;
8003                         changed = true;
8004                     } catch (RemoteException e) {
8005                         // If the process died while doing this, we will later
8006                         // do the cleanup with the process death link.
8007                     }
8008                 }
8009             }
8010
8011             if (changed) {
8012                 updateOomAdjLocked();
8013             }
8014         }
8015     }
8016
8017     @Override
8018     public boolean isAppForeground(int uid) throws RemoteException {
8019         synchronized (this) {
8020             UidRecord uidRec = mActiveUids.get(uid);
8021             if (uidRec == null || uidRec.idle) {
8022                 return false;
8023             }
8024             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8025         }
8026     }
8027
8028     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8029     // be guarded by permission checking.
8030     int getUidState(int uid) {
8031         synchronized (this) {
8032             return getUidStateLocked(uid);
8033         }
8034     }
8035
8036     int getUidStateLocked(int uid) {
8037         UidRecord uidRec = mActiveUids.get(uid);
8038         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8039     }
8040
8041     @Override
8042     public boolean isInMultiWindowMode(IBinder token) {
8043         final long origId = Binder.clearCallingIdentity();
8044         try {
8045             synchronized(this) {
8046                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8047                 if (r == null) {
8048                     return false;
8049                 }
8050                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8051                 return !r.getTask().mFullscreen;
8052             }
8053         } finally {
8054             Binder.restoreCallingIdentity(origId);
8055         }
8056     }
8057
8058     @Override
8059     public boolean isInPictureInPictureMode(IBinder token) {
8060         final long origId = Binder.clearCallingIdentity();
8061         try {
8062             synchronized(this) {
8063                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8064             }
8065         } finally {
8066             Binder.restoreCallingIdentity(origId);
8067         }
8068     }
8069
8070     private boolean isInPictureInPictureMode(ActivityRecord r) {
8071         if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8072                 r.getStack().isInStackLocked(r) == null) {
8073             return false;
8074         }
8075
8076         // If we are animating to fullscreen then we have already dispatched the PIP mode
8077         // changed, so we should reflect that check here as well.
8078         final PinnedActivityStack stack = r.getStack();
8079         final PinnedStackWindowController windowController = stack.getWindowContainerController();
8080         return !windowController.isAnimatingBoundsToFullscreen();
8081     }
8082
8083     @Override
8084     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8085         final long origId = Binder.clearCallingIdentity();
8086         try {
8087             synchronized(this) {
8088                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8089                         "enterPictureInPictureMode", token, params);
8090
8091                 // If the activity is already in picture in picture mode, then just return early
8092                 if (isInPictureInPictureMode(r)) {
8093                     return true;
8094                 }
8095
8096                 // Activity supports picture-in-picture, now check that we can enter PiP at this
8097                 // point, if it is
8098                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8099                         false /* beforeStopping */)) {
8100                     return false;
8101                 }
8102
8103                 final Runnable enterPipRunnable = () -> {
8104                     // Only update the saved args from the args that are set
8105                     r.pictureInPictureArgs.copyOnlySet(params);
8106                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8107                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8108                     // Adjust the source bounds by the insets for the transition down
8109                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8110                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8111                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8112                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8113                     stack.setPictureInPictureAspectRatio(aspectRatio);
8114                     stack.setPictureInPictureActions(actions);
8115
8116                     MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8117                             r.supportsEnterPipOnTaskSwitch);
8118                     logPictureInPictureArgs(params);
8119                 };
8120
8121                 if (isKeyguardLocked()) {
8122                     // If the keyguard is showing or occluded, then try and dismiss it before
8123                     // entering picture-in-picture (this will prompt the user to authenticate if the
8124                     // device is currently locked).
8125                     try {
8126                         dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8127                             @Override
8128                             public void onDismissError() throws RemoteException {
8129                                 // Do nothing
8130                             }
8131
8132                             @Override
8133                             public void onDismissSucceeded() throws RemoteException {
8134                                 mHandler.post(enterPipRunnable);
8135                             }
8136
8137                             @Override
8138                             public void onDismissCancelled() throws RemoteException {
8139                                 // Do nothing
8140                             }
8141                         });
8142                     } catch (RemoteException e) {
8143                         // Local call
8144                     }
8145                 } else {
8146                     // Enter picture in picture immediately otherwise
8147                     enterPipRunnable.run();
8148                 }
8149                 return true;
8150             }
8151         } finally {
8152             Binder.restoreCallingIdentity(origId);
8153         }
8154     }
8155
8156     @Override
8157     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8158         final long origId = Binder.clearCallingIdentity();
8159         try {
8160             synchronized(this) {
8161                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8162                         "setPictureInPictureParams", token, params);
8163
8164                 // Only update the saved args from the args that are set
8165                 r.pictureInPictureArgs.copyOnlySet(params);
8166                 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8167                     // If the activity is already in picture-in-picture, update the pinned stack now
8168                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
8169                     // be used the next time the activity enters PiP
8170                     final PinnedActivityStack stack = r.getStack();
8171                     if (!stack.isAnimatingBoundsToFullscreen()) {
8172                         stack.setPictureInPictureAspectRatio(
8173                                 r.pictureInPictureArgs.getAspectRatio());
8174                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8175                     }
8176                 }
8177                 logPictureInPictureArgs(params);
8178             }
8179         } finally {
8180             Binder.restoreCallingIdentity(origId);
8181         }
8182     }
8183
8184     @Override
8185     public int getMaxNumPictureInPictureActions(IBinder token) {
8186         // Currently, this is a static constant, but later, we may change this to be dependent on
8187         // the context of the activity
8188         return 3;
8189     }
8190
8191     private void logPictureInPictureArgs(PictureInPictureParams params) {
8192         if (params.hasSetActions()) {
8193             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8194                     params.getActions().size());
8195         }
8196         if (params.hasSetAspectRatio()) {
8197             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8198             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8199             MetricsLogger.action(lm);
8200         }
8201     }
8202
8203     /**
8204      * Checks the state of the system and the activity associated with the given {@param token} to
8205      * verify that picture-in-picture is supported for that activity.
8206      *
8207      * @return the activity record for the given {@param token} if all the checks pass.
8208      */
8209     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8210             IBinder token, PictureInPictureParams params) {
8211         if (!mSupportsPictureInPicture) {
8212             throw new IllegalStateException(caller
8213                     + ": Device doesn't support picture-in-picture mode.");
8214         }
8215
8216         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8217         if (r == null) {
8218             throw new IllegalStateException(caller
8219                     + ": Can't find activity for token=" + token);
8220         }
8221
8222         if (!r.supportsPictureInPicture()) {
8223             throw new IllegalStateException(caller
8224                     + ": Current activity does not support picture-in-picture.");
8225         }
8226
8227         if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8228             throw new IllegalStateException(caller
8229                     + ": Activities on the home, assistant, or recents stack not supported");
8230         }
8231
8232         if (params.hasSetAspectRatio()
8233                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8234                         params.getAspectRatio())) {
8235             final float minAspectRatio = mContext.getResources().getFloat(
8236                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8237             final float maxAspectRatio = mContext.getResources().getFloat(
8238                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8239             throw new IllegalArgumentException(String.format(caller
8240                     + ": Aspect ratio is too extreme (must be between %f and %f).",
8241                             minAspectRatio, maxAspectRatio));
8242         }
8243
8244         // Truncate the number of actions if necessary
8245         params.truncateActions(getMaxNumPictureInPictureActions(token));
8246
8247         return r;
8248     }
8249
8250     // =========================================================
8251     // PROCESS INFO
8252     // =========================================================
8253
8254     static class ProcessInfoService extends IProcessInfoService.Stub {
8255         final ActivityManagerService mActivityManagerService;
8256         ProcessInfoService(ActivityManagerService activityManagerService) {
8257             mActivityManagerService = activityManagerService;
8258         }
8259
8260         @Override
8261         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8262             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8263                     /*in*/ pids, /*out*/ states, null);
8264         }
8265
8266         @Override
8267         public void getProcessStatesAndOomScoresFromPids(
8268                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8269             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8270                     /*in*/ pids, /*out*/ states, /*out*/ scores);
8271         }
8272     }
8273
8274     /**
8275      * For each PID in the given input array, write the current process state
8276      * for that process into the states array, or -1 to indicate that no
8277      * process with the given PID exists. If scores array is provided, write
8278      * the oom score for the process into the scores array, with INVALID_ADJ
8279      * indicating the PID doesn't exist.
8280      */
8281     public void getProcessStatesAndOomScoresForPIDs(
8282             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8283         if (scores != null) {
8284             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8285                     "getProcessStatesAndOomScoresForPIDs()");
8286         }
8287
8288         if (pids == null) {
8289             throw new NullPointerException("pids");
8290         } else if (states == null) {
8291             throw new NullPointerException("states");
8292         } else if (pids.length != states.length) {
8293             throw new IllegalArgumentException("pids and states arrays have different lengths!");
8294         } else if (scores != null && pids.length != scores.length) {
8295             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8296         }
8297
8298         synchronized (mPidsSelfLocked) {
8299             for (int i = 0; i < pids.length; i++) {
8300                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8301                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8302                         pr.curProcState;
8303                 if (scores != null) {
8304                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8305                 }
8306             }
8307         }
8308     }
8309
8310     // =========================================================
8311     // PERMISSIONS
8312     // =========================================================
8313
8314     static class PermissionController extends IPermissionController.Stub {
8315         ActivityManagerService mActivityManagerService;
8316         PermissionController(ActivityManagerService activityManagerService) {
8317             mActivityManagerService = activityManagerService;
8318         }
8319
8320         @Override
8321         public boolean checkPermission(String permission, int pid, int uid) {
8322             return mActivityManagerService.checkPermission(permission, pid,
8323                     uid) == PackageManager.PERMISSION_GRANTED;
8324         }
8325
8326         @Override
8327         public String[] getPackagesForUid(int uid) {
8328             return mActivityManagerService.mContext.getPackageManager()
8329                     .getPackagesForUid(uid);
8330         }
8331
8332         @Override
8333         public boolean isRuntimePermission(String permission) {
8334             try {
8335                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8336                         .getPermissionInfo(permission, 0);
8337                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8338                         == PermissionInfo.PROTECTION_DANGEROUS;
8339             } catch (NameNotFoundException nnfe) {
8340                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8341             }
8342             return false;
8343         }
8344     }
8345
8346     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8347         @Override
8348         public int checkComponentPermission(String permission, int pid, int uid,
8349                 int owningUid, boolean exported) {
8350             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8351                     owningUid, exported);
8352         }
8353
8354         @Override
8355         public Object getAMSLock() {
8356             return ActivityManagerService.this;
8357         }
8358     }
8359
8360     /**
8361      * This can be called with or without the global lock held.
8362      */
8363     int checkComponentPermission(String permission, int pid, int uid,
8364             int owningUid, boolean exported) {
8365         if (pid == MY_PID) {
8366             return PackageManager.PERMISSION_GRANTED;
8367         }
8368         return ActivityManager.checkComponentPermission(permission, uid,
8369                 owningUid, exported);
8370     }
8371
8372     /**
8373      * As the only public entry point for permissions checking, this method
8374      * can enforce the semantic that requesting a check on a null global
8375      * permission is automatically denied.  (Internally a null permission
8376      * string is used when calling {@link #checkComponentPermission} in cases
8377      * when only uid-based security is needed.)
8378      *
8379      * This can be called with or without the global lock held.
8380      */
8381     @Override
8382     public int checkPermission(String permission, int pid, int uid) {
8383         if (permission == null) {
8384             return PackageManager.PERMISSION_DENIED;
8385         }
8386         return checkComponentPermission(permission, pid, uid, -1, true);
8387     }
8388
8389     @Override
8390     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8391         if (permission == null) {
8392             return PackageManager.PERMISSION_DENIED;
8393         }
8394
8395         // We might be performing an operation on behalf of an indirect binder
8396         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8397         // client identity accordingly before proceeding.
8398         Identity tlsIdentity = sCallerIdentity.get();
8399         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8400             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8401                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8402             uid = tlsIdentity.uid;
8403             pid = tlsIdentity.pid;
8404         }
8405
8406         return checkComponentPermission(permission, pid, uid, -1, true);
8407     }
8408
8409     /**
8410      * Binder IPC calls go through the public entry point.
8411      * This can be called with or without the global lock held.
8412      */
8413     int checkCallingPermission(String permission) {
8414         return checkPermission(permission,
8415                 Binder.getCallingPid(),
8416                 UserHandle.getAppId(Binder.getCallingUid()));
8417     }
8418
8419     /**
8420      * This can be called with or without the global lock held.
8421      */
8422     void enforceCallingPermission(String permission, String func) {
8423         if (checkCallingPermission(permission)
8424                 == PackageManager.PERMISSION_GRANTED) {
8425             return;
8426         }
8427
8428         String msg = "Permission Denial: " + func + " from pid="
8429                 + Binder.getCallingPid()
8430                 + ", uid=" + Binder.getCallingUid()
8431                 + " requires " + permission;
8432         Slog.w(TAG, msg);
8433         throw new SecurityException(msg);
8434     }
8435
8436     /**
8437      * Determine if UID is holding permissions required to access {@link Uri} in
8438      * the given {@link ProviderInfo}. Final permission checking is always done
8439      * in {@link ContentProvider}.
8440      */
8441     private final boolean checkHoldingPermissionsLocked(
8442             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8443         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8444                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8445         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8446             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8447                     != PERMISSION_GRANTED) {
8448                 return false;
8449             }
8450         }
8451         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8452     }
8453
8454     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8455             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8456         if (pi.applicationInfo.uid == uid) {
8457             return true;
8458         } else if (!pi.exported) {
8459             return false;
8460         }
8461
8462         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8463         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8464         try {
8465             // check if target holds top-level <provider> permissions
8466             if (!readMet && pi.readPermission != null && considerUidPermissions
8467                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8468                 readMet = true;
8469             }
8470             if (!writeMet && pi.writePermission != null && considerUidPermissions
8471                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8472                 writeMet = true;
8473             }
8474
8475             // track if unprotected read/write is allowed; any denied
8476             // <path-permission> below removes this ability
8477             boolean allowDefaultRead = pi.readPermission == null;
8478             boolean allowDefaultWrite = pi.writePermission == null;
8479
8480             // check if target holds any <path-permission> that match uri
8481             final PathPermission[] pps = pi.pathPermissions;
8482             if (pps != null) {
8483                 final String path = grantUri.uri.getPath();
8484                 int i = pps.length;
8485                 while (i > 0 && (!readMet || !writeMet)) {
8486                     i--;
8487                     PathPermission pp = pps[i];
8488                     if (pp.match(path)) {
8489                         if (!readMet) {
8490                             final String pprperm = pp.getReadPermission();
8491                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8492                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
8493                                     + ": match=" + pp.match(path)
8494                                     + " check=" + pm.checkUidPermission(pprperm, uid));
8495                             if (pprperm != null) {
8496                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8497                                         == PERMISSION_GRANTED) {
8498                                     readMet = true;
8499                                 } else {
8500                                     allowDefaultRead = false;
8501                                 }
8502                             }
8503                         }
8504                         if (!writeMet) {
8505                             final String ppwperm = pp.getWritePermission();
8506                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8507                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
8508                                     + ": match=" + pp.match(path)
8509                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
8510                             if (ppwperm != null) {
8511                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8512                                         == PERMISSION_GRANTED) {
8513                                     writeMet = true;
8514                                 } else {
8515                                     allowDefaultWrite = false;
8516                                 }
8517                             }
8518                         }
8519                     }
8520                 }
8521             }
8522
8523             // grant unprotected <provider> read/write, if not blocked by
8524             // <path-permission> above
8525             if (allowDefaultRead) readMet = true;
8526             if (allowDefaultWrite) writeMet = true;
8527
8528         } catch (RemoteException e) {
8529             return false;
8530         }
8531
8532         return readMet && writeMet;
8533     }
8534
8535     public boolean isAppStartModeDisabled(int uid, String packageName) {
8536         synchronized (this) {
8537             return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8538                     == ActivityManager.APP_START_MODE_DISABLED;
8539         }
8540     }
8541
8542     // Unified app-op and target sdk check
8543     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8544         // Apps that target O+ are always subject to background check
8545         if (packageTargetSdk >= Build.VERSION_CODES.O) {
8546             if (DEBUG_BACKGROUND_CHECK) {
8547                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8548             }
8549             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8550         }
8551         // ...and legacy apps get an AppOp check
8552         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8553                 uid, packageName);
8554         if (DEBUG_BACKGROUND_CHECK) {
8555             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8556         }
8557         switch (appop) {
8558             case AppOpsManager.MODE_ALLOWED:
8559                 return ActivityManager.APP_START_MODE_NORMAL;
8560             case AppOpsManager.MODE_IGNORED:
8561                 return ActivityManager.APP_START_MODE_DELAYED;
8562             default:
8563                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8564         }
8565     }
8566
8567     // Service launch is available to apps with run-in-background exemptions but
8568     // some other background operations are not.  If we're doing a check
8569     // of service-launch policy, allow those callers to proceed unrestricted.
8570     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8571         // Persistent app?
8572         if (mPackageManagerInt.isPackagePersistent(packageName)) {
8573             if (DEBUG_BACKGROUND_CHECK) {
8574                 Slog.i(TAG, "App " + uid + "/" + packageName
8575                         + " is persistent; not restricted in background");
8576             }
8577             return ActivityManager.APP_START_MODE_NORMAL;
8578         }
8579
8580         // Non-persistent but background whitelisted?
8581         if (uidOnBackgroundWhitelist(uid)) {
8582             if (DEBUG_BACKGROUND_CHECK) {
8583                 Slog.i(TAG, "App " + uid + "/" + packageName
8584                         + " on background whitelist; not restricted in background");
8585             }
8586             return ActivityManager.APP_START_MODE_NORMAL;
8587         }
8588
8589         // Is this app on the battery whitelist?
8590         if (isOnDeviceIdleWhitelistLocked(uid)) {
8591             if (DEBUG_BACKGROUND_CHECK) {
8592                 Slog.i(TAG, "App " + uid + "/" + packageName
8593                         + " on idle whitelist; not restricted in background");
8594             }
8595             return ActivityManager.APP_START_MODE_NORMAL;
8596         }
8597
8598         // None of the service-policy criteria apply, so we apply the common criteria
8599         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8600     }
8601
8602     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8603             int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8604         UidRecord uidRec = mActiveUids.get(uid);
8605         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8606                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8607                 + (uidRec != null ? uidRec.idle : false));
8608         if (uidRec == null || alwaysRestrict || uidRec.idle) {
8609             boolean ephemeral;
8610             if (uidRec == null) {
8611                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8612                         UserHandle.getUserId(uid), packageName);
8613             } else {
8614                 ephemeral = uidRec.ephemeral;
8615             }
8616
8617             if (ephemeral) {
8618                 // We are hard-core about ephemeral apps not running in the background.
8619                 return ActivityManager.APP_START_MODE_DISABLED;
8620             } else {
8621                 if (disabledOnly) {
8622                     // The caller is only interested in whether app starts are completely
8623                     // disabled for the given package (that is, it is an instant app).  So
8624                     // we don't need to go further, which is all just seeing if we should
8625                     // apply a "delayed" mode for a regular app.
8626                     return ActivityManager.APP_START_MODE_NORMAL;
8627                 }
8628                 final int startMode = (alwaysRestrict)
8629                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8630                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
8631                                 packageTargetSdk);
8632                 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8633                         + " pkg=" + packageName + " startMode=" + startMode
8634                         + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8635                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8636                     // This is an old app that has been forced into a "compatible as possible"
8637                     // mode of background check.  To increase compatibility, we will allow other
8638                     // foreground apps to cause its services to start.
8639                     if (callingPid >= 0) {
8640                         ProcessRecord proc;
8641                         synchronized (mPidsSelfLocked) {
8642                             proc = mPidsSelfLocked.get(callingPid);
8643                         }
8644                         if (proc != null &&
8645                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8646                             // Whoever is instigating this is in the foreground, so we will allow it
8647                             // to go through.
8648                             return ActivityManager.APP_START_MODE_NORMAL;
8649                         }
8650                     }
8651                 }
8652                 return startMode;
8653             }
8654         }
8655         return ActivityManager.APP_START_MODE_NORMAL;
8656     }
8657
8658     boolean isOnDeviceIdleWhitelistLocked(int uid) {
8659         final int appId = UserHandle.getAppId(uid);
8660         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8661                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8662                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8663     }
8664
8665     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8666         ProviderInfo pi = null;
8667         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8668         if (cpr != null) {
8669             pi = cpr.info;
8670         } else {
8671             try {
8672                 pi = AppGlobals.getPackageManager().resolveContentProvider(
8673                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8674                         userHandle);
8675             } catch (RemoteException ex) {
8676             }
8677         }
8678         return pi;
8679     }
8680
8681     void grantEphemeralAccessLocked(int userId, Intent intent,
8682             int targetAppId, int ephemeralAppId) {
8683         getPackageManagerInternalLocked().
8684                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8685     }
8686
8687     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8688         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8689         if (targetUris != null) {
8690             return targetUris.get(grantUri);
8691         }
8692         return null;
8693     }
8694
8695     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8696             String targetPkg, int targetUid, GrantUri grantUri) {
8697         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8698         if (targetUris == null) {
8699             targetUris = Maps.newArrayMap();
8700             mGrantedUriPermissions.put(targetUid, targetUris);
8701         }
8702
8703         UriPermission perm = targetUris.get(grantUri);
8704         if (perm == null) {
8705             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8706             targetUris.put(grantUri, perm);
8707         }
8708
8709         return perm;
8710     }
8711
8712     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8713             final int modeFlags) {
8714         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8715         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8716                 : UriPermission.STRENGTH_OWNED;
8717
8718         // Root gets to do everything.
8719         if (uid == 0) {
8720             return true;
8721         }
8722
8723         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8724         if (perms == null) return false;
8725
8726         // First look for exact match
8727         final UriPermission exactPerm = perms.get(grantUri);
8728         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8729             return true;
8730         }
8731
8732         // No exact match, look for prefixes
8733         final int N = perms.size();
8734         for (int i = 0; i < N; i++) {
8735             final UriPermission perm = perms.valueAt(i);
8736             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8737                     && perm.getStrength(modeFlags) >= minStrength) {
8738                 return true;
8739             }
8740         }
8741
8742         return false;
8743     }
8744
8745     /**
8746      * @param uri This uri must NOT contain an embedded userId.
8747      * @param userId The userId in which the uri is to be resolved.
8748      */
8749     @Override
8750     public int checkUriPermission(Uri uri, int pid, int uid,
8751             final int modeFlags, int userId, IBinder callerToken) {
8752         enforceNotIsolatedCaller("checkUriPermission");
8753
8754         // Another redirected-binder-call permissions check as in
8755         // {@link checkPermissionWithToken}.
8756         Identity tlsIdentity = sCallerIdentity.get();
8757         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8758             uid = tlsIdentity.uid;
8759             pid = tlsIdentity.pid;
8760         }
8761
8762         // Our own process gets to do everything.
8763         if (pid == MY_PID) {
8764             return PackageManager.PERMISSION_GRANTED;
8765         }
8766         synchronized (this) {
8767             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8768                     ? PackageManager.PERMISSION_GRANTED
8769                     : PackageManager.PERMISSION_DENIED;
8770         }
8771     }
8772
8773     /**
8774      * Check if the targetPkg can be granted permission to access uri by
8775      * the callingUid using the given modeFlags.  Throws a security exception
8776      * if callingUid is not allowed to do this.  Returns the uid of the target
8777      * if the URI permission grant should be performed; returns -1 if it is not
8778      * needed (for example targetPkg already has permission to access the URI).
8779      * If you already know the uid of the target, you can supply it in
8780      * lastTargetUid else set that to -1.
8781      */
8782     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8783             final int modeFlags, int lastTargetUid) {
8784         if (!Intent.isAccessUriMode(modeFlags)) {
8785             return -1;
8786         }
8787
8788         if (targetPkg != null) {
8789             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8790                     "Checking grant " + targetPkg + " permission to " + grantUri);
8791         }
8792
8793         final IPackageManager pm = AppGlobals.getPackageManager();
8794
8795         // If this is not a content: uri, we can't do anything with it.
8796         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8797             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8798                     "Can't grant URI permission for non-content URI: " + grantUri);
8799             return -1;
8800         }
8801
8802         // Bail early if system is trying to hand out permissions directly; it
8803         // must always grant permissions on behalf of someone explicit.
8804         final int callingAppId = UserHandle.getAppId(callingUid);
8805         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8806             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8807                 // Exempted authority for cropping user photos in Settings app
8808             } else {
8809                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8810                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8811                 return -1;
8812             }
8813         }
8814
8815         final String authority = grantUri.uri.getAuthority();
8816         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8817                 MATCH_DEBUG_TRIAGED_MISSING);
8818         if (pi == null) {
8819             Slog.w(TAG, "No content provider found for permission check: " +
8820                     grantUri.uri.toSafeString());
8821             return -1;
8822         }
8823
8824         int targetUid = lastTargetUid;
8825         if (targetUid < 0 && targetPkg != null) {
8826             try {
8827                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8828                         UserHandle.getUserId(callingUid));
8829                 if (targetUid < 0) {
8830                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8831                             "Can't grant URI permission no uid for: " + targetPkg);
8832                     return -1;
8833                 }
8834             } catch (RemoteException ex) {
8835                 return -1;
8836             }
8837         }
8838
8839         // If we're extending a persistable grant, then we always need to create
8840         // the grant data structure so that take/release APIs work
8841         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8842             return targetUid;
8843         }
8844
8845         if (targetUid >= 0) {
8846             // First...  does the target actually need this permission?
8847             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8848                 // No need to grant the target this permission.
8849                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8850                         "Target " + targetPkg + " already has full permission to " + grantUri);
8851                 return -1;
8852             }
8853         } else {
8854             // First...  there is no target package, so can anyone access it?
8855             boolean allowed = pi.exported;
8856             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8857                 if (pi.readPermission != null) {
8858                     allowed = false;
8859                 }
8860             }
8861             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8862                 if (pi.writePermission != null) {
8863                     allowed = false;
8864                 }
8865             }
8866             if (allowed) {
8867                 return -1;
8868             }
8869         }
8870
8871         /* There is a special cross user grant if:
8872          * - The target is on another user.
8873          * - Apps on the current user can access the uri without any uid permissions.
8874          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8875          * grant uri permissions.
8876          */
8877         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8878                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8879                 modeFlags, false /*without considering the uid permissions*/);
8880
8881         // Second...  is the provider allowing granting of URI permissions?
8882         if (!specialCrossUserGrant) {
8883             if (!pi.grantUriPermissions) {
8884                 throw new SecurityException("Provider " + pi.packageName
8885                         + "/" + pi.name
8886                         + " does not allow granting of Uri permissions (uri "
8887                         + grantUri + ")");
8888             }
8889             if (pi.uriPermissionPatterns != null) {
8890                 final int N = pi.uriPermissionPatterns.length;
8891                 boolean allowed = false;
8892                 for (int i=0; i<N; i++) {
8893                     if (pi.uriPermissionPatterns[i] != null
8894                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8895                         allowed = true;
8896                         break;
8897                     }
8898                 }
8899                 if (!allowed) {
8900                     throw new SecurityException("Provider " + pi.packageName
8901                             + "/" + pi.name
8902                             + " does not allow granting of permission to path of Uri "
8903                             + grantUri);
8904                 }
8905             }
8906         }
8907
8908         // Third...  does the caller itself have permission to access
8909         // this uri?
8910         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8911             // Require they hold a strong enough Uri permission
8912             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8913                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8914                     throw new SecurityException(
8915                             "UID " + callingUid + " does not have permission to " + grantUri
8916                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8917                                     + "or related APIs");
8918                 } else {
8919                     throw new SecurityException(
8920                             "UID " + callingUid + " does not have permission to " + grantUri);
8921                 }
8922             }
8923         }
8924         return targetUid;
8925     }
8926
8927     /**
8928      * @param uri This uri must NOT contain an embedded userId.
8929      * @param userId The userId in which the uri is to be resolved.
8930      */
8931     @Override
8932     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8933             final int modeFlags, int userId) {
8934         enforceNotIsolatedCaller("checkGrantUriPermission");
8935         synchronized(this) {
8936             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8937                     new GrantUri(userId, uri, false), modeFlags, -1);
8938         }
8939     }
8940
8941     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8942             final int modeFlags, UriPermissionOwner owner) {
8943         if (!Intent.isAccessUriMode(modeFlags)) {
8944             return;
8945         }
8946
8947         // So here we are: the caller has the assumed permission
8948         // to the uri, and the target doesn't.  Let's now give this to
8949         // the target.
8950
8951         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8952                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8953
8954         final String authority = grantUri.uri.getAuthority();
8955         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8956                 MATCH_DEBUG_TRIAGED_MISSING);
8957         if (pi == null) {
8958             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8959             return;
8960         }
8961
8962         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8963             grantUri.prefix = true;
8964         }
8965         final UriPermission perm = findOrCreateUriPermissionLocked(
8966                 pi.packageName, targetPkg, targetUid, grantUri);
8967         perm.grantModes(modeFlags, owner);
8968     }
8969
8970     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8971             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8972         if (targetPkg == null) {
8973             throw new NullPointerException("targetPkg");
8974         }
8975         int targetUid;
8976         final IPackageManager pm = AppGlobals.getPackageManager();
8977         try {
8978             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8979         } catch (RemoteException ex) {
8980             return;
8981         }
8982
8983         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8984                 targetUid);
8985         if (targetUid < 0) {
8986             return;
8987         }
8988
8989         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8990                 owner);
8991     }
8992
8993     static class NeededUriGrants extends ArrayList<GrantUri> {
8994         final String targetPkg;
8995         final int targetUid;
8996         final int flags;
8997
8998         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8999             this.targetPkg = targetPkg;
9000             this.targetUid = targetUid;
9001             this.flags = flags;
9002         }
9003     }
9004
9005     /**
9006      * Like checkGrantUriPermissionLocked, but takes an Intent.
9007      */
9008     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9009             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9010         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9011                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9012                 + " clip=" + (intent != null ? intent.getClipData() : null)
9013                 + " from " + intent + "; flags=0x"
9014                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9015
9016         if (targetPkg == null) {
9017             throw new NullPointerException("targetPkg");
9018         }
9019
9020         if (intent == null) {
9021             return null;
9022         }
9023         Uri data = intent.getData();
9024         ClipData clip = intent.getClipData();
9025         if (data == null && clip == null) {
9026             return null;
9027         }
9028         // Default userId for uris in the intent (if they don't specify it themselves)
9029         int contentUserHint = intent.getContentUserHint();
9030         if (contentUserHint == UserHandle.USER_CURRENT) {
9031             contentUserHint = UserHandle.getUserId(callingUid);
9032         }
9033         final IPackageManager pm = AppGlobals.getPackageManager();
9034         int targetUid;
9035         if (needed != null) {
9036             targetUid = needed.targetUid;
9037         } else {
9038             try {
9039                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9040                         targetUserId);
9041             } catch (RemoteException ex) {
9042                 return null;
9043             }
9044             if (targetUid < 0) {
9045                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9046                         "Can't grant URI permission no uid for: " + targetPkg
9047                         + " on user " + targetUserId);
9048                 return null;
9049             }
9050         }
9051         if (data != null) {
9052             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9053             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9054                     targetUid);
9055             if (targetUid > 0) {
9056                 if (needed == null) {
9057                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
9058                 }
9059                 needed.add(grantUri);
9060             }
9061         }
9062         if (clip != null) {
9063             for (int i=0; i<clip.getItemCount(); i++) {
9064                 Uri uri = clip.getItemAt(i).getUri();
9065                 if (uri != null) {
9066                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9067                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9068                             targetUid);
9069                     if (targetUid > 0) {
9070                         if (needed == null) {
9071                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
9072                         }
9073                         needed.add(grantUri);
9074                     }
9075                 } else {
9076                     Intent clipIntent = clip.getItemAt(i).getIntent();
9077                     if (clipIntent != null) {
9078                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9079                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9080                         if (newNeeded != null) {
9081                             needed = newNeeded;
9082                         }
9083                     }
9084                 }
9085             }
9086         }
9087
9088         return needed;
9089     }
9090
9091     /**
9092      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9093      */
9094     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9095             UriPermissionOwner owner) {
9096         if (needed != null) {
9097             for (int i=0; i<needed.size(); i++) {
9098                 GrantUri grantUri = needed.get(i);
9099                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9100                         grantUri, needed.flags, owner);
9101             }
9102         }
9103     }
9104
9105     void grantUriPermissionFromIntentLocked(int callingUid,
9106             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9107         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9108                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9109         if (needed == null) {
9110             return;
9111         }
9112
9113         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9114     }
9115
9116     /**
9117      * @param uri This uri must NOT contain an embedded userId.
9118      * @param userId The userId in which the uri is to be resolved.
9119      */
9120     @Override
9121     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9122             final int modeFlags, int userId) {
9123         enforceNotIsolatedCaller("grantUriPermission");
9124         GrantUri grantUri = new GrantUri(userId, uri, false);
9125         synchronized(this) {
9126             final ProcessRecord r = getRecordForAppLocked(caller);
9127             if (r == null) {
9128                 throw new SecurityException("Unable to find app for caller "
9129                         + caller
9130                         + " when granting permission to uri " + grantUri);
9131             }
9132             if (targetPkg == null) {
9133                 throw new IllegalArgumentException("null target");
9134             }
9135             if (grantUri == null) {
9136                 throw new IllegalArgumentException("null uri");
9137             }
9138
9139             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9140                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9141                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9142                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9143
9144             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9145                     UserHandle.getUserId(r.uid));
9146         }
9147     }
9148
9149     void removeUriPermissionIfNeededLocked(UriPermission perm) {
9150         if (perm.modeFlags == 0) {
9151             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9152                     perm.targetUid);
9153             if (perms != null) {
9154                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9155                         "Removing " + perm.targetUid + " permission to " + perm.uri);
9156
9157                 perms.remove(perm.uri);
9158                 if (perms.isEmpty()) {
9159                     mGrantedUriPermissions.remove(perm.targetUid);
9160                 }
9161             }
9162         }
9163     }
9164
9165     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9166             final int modeFlags) {
9167         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9168                 "Revoking all granted permissions to " + grantUri);
9169
9170         final IPackageManager pm = AppGlobals.getPackageManager();
9171         final String authority = grantUri.uri.getAuthority();
9172         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9173                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9174         if (pi == null) {
9175             Slog.w(TAG, "No content provider found for permission revoke: "
9176                     + grantUri.toSafeString());
9177             return;
9178         }
9179
9180         // Does the caller have this permission on the URI?
9181         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9182             // If they don't have direct access to the URI, then revoke any
9183             // ownerless URI permissions that have been granted to them.
9184             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9185             if (perms != null) {
9186                 boolean persistChanged = false;
9187                 for (int i = perms.size()-1; i >= 0; i--) {
9188                     final UriPermission perm = perms.valueAt(i);
9189                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9190                         continue;
9191                     }
9192                     if (perm.uri.sourceUserId == grantUri.sourceUserId
9193                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9194                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9195                                 "Revoking non-owned " + perm.targetUid
9196                                 + " permission to " + perm.uri);
9197                         persistChanged |= perm.revokeModes(
9198                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9199                         if (perm.modeFlags == 0) {
9200                             perms.removeAt(i);
9201                         }
9202                     }
9203                 }
9204                 if (perms.isEmpty()) {
9205                     mGrantedUriPermissions.remove(callingUid);
9206                 }
9207                 if (persistChanged) {
9208                     schedulePersistUriGrants();
9209                 }
9210             }
9211             return;
9212         }
9213
9214         boolean persistChanged = false;
9215
9216         // Go through all of the permissions and remove any that match.
9217         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9218             final int targetUid = mGrantedUriPermissions.keyAt(i);
9219             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9220
9221             for (int j = perms.size()-1; j >= 0; j--) {
9222                 final UriPermission perm = perms.valueAt(j);
9223                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9224                     continue;
9225                 }
9226                 if (perm.uri.sourceUserId == grantUri.sourceUserId
9227                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9228                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9229                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9230                     persistChanged |= perm.revokeModes(
9231                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9232                             targetPackage == null);
9233                     if (perm.modeFlags == 0) {
9234                         perms.removeAt(j);
9235                     }
9236                 }
9237             }
9238
9239             if (perms.isEmpty()) {
9240                 mGrantedUriPermissions.removeAt(i);
9241             }
9242         }
9243
9244         if (persistChanged) {
9245             schedulePersistUriGrants();
9246         }
9247     }
9248
9249     /**
9250      * @param uri This uri must NOT contain an embedded userId.
9251      * @param userId The userId in which the uri is to be resolved.
9252      */
9253     @Override
9254     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9255             final int modeFlags, int userId) {
9256         enforceNotIsolatedCaller("revokeUriPermission");
9257         synchronized(this) {
9258             final ProcessRecord r = getRecordForAppLocked(caller);
9259             if (r == null) {
9260                 throw new SecurityException("Unable to find app for caller "
9261                         + caller
9262                         + " when revoking permission to uri " + uri);
9263             }
9264             if (uri == null) {
9265                 Slog.w(TAG, "revokeUriPermission: null uri");
9266                 return;
9267             }
9268
9269             if (!Intent.isAccessUriMode(modeFlags)) {
9270                 return;
9271             }
9272
9273             final String authority = uri.getAuthority();
9274             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9275                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9276             if (pi == null) {
9277                 Slog.w(TAG, "No content provider found for permission revoke: "
9278                         + uri.toSafeString());
9279                 return;
9280             }
9281
9282             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9283                     modeFlags);
9284         }
9285     }
9286
9287     /**
9288      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9289      * given package.
9290      *
9291      * @param packageName Package name to match, or {@code null} to apply to all
9292      *            packages.
9293      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9294      *            to all users.
9295      * @param persistable If persistable grants should be removed.
9296      */
9297     private void removeUriPermissionsForPackageLocked(
9298             String packageName, int userHandle, boolean persistable) {
9299         if (userHandle == UserHandle.USER_ALL && packageName == null) {
9300             throw new IllegalArgumentException("Must narrow by either package or user");
9301         }
9302
9303         boolean persistChanged = false;
9304
9305         int N = mGrantedUriPermissions.size();
9306         for (int i = 0; i < N; i++) {
9307             final int targetUid = mGrantedUriPermissions.keyAt(i);
9308             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9309
9310             // Only inspect grants matching user
9311             if (userHandle == UserHandle.USER_ALL
9312                     || userHandle == UserHandle.getUserId(targetUid)) {
9313                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9314                     final UriPermission perm = it.next();
9315
9316                     // Only inspect grants matching package
9317                     if (packageName == null || perm.sourcePkg.equals(packageName)
9318                             || perm.targetPkg.equals(packageName)) {
9319                         // Hacky solution as part of fixing a security bug; ignore
9320                         // grants associated with DownloadManager so we don't have
9321                         // to immediately launch it to regrant the permissions
9322                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9323                                 && !persistable) continue;
9324
9325                         persistChanged |= perm.revokeModes(persistable
9326                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9327
9328                         // Only remove when no modes remain; any persisted grants
9329                         // will keep this alive.
9330                         if (perm.modeFlags == 0) {
9331                             it.remove();
9332                         }
9333                     }
9334                 }
9335
9336                 if (perms.isEmpty()) {
9337                     mGrantedUriPermissions.remove(targetUid);
9338                     N--;
9339                     i--;
9340                 }
9341             }
9342         }
9343
9344         if (persistChanged) {
9345             schedulePersistUriGrants();
9346         }
9347     }
9348
9349     @Override
9350     public IBinder newUriPermissionOwner(String name) {
9351         enforceNotIsolatedCaller("newUriPermissionOwner");
9352         synchronized(this) {
9353             UriPermissionOwner owner = new UriPermissionOwner(this, name);
9354             return owner.getExternalTokenLocked();
9355         }
9356     }
9357
9358     @Override
9359     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9360         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9361         synchronized(this) {
9362             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9363             if (r == null) {
9364                 throw new IllegalArgumentException("Activity does not exist; token="
9365                         + activityToken);
9366             }
9367             return r.getUriPermissionsLocked().getExternalTokenLocked();
9368         }
9369     }
9370     /**
9371      * @param uri This uri must NOT contain an embedded userId.
9372      * @param sourceUserId The userId in which the uri is to be resolved.
9373      * @param targetUserId The userId of the app that receives the grant.
9374      */
9375     @Override
9376     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9377             final int modeFlags, int sourceUserId, int targetUserId) {
9378         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9379                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9380                 "grantUriPermissionFromOwner", null);
9381         synchronized(this) {
9382             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9383             if (owner == null) {
9384                 throw new IllegalArgumentException("Unknown owner: " + token);
9385             }
9386             if (fromUid != Binder.getCallingUid()) {
9387                 if (Binder.getCallingUid() != myUid()) {
9388                     // Only system code can grant URI permissions on behalf
9389                     // of other users.
9390                     throw new SecurityException("nice try");
9391                 }
9392             }
9393             if (targetPkg == null) {
9394                 throw new IllegalArgumentException("null target");
9395             }
9396             if (uri == null) {
9397                 throw new IllegalArgumentException("null uri");
9398             }
9399
9400             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9401                     modeFlags, owner, targetUserId);
9402         }
9403     }
9404
9405     /**
9406      * @param uri This uri must NOT contain an embedded userId.
9407      * @param userId The userId in which the uri is to be resolved.
9408      */
9409     @Override
9410     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9411         synchronized(this) {
9412             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9413             if (owner == null) {
9414                 throw new IllegalArgumentException("Unknown owner: " + token);
9415             }
9416
9417             if (uri == null) {
9418                 owner.removeUriPermissionsLocked(mode);
9419             } else {
9420                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9421                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9422             }
9423         }
9424     }
9425
9426     private void schedulePersistUriGrants() {
9427         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9428             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9429                     10 * DateUtils.SECOND_IN_MILLIS);
9430         }
9431     }
9432
9433     private void writeGrantedUriPermissions() {
9434         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9435
9436         // Snapshot permissions so we can persist without lock
9437         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9438         synchronized (this) {
9439             final int size = mGrantedUriPermissions.size();
9440             for (int i = 0; i < size; i++) {
9441                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9442                 for (UriPermission perm : perms.values()) {
9443                     if (perm.persistedModeFlags != 0) {
9444                         persist.add(perm.snapshot());
9445                     }
9446                 }
9447             }
9448         }
9449
9450         FileOutputStream fos = null;
9451         try {
9452             fos = mGrantFile.startWrite();
9453
9454             XmlSerializer out = new FastXmlSerializer();
9455             out.setOutput(fos, StandardCharsets.UTF_8.name());
9456             out.startDocument(null, true);
9457             out.startTag(null, TAG_URI_GRANTS);
9458             for (UriPermission.Snapshot perm : persist) {
9459                 out.startTag(null, TAG_URI_GRANT);
9460                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9461                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9462                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9463                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9464                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9465                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9466                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9467                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9468                 out.endTag(null, TAG_URI_GRANT);
9469             }
9470             out.endTag(null, TAG_URI_GRANTS);
9471             out.endDocument();
9472
9473             mGrantFile.finishWrite(fos);
9474         } catch (IOException e) {
9475             if (fos != null) {
9476                 mGrantFile.failWrite(fos);
9477             }
9478         }
9479     }
9480
9481     private void readGrantedUriPermissionsLocked() {
9482         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9483
9484         final long now = System.currentTimeMillis();
9485
9486         FileInputStream fis = null;
9487         try {
9488             fis = mGrantFile.openRead();
9489             final XmlPullParser in = Xml.newPullParser();
9490             in.setInput(fis, StandardCharsets.UTF_8.name());
9491
9492             int type;
9493             while ((type = in.next()) != END_DOCUMENT) {
9494                 final String tag = in.getName();
9495                 if (type == START_TAG) {
9496                     if (TAG_URI_GRANT.equals(tag)) {
9497                         final int sourceUserId;
9498                         final int targetUserId;
9499                         final int userHandle = readIntAttribute(in,
9500                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9501                         if (userHandle != UserHandle.USER_NULL) {
9502                             // For backwards compatibility.
9503                             sourceUserId = userHandle;
9504                             targetUserId = userHandle;
9505                         } else {
9506                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9507                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9508                         }
9509                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9510                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9511                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9512                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9513                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9514                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9515
9516                         // Sanity check that provider still belongs to source package
9517                         // Both direct boot aware and unaware packages are fine as we
9518                         // will do filtering at query time to avoid multiple parsing.
9519                         final ProviderInfo pi = getProviderInfoLocked(
9520                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9521                                         | MATCH_DIRECT_BOOT_UNAWARE);
9522                         if (pi != null && sourcePkg.equals(pi.packageName)) {
9523                             int targetUid = -1;
9524                             try {
9525                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
9526                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9527                             } catch (RemoteException e) {
9528                             }
9529                             if (targetUid != -1) {
9530                                 final UriPermission perm = findOrCreateUriPermissionLocked(
9531                                         sourcePkg, targetPkg, targetUid,
9532                                         new GrantUri(sourceUserId, uri, prefix));
9533                                 perm.initPersistedModes(modeFlags, createdTime);
9534                             }
9535                         } else {
9536                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9537                                     + " but instead found " + pi);
9538                         }
9539                     }
9540                 }
9541             }
9542         } catch (FileNotFoundException e) {
9543             // Missing grants is okay
9544         } catch (IOException e) {
9545             Slog.wtf(TAG, "Failed reading Uri grants", e);
9546         } catch (XmlPullParserException e) {
9547             Slog.wtf(TAG, "Failed reading Uri grants", e);
9548         } finally {
9549             IoUtils.closeQuietly(fis);
9550         }
9551     }
9552
9553     /**
9554      * @param uri This uri must NOT contain an embedded userId.
9555      * @param userId The userId in which the uri is to be resolved.
9556      */
9557     @Override
9558     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9559         enforceNotIsolatedCaller("takePersistableUriPermission");
9560
9561         Preconditions.checkFlagsArgument(modeFlags,
9562                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9563
9564         synchronized (this) {
9565             final int callingUid = Binder.getCallingUid();
9566             boolean persistChanged = false;
9567             GrantUri grantUri = new GrantUri(userId, uri, false);
9568
9569             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9570                     new GrantUri(userId, uri, false));
9571             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9572                     new GrantUri(userId, uri, true));
9573
9574             final boolean exactValid = (exactPerm != null)
9575                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9576             final boolean prefixValid = (prefixPerm != null)
9577                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9578
9579             if (!(exactValid || prefixValid)) {
9580                 throw new SecurityException("No persistable permission grants found for UID "
9581                         + callingUid + " and Uri " + grantUri.toSafeString());
9582             }
9583
9584             if (exactValid) {
9585                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9586             }
9587             if (prefixValid) {
9588                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9589             }
9590
9591             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9592
9593             if (persistChanged) {
9594                 schedulePersistUriGrants();
9595             }
9596         }
9597     }
9598
9599     /**
9600      * @param uri This uri must NOT contain an embedded userId.
9601      * @param userId The userId in which the uri is to be resolved.
9602      */
9603     @Override
9604     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9605         enforceNotIsolatedCaller("releasePersistableUriPermission");
9606
9607         Preconditions.checkFlagsArgument(modeFlags,
9608                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9609
9610         synchronized (this) {
9611             final int callingUid = Binder.getCallingUid();
9612             boolean persistChanged = false;
9613
9614             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9615                     new GrantUri(userId, uri, false));
9616             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9617                     new GrantUri(userId, uri, true));
9618             if (exactPerm == null && prefixPerm == null) {
9619                 throw new SecurityException("No permission grants found for UID " + callingUid
9620                         + " and Uri " + uri.toSafeString());
9621             }
9622
9623             if (exactPerm != null) {
9624                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9625                 removeUriPermissionIfNeededLocked(exactPerm);
9626             }
9627             if (prefixPerm != null) {
9628                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9629                 removeUriPermissionIfNeededLocked(prefixPerm);
9630             }
9631
9632             if (persistChanged) {
9633                 schedulePersistUriGrants();
9634             }
9635         }
9636     }
9637
9638     /**
9639      * Prune any older {@link UriPermission} for the given UID until outstanding
9640      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9641      *
9642      * @return if any mutations occured that require persisting.
9643      */
9644     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9645         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9646         if (perms == null) return false;
9647         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9648
9649         final ArrayList<UriPermission> persisted = Lists.newArrayList();
9650         for (UriPermission perm : perms.values()) {
9651             if (perm.persistedModeFlags != 0) {
9652                 persisted.add(perm);
9653             }
9654         }
9655
9656         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9657         if (trimCount <= 0) return false;
9658
9659         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9660         for (int i = 0; i < trimCount; i++) {
9661             final UriPermission perm = persisted.get(i);
9662
9663             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9664                     "Trimming grant created at " + perm.persistedCreateTime);
9665
9666             perm.releasePersistableModes(~0);
9667             removeUriPermissionIfNeededLocked(perm);
9668         }
9669
9670         return true;
9671     }
9672
9673     @Override
9674     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9675             String packageName, boolean incoming) {
9676         enforceNotIsolatedCaller("getPersistedUriPermissions");
9677         Preconditions.checkNotNull(packageName, "packageName");
9678
9679         final int callingUid = Binder.getCallingUid();
9680         final int callingUserId = UserHandle.getUserId(callingUid);
9681         final IPackageManager pm = AppGlobals.getPackageManager();
9682         try {
9683             final int packageUid = pm.getPackageUid(packageName,
9684                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9685             if (packageUid != callingUid) {
9686                 throw new SecurityException(
9687                         "Package " + packageName + " does not belong to calling UID " + callingUid);
9688             }
9689         } catch (RemoteException e) {
9690             throw new SecurityException("Failed to verify package name ownership");
9691         }
9692
9693         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9694         synchronized (this) {
9695             if (incoming) {
9696                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9697                         callingUid);
9698                 if (perms == null) {
9699                     Slog.w(TAG, "No permission grants found for " + packageName);
9700                 } else {
9701                     for (UriPermission perm : perms.values()) {
9702                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9703                             result.add(perm.buildPersistedPublicApiObject());
9704                         }
9705                     }
9706                 }
9707             } else {
9708                 final int size = mGrantedUriPermissions.size();
9709                 for (int i = 0; i < size; i++) {
9710                     final ArrayMap<GrantUri, UriPermission> perms =
9711                             mGrantedUriPermissions.valueAt(i);
9712                     for (UriPermission perm : perms.values()) {
9713                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9714                             result.add(perm.buildPersistedPublicApiObject());
9715                         }
9716                     }
9717                 }
9718             }
9719         }
9720         return new ParceledListSlice<android.content.UriPermission>(result);
9721     }
9722
9723     @Override
9724     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9725             String packageName, int userId) {
9726         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9727                 "getGrantedUriPermissions");
9728
9729         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9730         synchronized (this) {
9731             final int size = mGrantedUriPermissions.size();
9732             for (int i = 0; i < size; i++) {
9733                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9734                 for (UriPermission perm : perms.values()) {
9735                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9736                             && perm.persistedModeFlags != 0) {
9737                         result.add(perm.buildPersistedPublicApiObject());
9738                     }
9739                 }
9740             }
9741         }
9742         return new ParceledListSlice<android.content.UriPermission>(result);
9743     }
9744
9745     @Override
9746     public void clearGrantedUriPermissions(String packageName, int userId) {
9747         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9748                 "clearGrantedUriPermissions");
9749         removeUriPermissionsForPackageLocked(packageName, userId, true);
9750     }
9751
9752     @Override
9753     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9754         synchronized (this) {
9755             ProcessRecord app =
9756                 who != null ? getRecordForAppLocked(who) : null;
9757             if (app == null) return;
9758
9759             Message msg = Message.obtain();
9760             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9761             msg.obj = app;
9762             msg.arg1 = waiting ? 1 : 0;
9763             mUiHandler.sendMessage(msg);
9764         }
9765     }
9766
9767     @Override
9768     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9769         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9770         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9771         outInfo.availMem = getFreeMemory();
9772         outInfo.totalMem = getTotalMemory();
9773         outInfo.threshold = homeAppMem;
9774         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9775         outInfo.hiddenAppThreshold = cachedAppMem;
9776         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9777                 ProcessList.SERVICE_ADJ);
9778         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9779                 ProcessList.VISIBLE_APP_ADJ);
9780         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9781                 ProcessList.FOREGROUND_APP_ADJ);
9782     }
9783
9784     // =========================================================
9785     // TASK MANAGEMENT
9786     // =========================================================
9787
9788     @Override
9789     public List<IBinder> getAppTasks(String callingPackage) {
9790         int callingUid = Binder.getCallingUid();
9791         long ident = Binder.clearCallingIdentity();
9792
9793         synchronized(this) {
9794             ArrayList<IBinder> list = new ArrayList<IBinder>();
9795             try {
9796                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9797
9798                 final int N = mRecentTasks.size();
9799                 for (int i = 0; i < N; i++) {
9800                     TaskRecord tr = mRecentTasks.get(i);
9801                     // Skip tasks that do not match the caller.  We don't need to verify
9802                     // callingPackage, because we are also limiting to callingUid and know
9803                     // that will limit to the correct security sandbox.
9804                     if (tr.effectiveUid != callingUid) {
9805                         continue;
9806                     }
9807                     Intent intent = tr.getBaseIntent();
9808                     if (intent == null ||
9809                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9810                         continue;
9811                     }
9812                     ActivityManager.RecentTaskInfo taskInfo =
9813                             createRecentTaskInfoFromTaskRecord(tr);
9814                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9815                     list.add(taskImpl.asBinder());
9816                 }
9817             } finally {
9818                 Binder.restoreCallingIdentity(ident);
9819             }
9820             return list;
9821         }
9822     }
9823
9824     @Override
9825     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9826         final int callingUid = Binder.getCallingUid();
9827         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9828
9829         synchronized(this) {
9830             if (DEBUG_ALL) Slog.v(
9831                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9832
9833             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9834                     callingUid);
9835
9836             // TODO: Improve with MRU list from all ActivityStacks.
9837             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9838         }
9839
9840         return list;
9841     }
9842
9843     /**
9844      * Creates a new RecentTaskInfo from a TaskRecord.
9845      */
9846     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9847         // Update the task description to reflect any changes in the task stack
9848         tr.updateTaskDescription();
9849
9850         // Compose the recent task info
9851         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9852         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9853         rti.persistentId = tr.taskId;
9854         rti.baseIntent = new Intent(tr.getBaseIntent());
9855         rti.origActivity = tr.origActivity;
9856         rti.realActivity = tr.realActivity;
9857         rti.description = tr.lastDescription;
9858         rti.stackId = tr.getStackId();
9859         rti.userId = tr.userId;
9860         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9861         rti.firstActiveTime = tr.firstActiveTime;
9862         rti.lastActiveTime = tr.lastActiveTime;
9863         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9864         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9865         rti.numActivities = 0;
9866         if (tr.mBounds != null) {
9867             rti.bounds = new Rect(tr.mBounds);
9868         }
9869         rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9870         rti.resizeMode = tr.mResizeMode;
9871
9872         ActivityRecord base = null;
9873         ActivityRecord top = null;
9874         ActivityRecord tmp;
9875
9876         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9877             tmp = tr.mActivities.get(i);
9878             if (tmp.finishing) {
9879                 continue;
9880             }
9881             base = tmp;
9882             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9883                 top = base;
9884             }
9885             rti.numActivities++;
9886         }
9887
9888         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9889         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9890
9891         return rti;
9892     }
9893
9894     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9895         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9896                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9897         if (!allowed) {
9898             if (checkPermission(android.Manifest.permission.GET_TASKS,
9899                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9900                 // Temporary compatibility: some existing apps on the system image may
9901                 // still be requesting the old permission and not switched to the new
9902                 // one; if so, we'll still allow them full access.  This means we need
9903                 // to see if they are holding the old permission and are a system app.
9904                 try {
9905                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9906                         allowed = true;
9907                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9908                                 + " is using old GET_TASKS but privileged; allowing");
9909                     }
9910                 } catch (RemoteException e) {
9911                 }
9912             }
9913         }
9914         if (!allowed) {
9915             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9916                     + " does not hold REAL_GET_TASKS; limiting output");
9917         }
9918         return allowed;
9919     }
9920
9921     @Override
9922     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9923             int userId) {
9924         final int callingUid = Binder.getCallingUid();
9925         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9926                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9927
9928         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9929         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9930         synchronized (this) {
9931             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9932                     callingUid);
9933             final boolean detailed = checkCallingPermission(
9934                     android.Manifest.permission.GET_DETAILED_TASKS)
9935                     == PackageManager.PERMISSION_GRANTED;
9936
9937             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9938                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9939                 return ParceledListSlice.emptyList();
9940             }
9941             mRecentTasks.loadUserRecentsLocked(userId);
9942
9943             final int recentsCount = mRecentTasks.size();
9944             ArrayList<ActivityManager.RecentTaskInfo> res =
9945                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9946
9947             final Set<Integer> includedUsers;
9948             if (includeProfiles) {
9949                 includedUsers = mUserController.getProfileIds(userId);
9950             } else {
9951                 includedUsers = new HashSet<>();
9952             }
9953             includedUsers.add(Integer.valueOf(userId));
9954
9955             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9956                 TaskRecord tr = mRecentTasks.get(i);
9957                 // Only add calling user or related users recent tasks
9958                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9959                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9960                     continue;
9961                 }
9962
9963                 if (tr.realActivitySuspended) {
9964                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9965                     continue;
9966                 }
9967
9968                 // Return the entry if desired by the caller.  We always return
9969                 // the first entry, because callers always expect this to be the
9970                 // foreground app.  We may filter others if the caller has
9971                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9972                 // we should exclude the entry.
9973
9974                 if (i == 0
9975                         || withExcluded
9976                         || (tr.intent == null)
9977                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9978                                 == 0)) {
9979                     if (!allowed) {
9980                         // If the caller doesn't have the GET_TASKS permission, then only
9981                         // allow them to see a small subset of tasks -- their own and home.
9982                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9983                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9984                             continue;
9985                         }
9986                     }
9987                     final ActivityStack stack = tr.getStack();
9988                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9989                         if (stack != null && stack.isHomeOrRecentsStack()) {
9990                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9991                                     "Skipping, home or recents stack task: " + tr);
9992                             continue;
9993                         }
9994                     }
9995                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9996                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9997                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9998                                     "Skipping, top task in docked stack: " + tr);
9999                             continue;
10000                         }
10001                     }
10002                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10003                         if (stack != null && stack.isPinnedStack()) {
10004                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10005                                     "Skipping, pinned stack task: " + tr);
10006                             continue;
10007                         }
10008                     }
10009                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10010                         // Don't include auto remove tasks that are finished or finishing.
10011                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10012                                 "Skipping, auto-remove without activity: " + tr);
10013                         continue;
10014                     }
10015                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10016                             && !tr.isAvailable) {
10017                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10018                                 "Skipping, unavail real act: " + tr);
10019                         continue;
10020                     }
10021
10022                     if (!tr.mUserSetupComplete) {
10023                         // Don't include task launched while user is not done setting-up.
10024                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10025                                 "Skipping, user setup not complete: " + tr);
10026                         continue;
10027                     }
10028
10029                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10030                     if (!detailed) {
10031                         rti.baseIntent.replaceExtras((Bundle)null);
10032                     }
10033
10034                     res.add(rti);
10035                     maxNum--;
10036                 }
10037             }
10038             return new ParceledListSlice<>(res);
10039         }
10040     }
10041
10042     @Override
10043     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10044         synchronized (this) {
10045             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10046                     "getTaskThumbnail()");
10047             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10048                     id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10049             if (tr != null) {
10050                 return tr.getTaskThumbnailLocked();
10051             }
10052         }
10053         return null;
10054     }
10055
10056     @Override
10057     public ActivityManager.TaskDescription getTaskDescription(int id) {
10058         synchronized (this) {
10059             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10060                     "getTaskDescription()");
10061             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10062                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10063             if (tr != null) {
10064                 return tr.lastTaskDescription;
10065             }
10066         }
10067         return null;
10068     }
10069
10070     @Override
10071     public int addAppTask(IBinder activityToken, Intent intent,
10072             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10073         final int callingUid = Binder.getCallingUid();
10074         final long callingIdent = Binder.clearCallingIdentity();
10075
10076         try {
10077             synchronized (this) {
10078                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10079                 if (r == null) {
10080                     throw new IllegalArgumentException("Activity does not exist; token="
10081                             + activityToken);
10082                 }
10083                 ComponentName comp = intent.getComponent();
10084                 if (comp == null) {
10085                     throw new IllegalArgumentException("Intent " + intent
10086                             + " must specify explicit component");
10087                 }
10088                 if (thumbnail.getWidth() != mThumbnailWidth
10089                         || thumbnail.getHeight() != mThumbnailHeight) {
10090                     throw new IllegalArgumentException("Bad thumbnail size: got "
10091                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10092                             + mThumbnailWidth + "x" + mThumbnailHeight);
10093                 }
10094                 if (intent.getSelector() != null) {
10095                     intent.setSelector(null);
10096                 }
10097                 if (intent.getSourceBounds() != null) {
10098                     intent.setSourceBounds(null);
10099                 }
10100                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10101                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10102                         // The caller has added this as an auto-remove task...  that makes no
10103                         // sense, so turn off auto-remove.
10104                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10105                     }
10106                 }
10107                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10108                     mLastAddedTaskActivity = null;
10109                 }
10110                 ActivityInfo ainfo = mLastAddedTaskActivity;
10111                 if (ainfo == null) {
10112                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10113                             comp, 0, UserHandle.getUserId(callingUid));
10114                     if (ainfo.applicationInfo.uid != callingUid) {
10115                         throw new SecurityException(
10116                                 "Can't add task for another application: target uid="
10117                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10118                     }
10119                 }
10120
10121                 TaskRecord task = new TaskRecord(this,
10122                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10123                         ainfo, intent, description, new TaskThumbnailInfo());
10124
10125                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10126                 if (trimIdx >= 0) {
10127                     // If this would have caused a trim, then we'll abort because that
10128                     // means it would be added at the end of the list but then just removed.
10129                     return INVALID_TASK_ID;
10130                 }
10131
10132                 final int N = mRecentTasks.size();
10133                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10134                     final TaskRecord tr = mRecentTasks.remove(N - 1);
10135                     tr.removedFromRecents();
10136                 }
10137
10138                 task.inRecents = true;
10139                 mRecentTasks.add(task);
10140                 r.getStack().addTask(task, false, "addAppTask");
10141
10142                 task.setLastThumbnailLocked(thumbnail);
10143                 task.freeLastThumbnail();
10144                 return task.taskId;
10145             }
10146         } finally {
10147             Binder.restoreCallingIdentity(callingIdent);
10148         }
10149     }
10150
10151     @Override
10152     public Point getAppTaskThumbnailSize() {
10153         synchronized (this) {
10154             return new Point(mThumbnailWidth,  mThumbnailHeight);
10155         }
10156     }
10157
10158     @Override
10159     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10160         synchronized (this) {
10161             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10162             if (r != null) {
10163                 r.setTaskDescription(td);
10164                 final TaskRecord task = r.getTask();
10165                 task.updateTaskDescription();
10166                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10167             }
10168         }
10169     }
10170
10171     @Override
10172     public void setTaskResizeable(int taskId, int resizeableMode) {
10173         synchronized (this) {
10174             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10175                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10176             if (task == null) {
10177                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10178                 return;
10179             }
10180             task.setResizeMode(resizeableMode);
10181         }
10182     }
10183
10184     @Override
10185     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10186         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10187         long ident = Binder.clearCallingIdentity();
10188         try {
10189             synchronized (this) {
10190                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10191                 if (task == null) {
10192                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10193                     return;
10194                 }
10195                 // Place the task in the right stack if it isn't there already based on
10196                 // the requested bounds.
10197                 // The stack transition logic is:
10198                 // - a null bounds on a freeform task moves that task to fullscreen
10199                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10200                 //   that task to freeform
10201                 // - otherwise the task is not moved
10202                 int stackId = task.getStackId();
10203                 if (!StackId.isTaskResizeAllowed(stackId)) {
10204                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10205                 }
10206                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10207                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10208                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10209                     stackId = FREEFORM_WORKSPACE_STACK_ID;
10210                 }
10211
10212                 // Reparent the task to the right stack if necessary
10213                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10214                 if (stackId != task.getStackId()) {
10215                     // Defer resume until the task is resized below
10216                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10217                             DEFER_RESUME, "resizeTask");
10218                     preserveWindow = false;
10219                 }
10220
10221                 // After reparenting (which only resizes the task to the stack bounds), resize the
10222                 // task to the actual bounds provided
10223                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10224             }
10225         } finally {
10226             Binder.restoreCallingIdentity(ident);
10227         }
10228     }
10229
10230     @Override
10231     public Rect getTaskBounds(int taskId) {
10232         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10233         long ident = Binder.clearCallingIdentity();
10234         Rect rect = new Rect();
10235         try {
10236             synchronized (this) {
10237                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10238                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10239                 if (task == null) {
10240                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10241                     return rect;
10242                 }
10243                 if (task.getStack() != null) {
10244                     // Return the bounds from window manager since it will be adjusted for various
10245                     // things like the presense of a docked stack for tasks that aren't resizeable.
10246                     task.getWindowContainerBounds(rect);
10247                 } else {
10248                     // Task isn't in window manager yet since it isn't associated with a stack.
10249                     // Return the persist value from activity manager
10250                     if (task.mBounds != null) {
10251                         rect.set(task.mBounds);
10252                     } else if (task.mLastNonFullscreenBounds != null) {
10253                         rect.set(task.mLastNonFullscreenBounds);
10254                     }
10255                 }
10256             }
10257         } finally {
10258             Binder.restoreCallingIdentity(ident);
10259         }
10260         return rect;
10261     }
10262
10263     @Override
10264     public void cancelTaskWindowTransition(int taskId) {
10265         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10266         final long ident = Binder.clearCallingIdentity();
10267         try {
10268             synchronized (this) {
10269                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10270                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10271                 if (task == null) {
10272                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10273                     return;
10274                 }
10275                 task.cancelWindowTransition();
10276             }
10277         } finally {
10278             Binder.restoreCallingIdentity(ident);
10279         }
10280     }
10281
10282     @Override
10283     public void cancelTaskThumbnailTransition(int taskId) {
10284         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10285         final long ident = Binder.clearCallingIdentity();
10286         try {
10287             synchronized (this) {
10288                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10289                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10290                 if (task == null) {
10291                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10292                     return;
10293                 }
10294                 task.cancelThumbnailTransition();
10295             }
10296         } finally {
10297             Binder.restoreCallingIdentity(ident);
10298         }
10299     }
10300
10301     @Override
10302     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10303         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10304         final long ident = Binder.clearCallingIdentity();
10305         try {
10306             final TaskRecord task;
10307             synchronized (this) {
10308                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10309                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10310                 if (task == null) {
10311                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10312                     return null;
10313                 }
10314             }
10315             // Don't call this while holding the lock as this operation might hit the disk.
10316             return task.getSnapshot(reducedResolution);
10317         } finally {
10318             Binder.restoreCallingIdentity(ident);
10319         }
10320     }
10321
10322     @Override
10323     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10324         if (userId != UserHandle.getCallingUserId()) {
10325             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10326                     "getTaskDescriptionIcon");
10327         }
10328         final File passedIconFile = new File(filePath);
10329         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10330                 passedIconFile.getName());
10331         if (!legitIconFile.getPath().equals(filePath)
10332                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10333             throw new IllegalArgumentException("Bad file path: " + filePath
10334                     + " passed for userId " + userId);
10335         }
10336         return mRecentTasks.getTaskDescriptionIcon(filePath);
10337     }
10338
10339     @Override
10340     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10341             throws RemoteException {
10342         final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10343         if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10344                 activityOptions.getCustomInPlaceResId() == 0) {
10345             throw new IllegalArgumentException("Expected in-place ActivityOption " +
10346                     "with valid animation");
10347         }
10348         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10349         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10350                 activityOptions.getCustomInPlaceResId());
10351         mWindowManager.executeAppTransition();
10352     }
10353
10354     private void removeTasksByPackageNameLocked(String packageName, int userId) {
10355         // Remove all tasks with activities in the specified package from the list of recent tasks
10356         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10357             TaskRecord tr = mRecentTasks.get(i);
10358             if (tr.userId != userId) continue;
10359
10360             ComponentName cn = tr.intent.getComponent();
10361             if (cn != null && cn.getPackageName().equals(packageName)) {
10362                 // If the package name matches, remove the task.
10363                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10364             }
10365         }
10366     }
10367
10368     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10369             int userId) {
10370
10371         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10372             TaskRecord tr = mRecentTasks.get(i);
10373             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10374                 continue;
10375             }
10376
10377             ComponentName cn = tr.intent.getComponent();
10378             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10379                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10380             if (sameComponent) {
10381                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10382             }
10383         }
10384     }
10385
10386     @Override
10387     public void removeStack(int stackId) {
10388         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10389         if (StackId.isHomeOrRecentsStack(stackId)) {
10390             throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10391         }
10392
10393         synchronized (this) {
10394             final long ident = Binder.clearCallingIdentity();
10395             try {
10396                 mStackSupervisor.removeStackLocked(stackId);
10397             } finally {
10398                 Binder.restoreCallingIdentity(ident);
10399             }
10400         }
10401     }
10402
10403     @Override
10404     public void moveStackToDisplay(int stackId, int displayId) {
10405         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10406
10407         synchronized (this) {
10408             final long ident = Binder.clearCallingIdentity();
10409             try {
10410                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10411                         + " to displayId=" + displayId);
10412                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10413             } finally {
10414                 Binder.restoreCallingIdentity(ident);
10415             }
10416         }
10417     }
10418
10419     @Override
10420     public boolean removeTask(int taskId) {
10421         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10422         synchronized (this) {
10423             final long ident = Binder.clearCallingIdentity();
10424             try {
10425                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10426             } finally {
10427                 Binder.restoreCallingIdentity(ident);
10428             }
10429         }
10430     }
10431
10432     /**
10433      * TODO: Add mController hook
10434      */
10435     @Override
10436     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10437         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10438
10439         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10440         synchronized(this) {
10441             moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10442         }
10443     }
10444
10445     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10446         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10447
10448         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10449                 Binder.getCallingUid(), -1, -1, "Task to front")) {
10450             ActivityOptions.abort(options);
10451             return;
10452         }
10453         final long origId = Binder.clearCallingIdentity();
10454         try {
10455             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10456             if (task == null) {
10457                 Slog.d(TAG, "Could not find task for id: "+ taskId);
10458                 return;
10459             }
10460             if (mStackSupervisor.isLockTaskModeViolation(task)) {
10461                 mStackSupervisor.showLockTaskToast();
10462                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10463                 return;
10464             }
10465             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10466             if (prev != null) {
10467                 task.setTaskToReturnTo(prev);
10468             }
10469             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10470                     false /* forceNonResizable */);
10471
10472             final ActivityRecord topActivity = task.getTopActivity();
10473             if (topActivity != null) {
10474
10475                 // We are reshowing a task, use a starting window to hide the initial draw delay
10476                 // so the transition can start earlier.
10477                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10478                         true /* taskSwitch */, fromRecents);
10479             }
10480         } finally {
10481             Binder.restoreCallingIdentity(origId);
10482         }
10483         ActivityOptions.abort(options);
10484     }
10485
10486     /**
10487      * Attempts to move a task backwards in z-order (the order of activities within the task is
10488      * unchanged).
10489      *
10490      * There are several possible results of this call:
10491      * - if the task is locked, then we will show the lock toast
10492      * - if there is a task behind the provided task, then that task is made visible and resumed as
10493      *   this task is moved to the back
10494      * - otherwise, if there are no other tasks in the stack:
10495      *     - if this task is in the pinned stack, then we remove the stack completely, which will
10496      *       have the effect of moving the task to the top or bottom of the fullscreen stack
10497      *       (depending on whether it is visible)
10498      *     - otherwise, we simply return home and hide this task
10499      *
10500      * @param token A reference to the activity we wish to move
10501      * @param nonRoot If false then this only works if the activity is the root
10502      *                of a task; if true it will work for any activity in a task.
10503      * @return Returns true if the move completed, false if not.
10504      */
10505     @Override
10506     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10507         enforceNotIsolatedCaller("moveActivityTaskToBack");
10508         synchronized(this) {
10509             final long origId = Binder.clearCallingIdentity();
10510             try {
10511                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10512                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10513                 if (task != null) {
10514                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10515                 }
10516             } finally {
10517                 Binder.restoreCallingIdentity(origId);
10518             }
10519         }
10520         return false;
10521     }
10522
10523     @Override
10524     public void moveTaskBackwards(int task) {
10525         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10526                 "moveTaskBackwards()");
10527
10528         synchronized(this) {
10529             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10530                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
10531                 return;
10532             }
10533             final long origId = Binder.clearCallingIdentity();
10534             moveTaskBackwardsLocked(task);
10535             Binder.restoreCallingIdentity(origId);
10536         }
10537     }
10538
10539     private final void moveTaskBackwardsLocked(int task) {
10540         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10541     }
10542
10543     @Override
10544     public int createStackOnDisplay(int displayId) throws RemoteException {
10545         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10546         synchronized (this) {
10547             final int stackId = mStackSupervisor.getNextStackId();
10548             final ActivityStack stack =
10549                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10550             if (stack == null) {
10551                 return INVALID_STACK_ID;
10552             }
10553             return stack.mStackId;
10554         }
10555     }
10556
10557     @Override
10558     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10559         synchronized (this) {
10560             final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10561             if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10562                 return stack.mDisplayId;
10563             }
10564             return DEFAULT_DISPLAY;
10565         }
10566     }
10567
10568     @Override
10569     public int getActivityStackId(IBinder token) throws RemoteException {
10570         synchronized (this) {
10571             ActivityStack stack = ActivityRecord.getStackLocked(token);
10572             if (stack == null) {
10573                 return INVALID_STACK_ID;
10574             }
10575             return stack.mStackId;
10576         }
10577     }
10578
10579     @Override
10580     public void exitFreeformMode(IBinder token) throws RemoteException {
10581         synchronized (this) {
10582             long ident = Binder.clearCallingIdentity();
10583             try {
10584                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10585                 if (r == null) {
10586                     throw new IllegalArgumentException(
10587                             "exitFreeformMode: No activity record matching token=" + token);
10588                 }
10589
10590                 final ActivityStack stack = r.getStack();
10591                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10592                     throw new IllegalStateException(
10593                             "exitFreeformMode: You can only go fullscreen from freeform.");
10594                 }
10595
10596                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10597                 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10598                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10599             } finally {
10600                 Binder.restoreCallingIdentity(ident);
10601             }
10602         }
10603     }
10604
10605     @Override
10606     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10607         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10608         if (StackId.isHomeOrRecentsStack(stackId)) {
10609             throw new IllegalArgumentException(
10610                     "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10611         }
10612         synchronized (this) {
10613             long ident = Binder.clearCallingIdentity();
10614             try {
10615                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10616                 if (task == null) {
10617                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10618                     return;
10619                 }
10620
10621                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10622                         + " to stackId=" + stackId + " toTop=" + toTop);
10623                 if (stackId == DOCKED_STACK_ID) {
10624                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10625                             null /* initialBounds */);
10626                 }
10627                 task.reparent(stackId, toTop,
10628                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10629             } finally {
10630                 Binder.restoreCallingIdentity(ident);
10631             }
10632         }
10633     }
10634
10635     @Override
10636     public void swapDockedAndFullscreenStack() throws RemoteException {
10637         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10638         synchronized (this) {
10639             long ident = Binder.clearCallingIdentity();
10640             try {
10641                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10642                         FULLSCREEN_WORKSPACE_STACK_ID);
10643                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10644                         : null;
10645                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10646                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10647                         : null;
10648                 if (topTask == null || tasks == null || tasks.size() == 0) {
10649                     Slog.w(TAG,
10650                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
10651                     return;
10652                 }
10653
10654                 // TODO: App transition
10655                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10656
10657                 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10658                 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10659                         DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10660                 final int size = tasks.size();
10661                 for (int i = 0; i < size; i++) {
10662                     final int id = tasks.get(i).taskId;
10663                     if (id == topTask.taskId) {
10664                         continue;
10665                     }
10666
10667                     // Defer the resume until after all the tasks have been moved
10668                     tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10669                             REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10670                             "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10671                 }
10672
10673                 // Because we deferred the resume to avoid conflicts with stack switches while
10674                 // resuming, we need to do it after all the tasks are moved.
10675                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10676                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10677
10678                 mWindowManager.executeAppTransition();
10679             } finally {
10680                 Binder.restoreCallingIdentity(ident);
10681             }
10682         }
10683     }
10684
10685     /**
10686      * Moves the input task to the docked stack.
10687      *
10688      * @param taskId Id of task to move.
10689      * @param createMode The mode the docked stack should be created in if it doesn't exist
10690      *                   already. See
10691      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10692      *                   and
10693      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10694      * @param toTop If the task and stack should be moved to the top.
10695      * @param animate Whether we should play an animation for the moving the task
10696      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10697      *                      docked stack. Pass {@code null} to use default bounds.
10698      */
10699     @Override
10700     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10701             Rect initialBounds) {
10702         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10703         synchronized (this) {
10704             long ident = Binder.clearCallingIdentity();
10705             try {
10706                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10707                 if (task == null) {
10708                     Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10709                     return false;
10710                 }
10711
10712                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10713                         + " to createMode=" + createMode + " toTop=" + toTop);
10714                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10715
10716                 // Defer resuming until we move the home stack to the front below
10717                 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10718                         REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10719                         "moveTaskToDockedStack");
10720                 if (moved) {
10721                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10722                 }
10723                 return moved;
10724             } finally {
10725                 Binder.restoreCallingIdentity(ident);
10726             }
10727         }
10728     }
10729
10730     /**
10731      * Moves the top activity in the input stackId to the pinned stack.
10732      *
10733      * @param stackId Id of stack to move the top activity to pinned stack.
10734      * @param bounds Bounds to use for pinned stack.
10735      *
10736      * @return True if the top activity of the input stack was successfully moved to the pinned
10737      *          stack.
10738      */
10739     @Override
10740     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10741         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10742         synchronized (this) {
10743             if (!mSupportsPictureInPicture) {
10744                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10745                         + "Device doesn't support picture-in-picture mode");
10746             }
10747
10748             long ident = Binder.clearCallingIdentity();
10749             try {
10750                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10751             } finally {
10752                 Binder.restoreCallingIdentity(ident);
10753             }
10754         }
10755     }
10756
10757     @Override
10758     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10759             boolean preserveWindows, boolean animate, int animationDuration) {
10760         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10761         long ident = Binder.clearCallingIdentity();
10762         try {
10763             synchronized (this) {
10764                 if (animate) {
10765                     if (stackId == PINNED_STACK_ID) {
10766                         final PinnedActivityStack pinnedStack =
10767                                 mStackSupervisor.getStack(PINNED_STACK_ID);
10768                         if (pinnedStack != null) {
10769                             pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10770                                     destBounds, animationDuration, false /* fromFullscreen */);
10771                         }
10772                     } else {
10773                         throw new IllegalArgumentException("Stack: " + stackId
10774                                 + " doesn't support animated resize.");
10775                     }
10776                 } else {
10777                     mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10778                             null /* tempTaskInsetBounds */, preserveWindows,
10779                             allowResizeInDockedMode, !DEFER_RESUME);
10780                 }
10781             }
10782         } finally {
10783             Binder.restoreCallingIdentity(ident);
10784         }
10785     }
10786
10787     @Override
10788     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10789             Rect tempDockedTaskInsetBounds,
10790             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10791         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10792                 "resizeDockedStack()");
10793         long ident = Binder.clearCallingIdentity();
10794         try {
10795             synchronized (this) {
10796                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10797                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10798                         PRESERVE_WINDOWS);
10799             }
10800         } finally {
10801             Binder.restoreCallingIdentity(ident);
10802         }
10803     }
10804
10805     @Override
10806     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10807         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10808                 "resizePinnedStack()");
10809         final long ident = Binder.clearCallingIdentity();
10810         try {
10811             synchronized (this) {
10812                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10813             }
10814         } finally {
10815             Binder.restoreCallingIdentity(ident);
10816         }
10817     }
10818
10819     /**
10820      * Try to place task to provided position. The final position might be different depending on
10821      * current user and stacks state. The task will be moved to target stack if it's currently in
10822      * different stack.
10823      */
10824     @Override
10825     public void positionTaskInStack(int taskId, int stackId, int position) {
10826         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10827         if (StackId.isHomeOrRecentsStack(stackId)) {
10828             throw new IllegalArgumentException(
10829                     "positionTaskInStack: Attempt to change the position of task "
10830                     + taskId + " in/to home/recents stack");
10831         }
10832         synchronized (this) {
10833             long ident = Binder.clearCallingIdentity();
10834             try {
10835                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10836                         + taskId + " in stackId=" + stackId + " at position=" + position);
10837                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10838                 if (task == null) {
10839                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
10840                             + taskId);
10841                 }
10842
10843                 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10844                         !ON_TOP);
10845
10846                 // TODO: Have the callers of this API call a separate reparent method if that is
10847                 // what they intended to do vs. having this method also do reparenting.
10848                 if (task.getStack() == stack) {
10849                     // Change position in current stack.
10850                     stack.positionChildAt(task, position);
10851                 } else {
10852                     // Reparent to new stack.
10853                     task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10854                             !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10855                 }
10856             } finally {
10857                 Binder.restoreCallingIdentity(ident);
10858             }
10859         }
10860     }
10861
10862     @Override
10863     public List<StackInfo> getAllStackInfos() {
10864         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10865         long ident = Binder.clearCallingIdentity();
10866         try {
10867             synchronized (this) {
10868                 return mStackSupervisor.getAllStackInfosLocked();
10869             }
10870         } finally {
10871             Binder.restoreCallingIdentity(ident);
10872         }
10873     }
10874
10875     @Override
10876     public StackInfo getStackInfo(int stackId) {
10877         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10878         long ident = Binder.clearCallingIdentity();
10879         try {
10880             synchronized (this) {
10881                 return mStackSupervisor.getStackInfoLocked(stackId);
10882             }
10883         } finally {
10884             Binder.restoreCallingIdentity(ident);
10885         }
10886     }
10887
10888     @Override
10889     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10890         synchronized(this) {
10891             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10892         }
10893     }
10894
10895     @Override
10896     public void updateDeviceOwner(String packageName) {
10897         final int callingUid = Binder.getCallingUid();
10898         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10899             throw new SecurityException("updateDeviceOwner called from non-system process");
10900         }
10901         synchronized (this) {
10902             mDeviceOwnerName = packageName;
10903         }
10904     }
10905
10906     @Override
10907     public void updateLockTaskPackages(int userId, String[] packages) {
10908         final int callingUid = Binder.getCallingUid();
10909         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10910             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10911                     "updateLockTaskPackages()");
10912         }
10913         synchronized (this) {
10914             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10915                     Arrays.toString(packages));
10916             mLockTaskPackages.put(userId, packages);
10917             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10918         }
10919     }
10920
10921
10922     void startLockTaskModeLocked(TaskRecord task) {
10923         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10924         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10925             return;
10926         }
10927
10928         // When a task is locked, dismiss the pinned stack if it exists
10929         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10930                 PINNED_STACK_ID);
10931         if (pinnedStack != null) {
10932             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10933         }
10934
10935         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10936         // is initiated by system after the pinning request was shown and locked mode is initiated
10937         // by an authorized app directly
10938         final int callingUid = Binder.getCallingUid();
10939         boolean isSystemInitiated = callingUid == SYSTEM_UID;
10940         long ident = Binder.clearCallingIdentity();
10941         try {
10942             if (!isSystemInitiated) {
10943                 task.mLockTaskUid = callingUid;
10944                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10945                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10946                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10947                     StatusBarManagerInternal statusBarManager =
10948                             LocalServices.getService(StatusBarManagerInternal.class);
10949                     if (statusBarManager != null) {
10950                         statusBarManager.showScreenPinningRequest(task.taskId);
10951                     }
10952                     return;
10953                 }
10954
10955                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10956                 if (stack == null || task != stack.topTask()) {
10957                     throw new IllegalArgumentException("Invalid task, not in foreground");
10958                 }
10959             }
10960             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10961                     "Locking fully");
10962             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10963                     ActivityManager.LOCK_TASK_MODE_PINNED :
10964                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10965                     "startLockTask", true);
10966         } finally {
10967             Binder.restoreCallingIdentity(ident);
10968         }
10969     }
10970
10971     @Override
10972     public void startLockTaskModeById(int taskId) {
10973         synchronized (this) {
10974             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10975             if (task != null) {
10976                 startLockTaskModeLocked(task);
10977             }
10978         }
10979     }
10980
10981     @Override
10982     public void startLockTaskModeByToken(IBinder token) {
10983         synchronized (this) {
10984             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10985             if (r == null) {
10986                 return;
10987             }
10988             final TaskRecord task = r.getTask();
10989             if (task != null) {
10990                 startLockTaskModeLocked(task);
10991             }
10992         }
10993     }
10994
10995     @Override
10996     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10997         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10998         // This makes inner call to look as if it was initiated by system.
10999         long ident = Binder.clearCallingIdentity();
11000         try {
11001             synchronized (this) {
11002                 startLockTaskModeById(taskId);
11003             }
11004         } finally {
11005             Binder.restoreCallingIdentity(ident);
11006         }
11007     }
11008
11009     @Override
11010     public void stopLockTaskMode() {
11011         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11012         if (lockTask == null) {
11013             // Our work here is done.
11014             return;
11015         }
11016
11017         final int callingUid = Binder.getCallingUid();
11018         final int lockTaskUid = lockTask.mLockTaskUid;
11019         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11020         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11021             // Done.
11022             return;
11023         } else {
11024             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11025             // It is possible lockTaskMode was started by the system process because
11026             // android:lockTaskMode is set to a locking value in the application manifest
11027             // instead of the app calling startLockTaskMode. In this case
11028             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11029             // {@link TaskRecord.effectiveUid} instead. Also caller with
11030             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11031             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11032                     && callingUid != lockTaskUid
11033                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11034                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11035                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11036             }
11037         }
11038         long ident = Binder.clearCallingIdentity();
11039         try {
11040             Log.d(TAG, "stopLockTaskMode");
11041             // Stop lock task
11042             synchronized (this) {
11043                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11044                         "stopLockTask", true);
11045             }
11046             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11047             if (tm != null) {
11048                 tm.showInCallScreen(false);
11049             }
11050         } finally {
11051             Binder.restoreCallingIdentity(ident);
11052         }
11053     }
11054
11055     /**
11056      * This API should be called by SystemUI only when user perform certain action to dismiss
11057      * lock task mode. We should only dismiss pinned lock task mode in this case.
11058      */
11059     @Override
11060     public void stopSystemLockTaskMode() throws RemoteException {
11061         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11062             stopLockTaskMode();
11063         } else {
11064             mStackSupervisor.showLockTaskToast();
11065         }
11066     }
11067
11068     @Override
11069     public boolean isInLockTaskMode() {
11070         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11071     }
11072
11073     @Override
11074     public int getLockTaskModeState() {
11075         synchronized (this) {
11076             return mStackSupervisor.getLockTaskModeState();
11077         }
11078     }
11079
11080     @Override
11081     public void showLockTaskEscapeMessage(IBinder token) {
11082         synchronized (this) {
11083             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11084             if (r == null) {
11085                 return;
11086             }
11087             mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11088         }
11089     }
11090
11091     @Override
11092     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11093             throws RemoteException {
11094         synchronized (this) {
11095             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11096             if (r == null) {
11097                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11098                         + token);
11099                 return;
11100             }
11101             final long origId = Binder.clearCallingIdentity();
11102             try {
11103                 r.setDisablePreviewScreenshots(disable);
11104             } finally {
11105                 Binder.restoreCallingIdentity(origId);
11106             }
11107         }
11108     }
11109
11110     // =========================================================
11111     // CONTENT PROVIDERS
11112     // =========================================================
11113
11114     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11115         List<ProviderInfo> providers = null;
11116         try {
11117             providers = AppGlobals.getPackageManager()
11118                     .queryContentProviders(app.processName, app.uid,
11119                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11120                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11121                     .getList();
11122         } catch (RemoteException ex) {
11123         }
11124         if (DEBUG_MU) Slog.v(TAG_MU,
11125                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11126         int userId = app.userId;
11127         if (providers != null) {
11128             int N = providers.size();
11129             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11130             for (int i=0; i<N; i++) {
11131                 // TODO: keep logic in sync with installEncryptionUnawareProviders
11132                 ProviderInfo cpi =
11133                     (ProviderInfo)providers.get(i);
11134                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11135                         cpi.name, cpi.flags);
11136                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11137                     // This is a singleton provider, but a user besides the
11138                     // default user is asking to initialize a process it runs
11139                     // in...  well, no, it doesn't actually run in this process,
11140                     // it runs in the process of the default user.  Get rid of it.
11141                     providers.remove(i);
11142                     N--;
11143                     i--;
11144                     continue;
11145                 }
11146
11147                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11148                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11149                 if (cpr == null) {
11150                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11151                     mProviderMap.putProviderByClass(comp, cpr);
11152                 }
11153                 if (DEBUG_MU) Slog.v(TAG_MU,
11154                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11155                 app.pubProviders.put(cpi.name, cpr);
11156                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11157                     // Don't add this if it is a platform component that is marked
11158                     // to run in multiple processes, because this is actually
11159                     // part of the framework so doesn't make sense to track as a
11160                     // separate apk in the process.
11161                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11162                             mProcessStats);
11163                 }
11164                 notifyPackageUse(cpi.applicationInfo.packageName,
11165                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11166             }
11167         }
11168         return providers;
11169     }
11170
11171     /**
11172      * Check if the calling UID has a possible chance at accessing the provider
11173      * at the given authority and user.
11174      */
11175     public String checkContentProviderAccess(String authority, int userId) {
11176         if (userId == UserHandle.USER_ALL) {
11177             mContext.enforceCallingOrSelfPermission(
11178                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11179             userId = UserHandle.getCallingUserId();
11180         }
11181
11182         ProviderInfo cpi = null;
11183         try {
11184             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11185                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11186                             | PackageManager.MATCH_DISABLED_COMPONENTS
11187                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
11188                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11189                     userId);
11190         } catch (RemoteException ignored) {
11191         }
11192         if (cpi == null) {
11193             return "Failed to find provider " + authority + " for user " + userId
11194                     + "; expected to find a valid ContentProvider for this authority";
11195         }
11196
11197         ProcessRecord r = null;
11198         synchronized (mPidsSelfLocked) {
11199             r = mPidsSelfLocked.get(Binder.getCallingPid());
11200         }
11201         if (r == null) {
11202             return "Failed to find PID " + Binder.getCallingPid();
11203         }
11204
11205         synchronized (this) {
11206             return checkContentProviderPermissionLocked(cpi, r, userId, true);
11207         }
11208     }
11209
11210     /**
11211      * Check if {@link ProcessRecord} has a possible chance at accessing the
11212      * given {@link ProviderInfo}. Final permission checking is always done
11213      * in {@link ContentProvider}.
11214      */
11215     private final String checkContentProviderPermissionLocked(
11216             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11217         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11218         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11219         boolean checkedGrants = false;
11220         if (checkUser) {
11221             // Looking for cross-user grants before enforcing the typical cross-users permissions
11222             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11223             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11224                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11225                     return null;
11226                 }
11227                 checkedGrants = true;
11228             }
11229             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11230                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11231             if (userId != tmpTargetUserId) {
11232                 // When we actually went to determine the final targer user ID, this ended
11233                 // up different than our initial check for the authority.  This is because
11234                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11235                 // SELF.  So we need to re-check the grants again.
11236                 checkedGrants = false;
11237             }
11238         }
11239         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11240                 cpi.applicationInfo.uid, cpi.exported)
11241                 == PackageManager.PERMISSION_GRANTED) {
11242             return null;
11243         }
11244         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11245                 cpi.applicationInfo.uid, cpi.exported)
11246                 == PackageManager.PERMISSION_GRANTED) {
11247             return null;
11248         }
11249
11250         PathPermission[] pps = cpi.pathPermissions;
11251         if (pps != null) {
11252             int i = pps.length;
11253             while (i > 0) {
11254                 i--;
11255                 PathPermission pp = pps[i];
11256                 String pprperm = pp.getReadPermission();
11257                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11258                         cpi.applicationInfo.uid, cpi.exported)
11259                         == PackageManager.PERMISSION_GRANTED) {
11260                     return null;
11261                 }
11262                 String ppwperm = pp.getWritePermission();
11263                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11264                         cpi.applicationInfo.uid, cpi.exported)
11265                         == PackageManager.PERMISSION_GRANTED) {
11266                     return null;
11267                 }
11268             }
11269         }
11270         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11271             return null;
11272         }
11273
11274         final String suffix;
11275         if (!cpi.exported) {
11276             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11277         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11278             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11279         } else {
11280             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11281         }
11282         final String msg = "Permission Denial: opening provider " + cpi.name
11283                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11284                 + ", uid=" + callingUid + ")" + suffix;
11285         Slog.w(TAG, msg);
11286         return msg;
11287     }
11288
11289     /**
11290      * Returns if the ContentProvider has granted a uri to callingUid
11291      */
11292     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11293         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11294         if (perms != null) {
11295             for (int i=perms.size()-1; i>=0; i--) {
11296                 GrantUri grantUri = perms.keyAt(i);
11297                 if (grantUri.sourceUserId == userId || !checkUser) {
11298                     if (matchesProvider(grantUri.uri, cpi)) {
11299                         return true;
11300                     }
11301                 }
11302             }
11303         }
11304         return false;
11305     }
11306
11307     /**
11308      * Returns true if the uri authority is one of the authorities specified in the provider.
11309      */
11310     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11311         String uriAuth = uri.getAuthority();
11312         String cpiAuth = cpi.authority;
11313         if (cpiAuth.indexOf(';') == -1) {
11314             return cpiAuth.equals(uriAuth);
11315         }
11316         String[] cpiAuths = cpiAuth.split(";");
11317         int length = cpiAuths.length;
11318         for (int i = 0; i < length; i++) {
11319             if (cpiAuths[i].equals(uriAuth)) return true;
11320         }
11321         return false;
11322     }
11323
11324     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11325             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11326         if (r != null) {
11327             for (int i=0; i<r.conProviders.size(); i++) {
11328                 ContentProviderConnection conn = r.conProviders.get(i);
11329                 if (conn.provider == cpr) {
11330                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11331                             "Adding provider requested by "
11332                             + r.processName + " from process "
11333                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11334                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11335                     if (stable) {
11336                         conn.stableCount++;
11337                         conn.numStableIncs++;
11338                     } else {
11339                         conn.unstableCount++;
11340                         conn.numUnstableIncs++;
11341                     }
11342                     return conn;
11343                 }
11344             }
11345             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11346             if (stable) {
11347                 conn.stableCount = 1;
11348                 conn.numStableIncs = 1;
11349             } else {
11350                 conn.unstableCount = 1;
11351                 conn.numUnstableIncs = 1;
11352             }
11353             cpr.connections.add(conn);
11354             r.conProviders.add(conn);
11355             startAssociationLocked(r.uid, r.processName, r.curProcState,
11356                     cpr.uid, cpr.name, cpr.info.processName);
11357             return conn;
11358         }
11359         cpr.addExternalProcessHandleLocked(externalProcessToken);
11360         return null;
11361     }
11362
11363     boolean decProviderCountLocked(ContentProviderConnection conn,
11364             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11365         if (conn != null) {
11366             cpr = conn.provider;
11367             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11368                     "Removing provider requested by "
11369                     + conn.client.processName + " from process "
11370                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11371                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11372             if (stable) {
11373                 conn.stableCount--;
11374             } else {
11375                 conn.unstableCount--;
11376             }
11377             if (conn.stableCount == 0 && conn.unstableCount == 0) {
11378                 cpr.connections.remove(conn);
11379                 conn.client.conProviders.remove(conn);
11380                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11381                     // The client is more important than last activity -- note the time this
11382                     // is happening, so we keep the old provider process around a bit as last
11383                     // activity to avoid thrashing it.
11384                     if (cpr.proc != null) {
11385                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11386                     }
11387                 }
11388                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11389                 return true;
11390             }
11391             return false;
11392         }
11393         cpr.removeExternalProcessHandleLocked(externalProcessToken);
11394         return false;
11395     }
11396
11397     private void checkTime(long startTime, String where) {
11398         long now = SystemClock.uptimeMillis();
11399         if ((now-startTime) > 50) {
11400             // If we are taking more than 50ms, log about it.
11401             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11402         }
11403     }
11404
11405     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11406             PROC_SPACE_TERM,
11407             PROC_SPACE_TERM|PROC_PARENS,
11408             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11409     };
11410
11411     private final long[] mProcessStateStatsLongs = new long[1];
11412
11413     boolean isProcessAliveLocked(ProcessRecord proc) {
11414         if (proc.procStatFile == null) {
11415             proc.procStatFile = "/proc/" + proc.pid + "/stat";
11416         }
11417         mProcessStateStatsLongs[0] = 0;
11418         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11419                 mProcessStateStatsLongs, null)) {
11420             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11421             return false;
11422         }
11423         final long state = mProcessStateStatsLongs[0];
11424         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11425                 + (char)state);
11426         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11427     }
11428
11429     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11430             String name, IBinder token, boolean stable, int userId) {
11431         ContentProviderRecord cpr;
11432         ContentProviderConnection conn = null;
11433         ProviderInfo cpi = null;
11434
11435         synchronized(this) {
11436             long startTime = SystemClock.uptimeMillis();
11437
11438             ProcessRecord r = null;
11439             if (caller != null) {
11440                 r = getRecordForAppLocked(caller);
11441                 if (r == null) {
11442                     throw new SecurityException(
11443                             "Unable to find app for caller " + caller
11444                           + " (pid=" + Binder.getCallingPid()
11445                           + ") when getting content provider " + name);
11446                 }
11447             }
11448
11449             boolean checkCrossUser = true;
11450
11451             checkTime(startTime, "getContentProviderImpl: getProviderByName");
11452
11453             // First check if this content provider has been published...
11454             cpr = mProviderMap.getProviderByName(name, userId);
11455             // If that didn't work, check if it exists for user 0 and then
11456             // verify that it's a singleton provider before using it.
11457             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11458                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11459                 if (cpr != null) {
11460                     cpi = cpr.info;
11461                     if (isSingleton(cpi.processName, cpi.applicationInfo,
11462                             cpi.name, cpi.flags)
11463                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11464                         userId = UserHandle.USER_SYSTEM;
11465                         checkCrossUser = false;
11466                     } else {
11467                         cpr = null;
11468                         cpi = null;
11469                     }
11470                 }
11471             }
11472
11473             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11474             if (providerRunning) {
11475                 cpi = cpr.info;
11476                 String msg;
11477                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11478                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11479                         != null) {
11480                     throw new SecurityException(msg);
11481                 }
11482                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11483
11484                 if (r != null && cpr.canRunHere(r)) {
11485                     // This provider has been published or is in the process
11486                     // of being published...  but it is also allowed to run
11487                     // in the caller's process, so don't make a connection
11488                     // and just let the caller instantiate its own instance.
11489                     ContentProviderHolder holder = cpr.newHolder(null);
11490                     // don't give caller the provider object, it needs
11491                     // to make its own.
11492                     holder.provider = null;
11493                     return holder;
11494                 }
11495                 // Don't expose providers between normal apps and instant apps
11496                 try {
11497                     if (AppGlobals.getPackageManager()
11498                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11499                         return null;
11500                     }
11501                 } catch (RemoteException e) {
11502                 }
11503
11504                 final long origId = Binder.clearCallingIdentity();
11505
11506                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11507
11508                 // In this case the provider instance already exists, so we can
11509                 // return it right away.
11510                 conn = incProviderCountLocked(r, cpr, token, stable);
11511                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11512                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11513                         // If this is a perceptible app accessing the provider,
11514                         // make sure to count it as being accessed and thus
11515                         // back up on the LRU list.  This is good because
11516                         // content providers are often expensive to start.
11517                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11518                         updateLruProcessLocked(cpr.proc, false, null);
11519                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11520                     }
11521                 }
11522
11523                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11524                 final int verifiedAdj = cpr.proc.verifiedAdj;
11525                 boolean success = updateOomAdjLocked(cpr.proc, true);
11526                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11527                 // if the process has been successfully adjusted.  So to reduce races with
11528                 // it, we will check whether the process still exists.  Note that this doesn't
11529                 // completely get rid of races with LMK killing the process, but should make
11530                 // them much smaller.
11531                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11532                     success = false;
11533                 }
11534                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11535                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11536                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11537                 // NOTE: there is still a race here where a signal could be
11538                 // pending on the process even though we managed to update its
11539                 // adj level.  Not sure what to do about this, but at least
11540                 // the race is now smaller.
11541                 if (!success) {
11542                     // Uh oh...  it looks like the provider's process
11543                     // has been killed on us.  We need to wait for a new
11544                     // process to be started, and make sure its death
11545                     // doesn't kill our process.
11546                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11547                             + " is crashing; detaching " + r);
11548                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11549                     checkTime(startTime, "getContentProviderImpl: before appDied");
11550                     appDiedLocked(cpr.proc);
11551                     checkTime(startTime, "getContentProviderImpl: after appDied");
11552                     if (!lastRef) {
11553                         // This wasn't the last ref our process had on
11554                         // the provider...  we have now been killed, bail.
11555                         return null;
11556                     }
11557                     providerRunning = false;
11558                     conn = null;
11559                 } else {
11560                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
11561                 }
11562
11563                 Binder.restoreCallingIdentity(origId);
11564             }
11565
11566             if (!providerRunning) {
11567                 try {
11568                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11569                     cpi = AppGlobals.getPackageManager().
11570                         resolveContentProvider(name,
11571                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11572                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11573                 } catch (RemoteException ex) {
11574                 }
11575                 if (cpi == null) {
11576                     return null;
11577                 }
11578                 // If the provider is a singleton AND
11579                 // (it's a call within the same user || the provider is a
11580                 // privileged app)
11581                 // Then allow connecting to the singleton provider
11582                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11583                         cpi.name, cpi.flags)
11584                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11585                 if (singleton) {
11586                     userId = UserHandle.USER_SYSTEM;
11587                 }
11588                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11589                 checkTime(startTime, "getContentProviderImpl: got app info for user");
11590
11591                 String msg;
11592                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11593                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11594                         != null) {
11595                     throw new SecurityException(msg);
11596                 }
11597                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11598
11599                 if (!mProcessesReady
11600                         && !cpi.processName.equals("system")) {
11601                     // If this content provider does not run in the system
11602                     // process, and the system is not yet ready to run other
11603                     // processes, then fail fast instead of hanging.
11604                     throw new IllegalArgumentException(
11605                             "Attempt to launch content provider before system ready");
11606                 }
11607
11608                 // Make sure that the user who owns this provider is running.  If not,
11609                 // we don't want to allow it to run.
11610                 if (!mUserController.isUserRunningLocked(userId, 0)) {
11611                     Slog.w(TAG, "Unable to launch app "
11612                             + cpi.applicationInfo.packageName + "/"
11613                             + cpi.applicationInfo.uid + " for provider "
11614                             + name + ": user " + userId + " is stopped");
11615                     return null;
11616                 }
11617
11618                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11619                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11620                 cpr = mProviderMap.getProviderByClass(comp, userId);
11621                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11622                 final boolean firstClass = cpr == null;
11623                 if (firstClass) {
11624                     final long ident = Binder.clearCallingIdentity();
11625
11626                     // If permissions need a review before any of the app components can run,
11627                     // we return no provider and launch a review activity if the calling app
11628                     // is in the foreground.
11629                     if (mPermissionReviewRequired) {
11630                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11631                             return null;
11632                         }
11633                     }
11634
11635                     try {
11636                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11637                         ApplicationInfo ai =
11638                             AppGlobals.getPackageManager().
11639                                 getApplicationInfo(
11640                                         cpi.applicationInfo.packageName,
11641                                         STOCK_PM_FLAGS, userId);
11642                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11643                         if (ai == null) {
11644                             Slog.w(TAG, "No package info for content provider "
11645                                     + cpi.name);
11646                             return null;
11647                         }
11648                         ai = getAppInfoForUser(ai, userId);
11649                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11650                     } catch (RemoteException ex) {
11651                         // pm is in same process, this will never happen.
11652                     } finally {
11653                         Binder.restoreCallingIdentity(ident);
11654                     }
11655                 }
11656
11657                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11658
11659                 if (r != null && cpr.canRunHere(r)) {
11660                     // If this is a multiprocess provider, then just return its
11661                     // info and allow the caller to instantiate it.  Only do
11662                     // this if the provider is the same user as the caller's
11663                     // process, or can run as root (so can be in any process).
11664                     return cpr.newHolder(null);
11665                 }
11666
11667                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11668                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11669                             + cpr.info.name + " callers=" + Debug.getCallers(6));
11670
11671                 // This is single process, and our app is now connecting to it.
11672                 // See if we are already in the process of launching this
11673                 // provider.
11674                 final int N = mLaunchingProviders.size();
11675                 int i;
11676                 for (i = 0; i < N; i++) {
11677                     if (mLaunchingProviders.get(i) == cpr) {
11678                         break;
11679                     }
11680                 }
11681
11682                 // If the provider is not already being launched, then get it
11683                 // started.
11684                 if (i >= N) {
11685                     final long origId = Binder.clearCallingIdentity();
11686
11687                     try {
11688                         // Content provider is now in use, its package can't be stopped.
11689                         try {
11690                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
11691                             AppGlobals.getPackageManager().setPackageStoppedState(
11692                                     cpr.appInfo.packageName, false, userId);
11693                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
11694                         } catch (RemoteException e) {
11695                         } catch (IllegalArgumentException e) {
11696                             Slog.w(TAG, "Failed trying to unstop package "
11697                                     + cpr.appInfo.packageName + ": " + e);
11698                         }
11699
11700                         // Use existing process if already started
11701                         checkTime(startTime, "getContentProviderImpl: looking for process record");
11702                         ProcessRecord proc = getProcessRecordLocked(
11703                                 cpi.processName, cpr.appInfo.uid, false);
11704                         if (proc != null && proc.thread != null && !proc.killed) {
11705                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11706                                     "Installing in existing process " + proc);
11707                             if (!proc.pubProviders.containsKey(cpi.name)) {
11708                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
11709                                 proc.pubProviders.put(cpi.name, cpr);
11710                                 try {
11711                                     proc.thread.scheduleInstallProvider(cpi);
11712                                 } catch (RemoteException e) {
11713                                 }
11714                             }
11715                         } else {
11716                             checkTime(startTime, "getContentProviderImpl: before start process");
11717                             proc = startProcessLocked(cpi.processName,
11718                                     cpr.appInfo, false, 0, "content provider",
11719                                     new ComponentName(cpi.applicationInfo.packageName,
11720                                             cpi.name), false, false, false);
11721                             checkTime(startTime, "getContentProviderImpl: after start process");
11722                             if (proc == null) {
11723                                 Slog.w(TAG, "Unable to launch app "
11724                                         + cpi.applicationInfo.packageName + "/"
11725                                         + cpi.applicationInfo.uid + " for provider "
11726                                         + name + ": process is bad");
11727                                 return null;
11728                             }
11729                         }
11730                         cpr.launchingApp = proc;
11731                         mLaunchingProviders.add(cpr);
11732                     } finally {
11733                         Binder.restoreCallingIdentity(origId);
11734                     }
11735                 }
11736
11737                 checkTime(startTime, "getContentProviderImpl: updating data structures");
11738
11739                 // Make sure the provider is published (the same provider class
11740                 // may be published under multiple names).
11741                 if (firstClass) {
11742                     mProviderMap.putProviderByClass(comp, cpr);
11743                 }
11744
11745                 mProviderMap.putProviderByName(name, cpr);
11746                 conn = incProviderCountLocked(r, cpr, token, stable);
11747                 if (conn != null) {
11748                     conn.waiting = true;
11749                 }
11750             }
11751             checkTime(startTime, "getContentProviderImpl: done!");
11752
11753             grantEphemeralAccessLocked(userId, null /*intent*/,
11754                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11755         }
11756
11757         // Wait for the provider to be published...
11758         synchronized (cpr) {
11759             while (cpr.provider == null) {
11760                 if (cpr.launchingApp == null) {
11761                     Slog.w(TAG, "Unable to launch app "
11762                             + cpi.applicationInfo.packageName + "/"
11763                             + cpi.applicationInfo.uid + " for provider "
11764                             + name + ": launching app became null");
11765                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11766                             UserHandle.getUserId(cpi.applicationInfo.uid),
11767                             cpi.applicationInfo.packageName,
11768                             cpi.applicationInfo.uid, name);
11769                     return null;
11770                 }
11771                 try {
11772                     if (DEBUG_MU) Slog.v(TAG_MU,
11773                             "Waiting to start provider " + cpr
11774                             + " launchingApp=" + cpr.launchingApp);
11775                     if (conn != null) {
11776                         conn.waiting = true;
11777                     }
11778                     cpr.wait();
11779                 } catch (InterruptedException ex) {
11780                 } finally {
11781                     if (conn != null) {
11782                         conn.waiting = false;
11783                     }
11784                 }
11785             }
11786         }
11787         return cpr != null ? cpr.newHolder(conn) : null;
11788     }
11789
11790     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11791             ProcessRecord r, final int userId) {
11792         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11793                 cpi.packageName, userId)) {
11794
11795             final boolean callerForeground = r == null || r.setSchedGroup
11796                     != ProcessList.SCHED_GROUP_BACKGROUND;
11797
11798             // Show a permission review UI only for starting from a foreground app
11799             if (!callerForeground) {
11800                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11801                         + cpi.packageName + " requires a permissions review");
11802                 return false;
11803             }
11804
11805             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11806             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11807                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11808             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11809
11810             if (DEBUG_PERMISSIONS_REVIEW) {
11811                 Slog.i(TAG, "u" + userId + " Launching permission review "
11812                         + "for package " + cpi.packageName);
11813             }
11814
11815             final UserHandle userHandle = new UserHandle(userId);
11816             mHandler.post(new Runnable() {
11817                 @Override
11818                 public void run() {
11819                     mContext.startActivityAsUser(intent, userHandle);
11820                 }
11821             });
11822
11823             return false;
11824         }
11825
11826         return true;
11827     }
11828
11829     PackageManagerInternal getPackageManagerInternalLocked() {
11830         if (mPackageManagerInt == null) {
11831             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11832         }
11833         return mPackageManagerInt;
11834     }
11835
11836     @Override
11837     public final ContentProviderHolder getContentProvider(
11838             IApplicationThread caller, String name, int userId, boolean stable) {
11839         enforceNotIsolatedCaller("getContentProvider");
11840         if (caller == null) {
11841             String msg = "null IApplicationThread when getting content provider "
11842                     + name;
11843             Slog.w(TAG, msg);
11844             throw new SecurityException(msg);
11845         }
11846         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11847         // with cross-user grant.
11848         return getContentProviderImpl(caller, name, null, stable, userId);
11849     }
11850
11851     public ContentProviderHolder getContentProviderExternal(
11852             String name, int userId, IBinder token) {
11853         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11854             "Do not have permission in call getContentProviderExternal()");
11855         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11856                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11857         return getContentProviderExternalUnchecked(name, token, userId);
11858     }
11859
11860     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11861             IBinder token, int userId) {
11862         return getContentProviderImpl(null, name, token, true, userId);
11863     }
11864
11865     /**
11866      * Drop a content provider from a ProcessRecord's bookkeeping
11867      */
11868     public void removeContentProvider(IBinder connection, boolean stable) {
11869         enforceNotIsolatedCaller("removeContentProvider");
11870         long ident = Binder.clearCallingIdentity();
11871         try {
11872             synchronized (this) {
11873                 ContentProviderConnection conn;
11874                 try {
11875                     conn = (ContentProviderConnection)connection;
11876                 } catch (ClassCastException e) {
11877                     String msg ="removeContentProvider: " + connection
11878                             + " not a ContentProviderConnection";
11879                     Slog.w(TAG, msg);
11880                     throw new IllegalArgumentException(msg);
11881                 }
11882                 if (conn == null) {
11883                     throw new NullPointerException("connection is null");
11884                 }
11885                 if (decProviderCountLocked(conn, null, null, stable)) {
11886                     updateOomAdjLocked();
11887                 }
11888             }
11889         } finally {
11890             Binder.restoreCallingIdentity(ident);
11891         }
11892     }
11893
11894     public void removeContentProviderExternal(String name, IBinder token) {
11895         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11896             "Do not have permission in call removeContentProviderExternal()");
11897         int userId = UserHandle.getCallingUserId();
11898         long ident = Binder.clearCallingIdentity();
11899         try {
11900             removeContentProviderExternalUnchecked(name, token, userId);
11901         } finally {
11902             Binder.restoreCallingIdentity(ident);
11903         }
11904     }
11905
11906     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11907         synchronized (this) {
11908             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11909             if(cpr == null) {
11910                 //remove from mProvidersByClass
11911                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11912                 return;
11913             }
11914
11915             //update content provider record entry info
11916             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11917             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11918             if (localCpr.hasExternalProcessHandles()) {
11919                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11920                     updateOomAdjLocked();
11921                 } else {
11922                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11923                             + " with no external reference for token: "
11924                             + token + ".");
11925                 }
11926             } else {
11927                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11928                         + " with no external references.");
11929             }
11930         }
11931     }
11932
11933     public final void publishContentProviders(IApplicationThread caller,
11934             List<ContentProviderHolder> providers) {
11935         if (providers == null) {
11936             return;
11937         }
11938
11939         enforceNotIsolatedCaller("publishContentProviders");
11940         synchronized (this) {
11941             final ProcessRecord r = getRecordForAppLocked(caller);
11942             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11943             if (r == null) {
11944                 throw new SecurityException(
11945                         "Unable to find app for caller " + caller
11946                       + " (pid=" + Binder.getCallingPid()
11947                       + ") when publishing content providers");
11948             }
11949
11950             final long origId = Binder.clearCallingIdentity();
11951
11952             final int N = providers.size();
11953             for (int i = 0; i < N; i++) {
11954                 ContentProviderHolder src = providers.get(i);
11955                 if (src == null || src.info == null || src.provider == null) {
11956                     continue;
11957                 }
11958                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11959                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11960                 if (dst != null) {
11961                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11962                     mProviderMap.putProviderByClass(comp, dst);
11963                     String names[] = dst.info.authority.split(";");
11964                     for (int j = 0; j < names.length; j++) {
11965                         mProviderMap.putProviderByName(names[j], dst);
11966                     }
11967
11968                     int launchingCount = mLaunchingProviders.size();
11969                     int j;
11970                     boolean wasInLaunchingProviders = false;
11971                     for (j = 0; j < launchingCount; j++) {
11972                         if (mLaunchingProviders.get(j) == dst) {
11973                             mLaunchingProviders.remove(j);
11974                             wasInLaunchingProviders = true;
11975                             j--;
11976                             launchingCount--;
11977                         }
11978                     }
11979                     if (wasInLaunchingProviders) {
11980                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11981                     }
11982                     synchronized (dst) {
11983                         dst.provider = src.provider;
11984                         dst.proc = r;
11985                         dst.notifyAll();
11986                     }
11987                     updateOomAdjLocked(r, true);
11988                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11989                             src.info.authority);
11990                 }
11991             }
11992
11993             Binder.restoreCallingIdentity(origId);
11994         }
11995     }
11996
11997     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11998         ContentProviderConnection conn;
11999         try {
12000             conn = (ContentProviderConnection)connection;
12001         } catch (ClassCastException e) {
12002             String msg ="refContentProvider: " + connection
12003                     + " not a ContentProviderConnection";
12004             Slog.w(TAG, msg);
12005             throw new IllegalArgumentException(msg);
12006         }
12007         if (conn == null) {
12008             throw new NullPointerException("connection is null");
12009         }
12010
12011         synchronized (this) {
12012             if (stable > 0) {
12013                 conn.numStableIncs += stable;
12014             }
12015             stable = conn.stableCount + stable;
12016             if (stable < 0) {
12017                 throw new IllegalStateException("stableCount < 0: " + stable);
12018             }
12019
12020             if (unstable > 0) {
12021                 conn.numUnstableIncs += unstable;
12022             }
12023             unstable = conn.unstableCount + unstable;
12024             if (unstable < 0) {
12025                 throw new IllegalStateException("unstableCount < 0: " + unstable);
12026             }
12027
12028             if ((stable+unstable) <= 0) {
12029                 throw new IllegalStateException("ref counts can't go to zero here: stable="
12030                         + stable + " unstable=" + unstable);
12031             }
12032             conn.stableCount = stable;
12033             conn.unstableCount = unstable;
12034             return !conn.dead;
12035         }
12036     }
12037
12038     public void unstableProviderDied(IBinder connection) {
12039         ContentProviderConnection conn;
12040         try {
12041             conn = (ContentProviderConnection)connection;
12042         } catch (ClassCastException e) {
12043             String msg ="refContentProvider: " + connection
12044                     + " not a ContentProviderConnection";
12045             Slog.w(TAG, msg);
12046             throw new IllegalArgumentException(msg);
12047         }
12048         if (conn == null) {
12049             throw new NullPointerException("connection is null");
12050         }
12051
12052         // Safely retrieve the content provider associated with the connection.
12053         IContentProvider provider;
12054         synchronized (this) {
12055             provider = conn.provider.provider;
12056         }
12057
12058         if (provider == null) {
12059             // Um, yeah, we're way ahead of you.
12060             return;
12061         }
12062
12063         // Make sure the caller is being honest with us.
12064         if (provider.asBinder().pingBinder()) {
12065             // Er, no, still looks good to us.
12066             synchronized (this) {
12067                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12068                         + " says " + conn + " died, but we don't agree");
12069                 return;
12070             }
12071         }
12072
12073         // Well look at that!  It's dead!
12074         synchronized (this) {
12075             if (conn.provider.provider != provider) {
12076                 // But something changed...  good enough.
12077                 return;
12078             }
12079
12080             ProcessRecord proc = conn.provider.proc;
12081             if (proc == null || proc.thread == null) {
12082                 // Seems like the process is already cleaned up.
12083                 return;
12084             }
12085
12086             // As far as we're concerned, this is just like receiving a
12087             // death notification...  just a bit prematurely.
12088             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12089                     + ") early provider death");
12090             final long ident = Binder.clearCallingIdentity();
12091             try {
12092                 appDiedLocked(proc);
12093             } finally {
12094                 Binder.restoreCallingIdentity(ident);
12095             }
12096         }
12097     }
12098
12099     @Override
12100     public void appNotRespondingViaProvider(IBinder connection) {
12101         enforceCallingPermission(
12102                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12103
12104         final ContentProviderConnection conn = (ContentProviderConnection) connection;
12105         if (conn == null) {
12106             Slog.w(TAG, "ContentProviderConnection is null");
12107             return;
12108         }
12109
12110         final ProcessRecord host = conn.provider.proc;
12111         if (host == null) {
12112             Slog.w(TAG, "Failed to find hosting ProcessRecord");
12113             return;
12114         }
12115
12116         mHandler.post(new Runnable() {
12117             @Override
12118             public void run() {
12119                 mAppErrors.appNotResponding(host, null, null, false,
12120                         "ContentProvider not responding");
12121             }
12122         });
12123     }
12124
12125     public final void installSystemProviders() {
12126         List<ProviderInfo> providers;
12127         synchronized (this) {
12128             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12129             providers = generateApplicationProvidersLocked(app);
12130             if (providers != null) {
12131                 for (int i=providers.size()-1; i>=0; i--) {
12132                     ProviderInfo pi = (ProviderInfo)providers.get(i);
12133                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12134                         Slog.w(TAG, "Not installing system proc provider " + pi.name
12135                                 + ": not system .apk");
12136                         providers.remove(i);
12137                     }
12138                 }
12139             }
12140         }
12141         if (providers != null) {
12142             mSystemThread.installSystemProviders(providers);
12143         }
12144
12145         mConstants.start(mContext.getContentResolver());
12146         mCoreSettingsObserver = new CoreSettingsObserver(this);
12147         mFontScaleSettingObserver = new FontScaleSettingObserver();
12148
12149         // Now that the settings provider is published we can consider sending
12150         // in a rescue party.
12151         RescueParty.onSettingsProviderPublished(mContext);
12152
12153         //mUsageStatsService.monitorPackages();
12154     }
12155
12156     private void startPersistentApps(int matchFlags) {
12157         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12158
12159         synchronized (this) {
12160             try {
12161                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12162                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12163                 for (ApplicationInfo app : apps) {
12164                     if (!"android".equals(app.packageName)) {
12165                         addAppLocked(app, null, false, null /* ABI override */);
12166                     }
12167                 }
12168             } catch (RemoteException ex) {
12169             }
12170         }
12171     }
12172
12173     /**
12174      * When a user is unlocked, we need to install encryption-unaware providers
12175      * belonging to any running apps.
12176      */
12177     private void installEncryptionUnawareProviders(int userId) {
12178         // We're only interested in providers that are encryption unaware, and
12179         // we don't care about uninstalled apps, since there's no way they're
12180         // running at this point.
12181         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12182
12183         synchronized (this) {
12184             final int NP = mProcessNames.getMap().size();
12185             for (int ip = 0; ip < NP; ip++) {
12186                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12187                 final int NA = apps.size();
12188                 for (int ia = 0; ia < NA; ia++) {
12189                     final ProcessRecord app = apps.valueAt(ia);
12190                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
12191
12192                     final int NG = app.pkgList.size();
12193                     for (int ig = 0; ig < NG; ig++) {
12194                         try {
12195                             final String pkgName = app.pkgList.keyAt(ig);
12196                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12197                                     .getPackageInfo(pkgName, matchFlags, userId);
12198                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12199                                 for (ProviderInfo pi : pkgInfo.providers) {
12200                                     // TODO: keep in sync with generateApplicationProvidersLocked
12201                                     final boolean processMatch = Objects.equals(pi.processName,
12202                                             app.processName) || pi.multiprocess;
12203                                     final boolean userMatch = isSingleton(pi.processName,
12204                                             pi.applicationInfo, pi.name, pi.flags)
12205                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
12206                                     if (processMatch && userMatch) {
12207                                         Log.v(TAG, "Installing " + pi);
12208                                         app.thread.scheduleInstallProvider(pi);
12209                                     } else {
12210                                         Log.v(TAG, "Skipping " + pi);
12211                                     }
12212                                 }
12213                             }
12214                         } catch (RemoteException ignored) {
12215                         }
12216                     }
12217                 }
12218             }
12219         }
12220     }
12221
12222     /**
12223      * Allows apps to retrieve the MIME type of a URI.
12224      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12225      * users, then it does not need permission to access the ContentProvider.
12226      * Either, it needs cross-user uri grants.
12227      *
12228      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12229      *
12230      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12231      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12232      */
12233     public String getProviderMimeType(Uri uri, int userId) {
12234         enforceNotIsolatedCaller("getProviderMimeType");
12235         final String name = uri.getAuthority();
12236         int callingUid = Binder.getCallingUid();
12237         int callingPid = Binder.getCallingPid();
12238         long ident = 0;
12239         boolean clearedIdentity = false;
12240         synchronized (this) {
12241             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12242         }
12243         if (canClearIdentity(callingPid, callingUid, userId)) {
12244             clearedIdentity = true;
12245             ident = Binder.clearCallingIdentity();
12246         }
12247         ContentProviderHolder holder = null;
12248         try {
12249             holder = getContentProviderExternalUnchecked(name, null, userId);
12250             if (holder != null) {
12251                 return holder.provider.getType(uri);
12252             }
12253         } catch (RemoteException e) {
12254             Log.w(TAG, "Content provider dead retrieving " + uri, e);
12255             return null;
12256         } catch (Exception e) {
12257             Log.w(TAG, "Exception while determining type of " + uri, e);
12258             return null;
12259         } finally {
12260             // We need to clear the identity to call removeContentProviderExternalUnchecked
12261             if (!clearedIdentity) {
12262                 ident = Binder.clearCallingIdentity();
12263             }
12264             try {
12265                 if (holder != null) {
12266                     removeContentProviderExternalUnchecked(name, null, userId);
12267                 }
12268             } finally {
12269                 Binder.restoreCallingIdentity(ident);
12270             }
12271         }
12272
12273         return null;
12274     }
12275
12276     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12277         if (UserHandle.getUserId(callingUid) == userId) {
12278             return true;
12279         }
12280         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12281                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12282                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12283                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12284                 return true;
12285         }
12286         return false;
12287     }
12288
12289     // =========================================================
12290     // GLOBAL MANAGEMENT
12291     // =========================================================
12292
12293     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12294             boolean isolated, int isolatedUid) {
12295         String proc = customProcess != null ? customProcess : info.processName;
12296         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12297         final int userId = UserHandle.getUserId(info.uid);
12298         int uid = info.uid;
12299         if (isolated) {
12300             if (isolatedUid == 0) {
12301                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12302                 while (true) {
12303                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12304                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12305                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12306                     }
12307                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12308                     mNextIsolatedProcessUid++;
12309                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12310                         // No process for this uid, use it.
12311                         break;
12312                     }
12313                     stepsLeft--;
12314                     if (stepsLeft <= 0) {
12315                         return null;
12316                     }
12317                 }
12318             } else {
12319                 // Special case for startIsolatedProcess (internal only), where
12320                 // the uid of the isolated process is specified by the caller.
12321                 uid = isolatedUid;
12322             }
12323             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12324
12325             // Register the isolated UID with this application so BatteryStats knows to
12326             // attribute resource usage to the application.
12327             //
12328             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12329             // about the process state of the isolated UID *before* it is registered with the
12330             // owning application.
12331             mBatteryStatsService.addIsolatedUid(uid, info.uid);
12332         }
12333         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12334         if (!mBooted && !mBooting
12335                 && userId == UserHandle.USER_SYSTEM
12336                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12337             r.persistent = true;
12338             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12339         }
12340         addProcessNameLocked(r);
12341         return r;
12342     }
12343
12344     private boolean uidOnBackgroundWhitelist(final int uid) {
12345         final int appId = UserHandle.getAppId(uid);
12346         final int[] whitelist = mBackgroundAppIdWhitelist;
12347         final int N = whitelist.length;
12348         for (int i = 0; i < N; i++) {
12349             if (appId == whitelist[i]) {
12350                 return true;
12351             }
12352         }
12353         return false;
12354     }
12355
12356     @Override
12357     public void backgroundWhitelistUid(final int uid) {
12358         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12359             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12360         }
12361
12362         if (DEBUG_BACKGROUND_CHECK) {
12363             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12364         }
12365         synchronized (this) {
12366             final int N = mBackgroundAppIdWhitelist.length;
12367             int[] newList = new int[N+1];
12368             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12369             newList[N] = UserHandle.getAppId(uid);
12370             mBackgroundAppIdWhitelist = newList;
12371         }
12372     }
12373
12374     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12375             String abiOverride) {
12376         ProcessRecord app;
12377         if (!isolated) {
12378             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12379                     info.uid, true);
12380         } else {
12381             app = null;
12382         }
12383
12384         if (app == null) {
12385             app = newProcessRecordLocked(info, customProcess, isolated, 0);
12386             updateLruProcessLocked(app, false, null);
12387             updateOomAdjLocked();
12388         }
12389
12390         // This package really, really can not be stopped.
12391         try {
12392             AppGlobals.getPackageManager().setPackageStoppedState(
12393                     info.packageName, false, UserHandle.getUserId(app.uid));
12394         } catch (RemoteException e) {
12395         } catch (IllegalArgumentException e) {
12396             Slog.w(TAG, "Failed trying to unstop package "
12397                     + info.packageName + ": " + e);
12398         }
12399
12400         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12401             app.persistent = true;
12402             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12403         }
12404         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12405             mPersistentStartingProcesses.add(app);
12406             startProcessLocked(app, "added application",
12407                     customProcess != null ? customProcess : app.processName, abiOverride,
12408                     null /* entryPoint */, null /* entryPointArgs */);
12409         }
12410
12411         return app;
12412     }
12413
12414     public void unhandledBack() {
12415         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12416                 "unhandledBack()");
12417
12418         synchronized(this) {
12419             final long origId = Binder.clearCallingIdentity();
12420             try {
12421                 getFocusedStack().unhandledBackLocked();
12422             } finally {
12423                 Binder.restoreCallingIdentity(origId);
12424             }
12425         }
12426     }
12427
12428     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12429         enforceNotIsolatedCaller("openContentUri");
12430         final int userId = UserHandle.getCallingUserId();
12431         final Uri uri = Uri.parse(uriString);
12432         String name = uri.getAuthority();
12433         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12434         ParcelFileDescriptor pfd = null;
12435         if (cph != null) {
12436             // We record the binder invoker's uid in thread-local storage before
12437             // going to the content provider to open the file.  Later, in the code
12438             // that handles all permissions checks, we look for this uid and use
12439             // that rather than the Activity Manager's own uid.  The effect is that
12440             // we do the check against the caller's permissions even though it looks
12441             // to the content provider like the Activity Manager itself is making
12442             // the request.
12443             Binder token = new Binder();
12444             sCallerIdentity.set(new Identity(
12445                     token, Binder.getCallingPid(), Binder.getCallingUid()));
12446             try {
12447                 pfd = cph.provider.openFile(null, uri, "r", null, token);
12448             } catch (FileNotFoundException e) {
12449                 // do nothing; pfd will be returned null
12450             } finally {
12451                 // Ensure that whatever happens, we clean up the identity state
12452                 sCallerIdentity.remove();
12453                 // Ensure we're done with the provider.
12454                 removeContentProviderExternalUnchecked(name, null, userId);
12455             }
12456         } else {
12457             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12458         }
12459         return pfd;
12460     }
12461
12462     // Actually is sleeping or shutting down or whatever else in the future
12463     // is an inactive state.
12464     boolean isSleepingOrShuttingDownLocked() {
12465         return isSleepingLocked() || mShuttingDown;
12466     }
12467
12468     boolean isShuttingDownLocked() {
12469         return mShuttingDown;
12470     }
12471
12472     boolean isSleepingLocked() {
12473         return mSleeping;
12474     }
12475
12476     void onWakefulnessChanged(int wakefulness) {
12477         synchronized(this) {
12478             boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12479             boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12480             mWakefulness = wakefulness;
12481
12482             if (wasAwake != isAwake) {
12483                 // Also update state in a special way for running foreground services UI.
12484                 mServices.updateScreenStateLocked(isAwake);
12485                 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12486                         .sendToTarget();
12487             }
12488         }
12489     }
12490
12491     void finishRunningVoiceLocked() {
12492         if (mRunningVoice != null) {
12493             mRunningVoice = null;
12494             mVoiceWakeLock.release();
12495             updateSleepIfNeededLocked();
12496         }
12497     }
12498
12499     void startTimeTrackingFocusedActivityLocked() {
12500         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12501         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12502             mCurAppTimeTracker.start(resumedActivity.packageName);
12503         }
12504     }
12505
12506     void updateSleepIfNeededLocked() {
12507         final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12508         final boolean wasSleeping = mSleeping;
12509
12510         if (!shouldSleep) {
12511             // If wasSleeping is true, we need to wake up activity manager state from when
12512             // we started sleeping. In either case, we need to apply the sleep tokens, which
12513             // will wake up stacks or put them to sleep as appropriate.
12514             if (wasSleeping) {
12515                 mSleeping = false;
12516                 startTimeTrackingFocusedActivityLocked();
12517                 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12518                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12519             }
12520             mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12521             if (wasSleeping) {
12522                 updateOomAdjLocked();
12523             }
12524         } else if (!mSleeping && shouldSleep) {
12525             mSleeping = true;
12526             if (mCurAppTimeTracker != null) {
12527                 mCurAppTimeTracker.stop();
12528             }
12529             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12530             mStackSupervisor.goingToSleepLocked();
12531             updateOomAdjLocked();
12532         }
12533     }
12534
12535     /** Pokes the task persister. */
12536     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12537         mRecentTasks.notifyTaskPersisterLocked(task, flush);
12538     }
12539
12540     /**
12541      * Notifies all listeners when the pinned stack animation starts.
12542      */
12543     @Override
12544     public void notifyPinnedStackAnimationStarted() {
12545         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12546     }
12547
12548     /**
12549      * Notifies all listeners when the pinned stack animation ends.
12550      */
12551     @Override
12552     public void notifyPinnedStackAnimationEnded() {
12553         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12554     }
12555
12556     @Override
12557     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12558         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12559     }
12560
12561     @Override
12562     public boolean shutdown(int timeout) {
12563         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12564                 != PackageManager.PERMISSION_GRANTED) {
12565             throw new SecurityException("Requires permission "
12566                     + android.Manifest.permission.SHUTDOWN);
12567         }
12568
12569         boolean timedout = false;
12570
12571         synchronized(this) {
12572             mShuttingDown = true;
12573             mStackSupervisor.prepareForShutdownLocked();
12574             updateEventDispatchingLocked();
12575             timedout = mStackSupervisor.shutdownLocked(timeout);
12576         }
12577
12578         mAppOpsService.shutdown();
12579         if (mUsageStatsService != null) {
12580             mUsageStatsService.prepareShutdown();
12581         }
12582         mBatteryStatsService.shutdown();
12583         synchronized (this) {
12584             mProcessStats.shutdownLocked();
12585             notifyTaskPersisterLocked(null, true);
12586         }
12587
12588         return timedout;
12589     }
12590
12591     public final void activitySlept(IBinder token) {
12592         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12593
12594         final long origId = Binder.clearCallingIdentity();
12595
12596         synchronized (this) {
12597             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12598             if (r != null) {
12599                 mStackSupervisor.activitySleptLocked(r);
12600             }
12601         }
12602
12603         Binder.restoreCallingIdentity(origId);
12604     }
12605
12606     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12607         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12608         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12609         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12610             boolean wasRunningVoice = mRunningVoice != null;
12611             mRunningVoice = session;
12612             if (!wasRunningVoice) {
12613                 mVoiceWakeLock.acquire();
12614                 updateSleepIfNeededLocked();
12615             }
12616         }
12617     }
12618
12619     private void updateEventDispatchingLocked() {
12620         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12621     }
12622
12623     @Override
12624     public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12625         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12626                 != PackageManager.PERMISSION_GRANTED) {
12627             throw new SecurityException("Requires permission "
12628                     + android.Manifest.permission.DEVICE_POWER);
12629         }
12630
12631         synchronized(this) {
12632             long ident = Binder.clearCallingIdentity();
12633             try {
12634                 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12635             } finally {
12636                 Binder.restoreCallingIdentity(ident);
12637             }
12638         }
12639
12640         mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12641                 .sendToTarget();
12642     }
12643
12644     @Override
12645     public void notifyLockedProfile(@UserIdInt int userId) {
12646         try {
12647             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12648                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12649             }
12650         } catch (RemoteException ex) {
12651             throw new SecurityException("Fail to check is caller a privileged app", ex);
12652         }
12653
12654         synchronized (this) {
12655             final long ident = Binder.clearCallingIdentity();
12656             try {
12657                 if (mUserController.shouldConfirmCredentials(userId)) {
12658                     if (mKeyguardController.isKeyguardLocked()) {
12659                         // Showing launcher to avoid user entering credential twice.
12660                         final int currentUserId = mUserController.getCurrentUserIdLocked();
12661                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12662                     }
12663                     mStackSupervisor.lockAllProfileTasks(userId);
12664                 }
12665             } finally {
12666                 Binder.restoreCallingIdentity(ident);
12667             }
12668         }
12669     }
12670
12671     @Override
12672     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12673         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12674         synchronized (this) {
12675             final long ident = Binder.clearCallingIdentity();
12676             try {
12677                 mActivityStarter.startConfirmCredentialIntent(intent, options);
12678             } finally {
12679                 Binder.restoreCallingIdentity(ident);
12680             }
12681         }
12682     }
12683
12684     @Override
12685     public void stopAppSwitches() {
12686         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12687                 != PackageManager.PERMISSION_GRANTED) {
12688             throw new SecurityException("viewquires permission "
12689                     + android.Manifest.permission.STOP_APP_SWITCHES);
12690         }
12691
12692         synchronized(this) {
12693             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12694                     + APP_SWITCH_DELAY_TIME;
12695             mDidAppSwitch = false;
12696             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12697             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12698             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12699         }
12700     }
12701
12702     public void resumeAppSwitches() {
12703         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12704                 != PackageManager.PERMISSION_GRANTED) {
12705             throw new SecurityException("Requires permission "
12706                     + android.Manifest.permission.STOP_APP_SWITCHES);
12707         }
12708
12709         synchronized(this) {
12710             // Note that we don't execute any pending app switches... we will
12711             // let those wait until either the timeout, or the next start
12712             // activity request.
12713             mAppSwitchesAllowedTime = 0;
12714         }
12715     }
12716
12717     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12718             int callingPid, int callingUid, String name) {
12719         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12720             return true;
12721         }
12722
12723         int perm = checkComponentPermission(
12724                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12725                 sourceUid, -1, true);
12726         if (perm == PackageManager.PERMISSION_GRANTED) {
12727             return true;
12728         }
12729
12730         // If the actual IPC caller is different from the logical source, then
12731         // also see if they are allowed to control app switches.
12732         if (callingUid != -1 && callingUid != sourceUid) {
12733             perm = checkComponentPermission(
12734                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12735                     callingUid, -1, true);
12736             if (perm == PackageManager.PERMISSION_GRANTED) {
12737                 return true;
12738             }
12739         }
12740
12741         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12742         return false;
12743     }
12744
12745     public void setDebugApp(String packageName, boolean waitForDebugger,
12746             boolean persistent) {
12747         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12748                 "setDebugApp()");
12749
12750         long ident = Binder.clearCallingIdentity();
12751         try {
12752             // Note that this is not really thread safe if there are multiple
12753             // callers into it at the same time, but that's not a situation we
12754             // care about.
12755             if (persistent) {
12756                 final ContentResolver resolver = mContext.getContentResolver();
12757                 Settings.Global.putString(
12758                     resolver, Settings.Global.DEBUG_APP,
12759                     packageName);
12760                 Settings.Global.putInt(
12761                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12762                     waitForDebugger ? 1 : 0);
12763             }
12764
12765             synchronized (this) {
12766                 if (!persistent) {
12767                     mOrigDebugApp = mDebugApp;
12768                     mOrigWaitForDebugger = mWaitForDebugger;
12769                 }
12770                 mDebugApp = packageName;
12771                 mWaitForDebugger = waitForDebugger;
12772                 mDebugTransient = !persistent;
12773                 if (packageName != null) {
12774                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12775                             false, UserHandle.USER_ALL, "set debug app");
12776                 }
12777             }
12778         } finally {
12779             Binder.restoreCallingIdentity(ident);
12780         }
12781     }
12782
12783     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12784         synchronized (this) {
12785             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12786             if (!isDebuggable) {
12787                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12788                     throw new SecurityException("Process not debuggable: " + app.packageName);
12789                 }
12790             }
12791
12792             mTrackAllocationApp = processName;
12793         }
12794     }
12795
12796     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12797         synchronized (this) {
12798             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12799             if (!isDebuggable) {
12800                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12801                     throw new SecurityException("Process not debuggable: " + app.packageName);
12802                 }
12803             }
12804             mProfileApp = processName;
12805
12806             if (mProfilerInfo != null) {
12807                 if (mProfilerInfo.profileFd != null) {
12808                     try {
12809                         mProfilerInfo.profileFd.close();
12810                     } catch (IOException e) {
12811                     }
12812                 }
12813             }
12814             mProfilerInfo = new ProfilerInfo(profilerInfo);
12815             mProfileType = 0;
12816         }
12817     }
12818
12819     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12820         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12821         if (!isDebuggable) {
12822             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12823                 throw new SecurityException("Process not debuggable: " + app.packageName);
12824             }
12825         }
12826         mNativeDebuggingApp = processName;
12827     }
12828
12829     @Override
12830     public void setAlwaysFinish(boolean enabled) {
12831         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12832                 "setAlwaysFinish()");
12833
12834         long ident = Binder.clearCallingIdentity();
12835         try {
12836             Settings.Global.putInt(
12837                     mContext.getContentResolver(),
12838                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12839
12840             synchronized (this) {
12841                 mAlwaysFinishActivities = enabled;
12842             }
12843         } finally {
12844             Binder.restoreCallingIdentity(ident);
12845         }
12846     }
12847
12848     @Override
12849     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12850         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12851                 "setActivityController()");
12852         synchronized (this) {
12853             mController = controller;
12854             mControllerIsAMonkey = imAMonkey;
12855             Watchdog.getInstance().setActivityController(controller);
12856         }
12857     }
12858
12859     @Override
12860     public void setUserIsMonkey(boolean userIsMonkey) {
12861         synchronized (this) {
12862             synchronized (mPidsSelfLocked) {
12863                 final int callingPid = Binder.getCallingPid();
12864                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12865                 if (proc == null) {
12866                     throw new SecurityException("Unknown process: " + callingPid);
12867                 }
12868                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12869                     throw new SecurityException("Only an instrumentation process "
12870                             + "with a UiAutomation can call setUserIsMonkey");
12871                 }
12872             }
12873             mUserIsMonkey = userIsMonkey;
12874         }
12875     }
12876
12877     @Override
12878     public boolean isUserAMonkey() {
12879         synchronized (this) {
12880             // If there is a controller also implies the user is a monkey.
12881             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12882         }
12883     }
12884
12885     /**
12886      * @deprecated This method is only used by a few internal components and it will soon be
12887      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12888      * No new code should be calling it.
12889      */
12890     @Deprecated
12891     @Override
12892     public void requestBugReport(int bugreportType) {
12893         String extraOptions = null;
12894         switch (bugreportType) {
12895             case ActivityManager.BUGREPORT_OPTION_FULL:
12896                 // Default options.
12897                 break;
12898             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12899                 extraOptions = "bugreportplus";
12900                 break;
12901             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12902                 extraOptions = "bugreportremote";
12903                 break;
12904             case ActivityManager.BUGREPORT_OPTION_WEAR:
12905                 extraOptions = "bugreportwear";
12906                 break;
12907             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12908                 extraOptions = "bugreporttelephony";
12909                 break;
12910             default:
12911                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12912                         + bugreportType);
12913         }
12914         // Always log caller, even if it does not have permission to dump.
12915         String type = extraOptions == null ? "bugreport" : extraOptions;
12916         Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12917
12918         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12919         if (extraOptions != null) {
12920             SystemProperties.set("dumpstate.options", extraOptions);
12921         }
12922         SystemProperties.set("ctl.start", "bugreport");
12923     }
12924
12925     /**
12926      * @deprecated This method is only used by a few internal components and it will soon be
12927      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12928      * No new code should be calling it.
12929      */
12930     @Deprecated
12931     @Override
12932     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12933
12934         if (!TextUtils.isEmpty(shareTitle)) {
12935             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12936                 String errorStr = "shareTitle should be less than " +
12937                         MAX_BUGREPORT_TITLE_SIZE + " characters";
12938                 throw new IllegalArgumentException(errorStr);
12939             } else {
12940                 if (!TextUtils.isEmpty(shareDescription)) {
12941                     int length;
12942                     try {
12943                         length = shareDescription.getBytes("UTF-8").length;
12944                     } catch (UnsupportedEncodingException e) {
12945                         String errorStr = "shareDescription: UnsupportedEncodingException";
12946                         throw new IllegalArgumentException(errorStr);
12947                     }
12948                     if (length > SystemProperties.PROP_VALUE_MAX) {
12949                         String errorStr = "shareTitle should be less than " +
12950                                 SystemProperties.PROP_VALUE_MAX + " bytes";
12951                         throw new IllegalArgumentException(errorStr);
12952                     } else {
12953                         SystemProperties.set("dumpstate.options.description", shareDescription);
12954                     }
12955                 }
12956                 SystemProperties.set("dumpstate.options.title", shareTitle);
12957             }
12958         }
12959
12960         Slog.d(TAG, "Bugreport notification title " + shareTitle
12961                 + " description " + shareDescription);
12962         requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12963     }
12964
12965     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12966         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12967     }
12968
12969     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12970         if (r != null && (r.instr != null || r.usingWrapper)) {
12971             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12972         }
12973         return KEY_DISPATCHING_TIMEOUT;
12974     }
12975
12976     @Override
12977     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12978         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12979                 != PackageManager.PERMISSION_GRANTED) {
12980             throw new SecurityException("Requires permission "
12981                     + android.Manifest.permission.FILTER_EVENTS);
12982         }
12983         ProcessRecord proc;
12984         long timeout;
12985         synchronized (this) {
12986             synchronized (mPidsSelfLocked) {
12987                 proc = mPidsSelfLocked.get(pid);
12988             }
12989             timeout = getInputDispatchingTimeoutLocked(proc);
12990         }
12991
12992         if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12993             return -1;
12994         }
12995
12996         return timeout;
12997     }
12998
12999     /**
13000      * Handle input dispatching timeouts.
13001      * Returns whether input dispatching should be aborted or not.
13002      */
13003     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13004             final ActivityRecord activity, final ActivityRecord parent,
13005             final boolean aboveSystem, String reason) {
13006         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13007                 != PackageManager.PERMISSION_GRANTED) {
13008             throw new SecurityException("Requires permission "
13009                     + android.Manifest.permission.FILTER_EVENTS);
13010         }
13011
13012         final String annotation;
13013         if (reason == null) {
13014             annotation = "Input dispatching timed out";
13015         } else {
13016             annotation = "Input dispatching timed out (" + reason + ")";
13017         }
13018
13019         if (proc != null) {
13020             synchronized (this) {
13021                 if (proc.debugging) {
13022                     return false;
13023                 }
13024
13025                 if (proc.instr != null) {
13026                     Bundle info = new Bundle();
13027                     info.putString("shortMsg", "keyDispatchingTimedOut");
13028                     info.putString("longMsg", annotation);
13029                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13030                     return true;
13031                 }
13032             }
13033             mHandler.post(new Runnable() {
13034                 @Override
13035                 public void run() {
13036                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13037                 }
13038             });
13039         }
13040
13041         return true;
13042     }
13043
13044     @Override
13045     public Bundle getAssistContextExtras(int requestType) {
13046         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13047                 null, null, true /* focused */, true /* newSessionId */,
13048                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13049         if (pae == null) {
13050             return null;
13051         }
13052         synchronized (pae) {
13053             while (!pae.haveResult) {
13054                 try {
13055                     pae.wait();
13056                 } catch (InterruptedException e) {
13057                 }
13058             }
13059         }
13060         synchronized (this) {
13061             buildAssistBundleLocked(pae, pae.result);
13062             mPendingAssistExtras.remove(pae);
13063             mUiHandler.removeCallbacks(pae);
13064         }
13065         return pae.extras;
13066     }
13067
13068     @Override
13069     public boolean isAssistDataAllowedOnCurrentActivity() {
13070         int userId;
13071         synchronized (this) {
13072             final ActivityStack focusedStack = getFocusedStack();
13073             if (focusedStack == null || focusedStack.isAssistantStack()) {
13074                 return false;
13075             }
13076
13077             final ActivityRecord activity = focusedStack.topActivity();
13078             if (activity == null) {
13079                 return false;
13080             }
13081             userId = activity.userId;
13082         }
13083         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13084                 Context.DEVICE_POLICY_SERVICE);
13085         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13086     }
13087
13088     @Override
13089     public boolean showAssistFromActivity(IBinder token, Bundle args) {
13090         long ident = Binder.clearCallingIdentity();
13091         try {
13092             synchronized (this) {
13093                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13094                 ActivityRecord top = getFocusedStack().topActivity();
13095                 if (top != caller) {
13096                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13097                             + " is not current top " + top);
13098                     return false;
13099                 }
13100                 if (!top.nowVisible) {
13101                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13102                             + " is not visible");
13103                     return false;
13104                 }
13105             }
13106             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13107                     token);
13108         } finally {
13109             Binder.restoreCallingIdentity(ident);
13110         }
13111     }
13112
13113     @Override
13114     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13115             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13116         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13117                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13118                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13119     }
13120
13121     @Override
13122     public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13123             IBinder activityToken, int flags) {
13124         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13125                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13126                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13127     }
13128
13129     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13130             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13131             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13132             int flags) {
13133         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13134                 "enqueueAssistContext()");
13135
13136         synchronized (this) {
13137             ActivityRecord activity = getFocusedStack().topActivity();
13138             if (activity == null) {
13139                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13140                 return null;
13141             }
13142             if (activity.app == null || activity.app.thread == null) {
13143                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13144                 return null;
13145             }
13146             if (focused) {
13147                 if (activityToken != null) {
13148                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13149                     if (activity != caller) {
13150                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13151                                 + " is not current top " + activity);
13152                         return null;
13153                     }
13154                 }
13155             } else {
13156                 activity = ActivityRecord.forTokenLocked(activityToken);
13157                 if (activity == null) {
13158                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13159                             + " couldn't be found");
13160                     return null;
13161                 }
13162                 if (activity.app == null || activity.app.thread == null) {
13163                     Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13164                     return null;
13165                 }
13166             }
13167
13168             PendingAssistExtras pae;
13169             Bundle extras = new Bundle();
13170             if (args != null) {
13171                 extras.putAll(args);
13172             }
13173             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13174             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13175
13176             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13177                     userHandle);
13178             pae.isHome = activity.isHomeActivity();
13179
13180             // Increment the sessionId if necessary
13181             if (newSessionId) {
13182                 mViSessionId++;
13183             }
13184             try {
13185                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13186                         mViSessionId, flags);
13187                 mPendingAssistExtras.add(pae);
13188                 mUiHandler.postDelayed(pae, timeout);
13189             } catch (RemoteException e) {
13190                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13191                 return null;
13192             }
13193             return pae;
13194         }
13195     }
13196
13197     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13198         IResultReceiver receiver;
13199         synchronized (this) {
13200             mPendingAssistExtras.remove(pae);
13201             receiver = pae.receiver;
13202         }
13203         if (receiver != null) {
13204             // Caller wants result sent back to them.
13205             Bundle sendBundle = new Bundle();
13206             // At least return the receiver extras
13207             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13208                     pae.receiverExtras);
13209             try {
13210                 pae.receiver.send(0, sendBundle);
13211             } catch (RemoteException e) {
13212             }
13213         }
13214     }
13215
13216     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13217         if (result != null) {
13218             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13219         }
13220         if (pae.hint != null) {
13221             pae.extras.putBoolean(pae.hint, true);
13222         }
13223     }
13224
13225     /** Called from an app when assist data is ready. */
13226     @Override
13227     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13228             AssistContent content, Uri referrer) {
13229         PendingAssistExtras pae = (PendingAssistExtras)token;
13230         synchronized (pae) {
13231             pae.result = extras;
13232             pae.structure = structure;
13233             pae.content = content;
13234             if (referrer != null) {
13235                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13236             }
13237             if (structure != null) {
13238                 structure.setHomeActivity(pae.isHome);
13239             }
13240             pae.haveResult = true;
13241             pae.notifyAll();
13242             if (pae.intent == null && pae.receiver == null) {
13243                 // Caller is just waiting for the result.
13244                 return;
13245             }
13246         }
13247         // We are now ready to launch the assist activity.
13248         IResultReceiver sendReceiver = null;
13249         Bundle sendBundle = null;
13250         synchronized (this) {
13251             buildAssistBundleLocked(pae, extras);
13252             boolean exists = mPendingAssistExtras.remove(pae);
13253             mUiHandler.removeCallbacks(pae);
13254             if (!exists) {
13255                 // Timed out.
13256                 return;
13257             }
13258             if ((sendReceiver=pae.receiver) != null) {
13259                 // Caller wants result sent back to them.
13260                 sendBundle = new Bundle();
13261                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13262                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13263                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13264                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13265                         pae.receiverExtras);
13266             }
13267         }
13268         if (sendReceiver != null) {
13269             try {
13270                 sendReceiver.send(0, sendBundle);
13271             } catch (RemoteException e) {
13272             }
13273             return;
13274         }
13275
13276         final long ident = Binder.clearCallingIdentity();
13277         try {
13278             if (TextUtils.equals(pae.intent.getAction(),
13279                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13280                 pae.intent.putExtras(pae.extras);
13281                 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13282             } else {
13283                 pae.intent.replaceExtras(pae.extras);
13284                 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13285                         | Intent.FLAG_ACTIVITY_SINGLE_TOP
13286                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13287                 closeSystemDialogs("assist");
13288
13289                 try {
13290                     mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13291                 } catch (ActivityNotFoundException e) {
13292                     Slog.w(TAG, "No activity to handle assist action.", e);
13293                 }
13294             }
13295         } finally {
13296             Binder.restoreCallingIdentity(ident);
13297         }
13298     }
13299
13300     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13301             Bundle args) {
13302         return enqueueAssistContext(requestType, intent, hint, null, null, null,
13303                 true /* focused */, true /* newSessionId */, userHandle, args,
13304                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13305     }
13306
13307     public void registerProcessObserver(IProcessObserver observer) {
13308         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13309                 "registerProcessObserver()");
13310         synchronized (this) {
13311             mProcessObservers.register(observer);
13312         }
13313     }
13314
13315     @Override
13316     public void unregisterProcessObserver(IProcessObserver observer) {
13317         synchronized (this) {
13318             mProcessObservers.unregister(observer);
13319         }
13320     }
13321
13322     @Override
13323     public int getUidProcessState(int uid, String callingPackage) {
13324         if (!hasUsageStatsPermission(callingPackage)) {
13325             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13326                     "getUidProcessState");
13327         }
13328
13329         synchronized (this) {
13330             UidRecord uidRec = mActiveUids.get(uid);
13331             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13332         }
13333     }
13334
13335     @Override
13336     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13337             String callingPackage) {
13338         if (!hasUsageStatsPermission(callingPackage)) {
13339             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13340                     "registerUidObserver");
13341         }
13342         synchronized (this) {
13343             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13344                     callingPackage, which, cutpoint));
13345         }
13346     }
13347
13348     @Override
13349     public void unregisterUidObserver(IUidObserver observer) {
13350         synchronized (this) {
13351             mUidObservers.unregister(observer);
13352         }
13353     }
13354
13355     @Override
13356     public boolean convertFromTranslucent(IBinder token) {
13357         final long origId = Binder.clearCallingIdentity();
13358         try {
13359             synchronized (this) {
13360                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13361                 if (r == null) {
13362                     return false;
13363                 }
13364                 final boolean translucentChanged = r.changeWindowTranslucency(true);
13365                 if (translucentChanged) {
13366                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13367                 }
13368                 mWindowManager.setAppFullscreen(token, true);
13369                 return translucentChanged;
13370             }
13371         } finally {
13372             Binder.restoreCallingIdentity(origId);
13373         }
13374     }
13375
13376     @Override
13377     public boolean convertToTranslucent(IBinder token, Bundle options) {
13378         final long origId = Binder.clearCallingIdentity();
13379         try {
13380             synchronized (this) {
13381                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13382                 if (r == null) {
13383                     return false;
13384                 }
13385                 final TaskRecord task = r.getTask();
13386                 int index = task.mActivities.lastIndexOf(r);
13387                 if (index > 0) {
13388                     ActivityRecord under = task.mActivities.get(index - 1);
13389                     under.returningOptions = ActivityOptions.fromBundle(options);
13390                 }
13391                 final boolean translucentChanged = r.changeWindowTranslucency(false);
13392                 if (translucentChanged) {
13393                     r.getStack().convertActivityToTranslucent(r);
13394                 }
13395                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13396                 mWindowManager.setAppFullscreen(token, false);
13397                 return translucentChanged;
13398             }
13399         } finally {
13400             Binder.restoreCallingIdentity(origId);
13401         }
13402     }
13403
13404     @Override
13405     public Bundle getActivityOptions(IBinder token) {
13406         final long origId = Binder.clearCallingIdentity();
13407         try {
13408             synchronized (this) {
13409                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13410                 if (r != null) {
13411                     final ActivityOptions activityOptions = r.takeOptionsLocked();
13412                     return activityOptions == null ? null : activityOptions.toBundle();
13413                 }
13414                 return null;
13415             }
13416         } finally {
13417             Binder.restoreCallingIdentity(origId);
13418         }
13419     }
13420
13421     @Override
13422     public void setImmersive(IBinder token, boolean immersive) {
13423         synchronized(this) {
13424             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13425             if (r == null) {
13426                 throw new IllegalArgumentException();
13427             }
13428             r.immersive = immersive;
13429
13430             // update associated state if we're frontmost
13431             if (r == mStackSupervisor.getResumedActivityLocked()) {
13432                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13433                 applyUpdateLockStateLocked(r);
13434             }
13435         }
13436     }
13437
13438     @Override
13439     public boolean isImmersive(IBinder token) {
13440         synchronized (this) {
13441             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13442             if (r == null) {
13443                 throw new IllegalArgumentException();
13444             }
13445             return r.immersive;
13446         }
13447     }
13448
13449     @Override
13450     public void setVrThread(int tid) {
13451         enforceSystemHasVrFeature();
13452         synchronized (this) {
13453             synchronized (mPidsSelfLocked) {
13454                 final int pid = Binder.getCallingPid();
13455                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13456                 mVrController.setVrThreadLocked(tid, pid, proc);
13457             }
13458         }
13459     }
13460
13461     @Override
13462     public void setPersistentVrThread(int tid) {
13463         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13464             final String msg = "Permission Denial: setPersistentVrThread() from pid="
13465                     + Binder.getCallingPid()
13466                     + ", uid=" + Binder.getCallingUid()
13467                     + " requires " + permission.RESTRICTED_VR_ACCESS;
13468             Slog.w(TAG, msg);
13469             throw new SecurityException(msg);
13470         }
13471         enforceSystemHasVrFeature();
13472         synchronized (this) {
13473             synchronized (mPidsSelfLocked) {
13474                 final int pid = Binder.getCallingPid();
13475                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13476                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13477             }
13478         }
13479     }
13480
13481     /**
13482      * Schedule the given thread a normal scheduling priority.
13483      *
13484      * @param tid the tid of the thread to adjust the scheduling of.
13485      * @param suppressLogs {@code true} if any error logging should be disabled.
13486      *
13487      * @return {@code true} if this succeeded.
13488      */
13489     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13490         try {
13491             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13492             return true;
13493         } catch (IllegalArgumentException e) {
13494             if (!suppressLogs) {
13495                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13496             }
13497         } catch (SecurityException e) {
13498             if (!suppressLogs) {
13499                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13500             }
13501         }
13502         return false;
13503     }
13504
13505     /**
13506      * Schedule the given thread an FIFO scheduling priority.
13507      *
13508      * @param tid the tid of the thread to adjust the scheduling of.
13509      * @param suppressLogs {@code true} if any error logging should be disabled.
13510      *
13511      * @return {@code true} if this succeeded.
13512      */
13513     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13514         try {
13515             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13516             return true;
13517         } catch (IllegalArgumentException e) {
13518             if (!suppressLogs) {
13519                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13520             }
13521         } catch (SecurityException e) {
13522             if (!suppressLogs) {
13523                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13524             }
13525         }
13526         return false;
13527     }
13528
13529     /**
13530      * Check that we have the features required for VR-related API calls, and throw an exception if
13531      * not.
13532      */
13533     private void enforceSystemHasVrFeature() {
13534         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13535             throw new UnsupportedOperationException("VR mode not supported on this device!");
13536         }
13537     }
13538
13539     @Override
13540     public void setRenderThread(int tid) {
13541         synchronized (this) {
13542             ProcessRecord proc;
13543             int pid = Binder.getCallingPid();
13544             if (pid == Process.myPid()) {
13545                 demoteSystemServerRenderThread(tid);
13546                 return;
13547             }
13548             synchronized (mPidsSelfLocked) {
13549                 proc = mPidsSelfLocked.get(pid);
13550                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13551                     // ensure the tid belongs to the process
13552                     if (!isThreadInProcess(pid, tid)) {
13553                         throw new IllegalArgumentException(
13554                             "Render thread does not belong to process");
13555                     }
13556                     proc.renderThreadTid = tid;
13557                     if (DEBUG_OOM_ADJ) {
13558                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13559                     }
13560                     // promote to FIFO now
13561                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13562                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13563                         if (mUseFifoUiScheduling) {
13564                             setThreadScheduler(proc.renderThreadTid,
13565                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13566                         } else {
13567                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13568                         }
13569                     }
13570                 } else {
13571                     if (DEBUG_OOM_ADJ) {
13572                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13573                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
13574                                mUseFifoUiScheduling);
13575                     }
13576                 }
13577             }
13578         }
13579     }
13580
13581     /**
13582      * We only use RenderThread in system_server to store task snapshots to the disk, which should
13583      * happen in the background. Thus, demote render thread from system_server to a lower priority.
13584      *
13585      * @param tid the tid of the RenderThread
13586      */
13587     private void demoteSystemServerRenderThread(int tid) {
13588         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13589     }
13590
13591     @Override
13592     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13593         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13594             throw new UnsupportedOperationException("VR mode not supported on this device!");
13595         }
13596
13597         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13598
13599         ActivityRecord r;
13600         synchronized (this) {
13601             r = ActivityRecord.isInStackLocked(token);
13602         }
13603
13604         if (r == null) {
13605             throw new IllegalArgumentException();
13606         }
13607
13608         int err;
13609         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13610                 VrManagerInternal.NO_ERROR) {
13611             return err;
13612         }
13613
13614         synchronized(this) {
13615             r.requestedVrComponent = (enabled) ? packageName : null;
13616
13617             // Update associated state if this activity is currently focused
13618             if (r == mStackSupervisor.getResumedActivityLocked()) {
13619                 applyUpdateVrModeLocked(r);
13620             }
13621             return 0;
13622         }
13623     }
13624
13625     @Override
13626     public boolean isVrModePackageEnabled(ComponentName packageName) {
13627         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13628             throw new UnsupportedOperationException("VR mode not supported on this device!");
13629         }
13630
13631         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13632
13633         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13634                 VrManagerInternal.NO_ERROR;
13635     }
13636
13637     public boolean isTopActivityImmersive() {
13638         enforceNotIsolatedCaller("startActivity");
13639         synchronized (this) {
13640             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13641             return (r != null) ? r.immersive : false;
13642         }
13643     }
13644
13645     /**
13646      * @return whether the system should disable UI modes incompatible with VR mode.
13647      */
13648     boolean shouldDisableNonVrUiLocked() {
13649         return mVrController.shouldDisableNonVrUiLocked();
13650     }
13651
13652     @Override
13653     public boolean isTopOfTask(IBinder token) {
13654         synchronized (this) {
13655             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13656             if (r == null) {
13657                 throw new IllegalArgumentException();
13658             }
13659             return r.getTask().getTopActivity() == r;
13660         }
13661     }
13662
13663     @Override
13664     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13665         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13666             String msg = "Permission Denial: setHasTopUi() from pid="
13667                     + Binder.getCallingPid()
13668                     + ", uid=" + Binder.getCallingUid()
13669                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13670             Slog.w(TAG, msg);
13671             throw new SecurityException(msg);
13672         }
13673         final int pid = Binder.getCallingPid();
13674         final long origId = Binder.clearCallingIdentity();
13675         try {
13676             synchronized (this) {
13677                 boolean changed = false;
13678                 ProcessRecord pr;
13679                 synchronized (mPidsSelfLocked) {
13680                     pr = mPidsSelfLocked.get(pid);
13681                     if (pr == null) {
13682                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13683                         return;
13684                     }
13685                     if (pr.hasTopUi != hasTopUi) {
13686                         if (DEBUG_OOM_ADJ) {
13687                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13688                         }
13689                         pr.hasTopUi = hasTopUi;
13690                         changed = true;
13691                     }
13692                 }
13693                 if (changed) {
13694                     updateOomAdjLocked(pr, true);
13695                 }
13696             }
13697         } finally {
13698             Binder.restoreCallingIdentity(origId);
13699         }
13700     }
13701
13702     public final void enterSafeMode() {
13703         synchronized(this) {
13704             // It only makes sense to do this before the system is ready
13705             // and started launching other packages.
13706             if (!mSystemReady) {
13707                 try {
13708                     AppGlobals.getPackageManager().enterSafeMode();
13709                 } catch (RemoteException e) {
13710                 }
13711             }
13712
13713             mSafeMode = true;
13714         }
13715     }
13716
13717     public final void showSafeModeOverlay() {
13718         View v = LayoutInflater.from(mContext).inflate(
13719                 com.android.internal.R.layout.safe_mode, null);
13720         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13721         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13722         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13723         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13724         lp.gravity = Gravity.BOTTOM | Gravity.START;
13725         lp.format = v.getBackground().getOpacity();
13726         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13727                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13728         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13729         ((WindowManager)mContext.getSystemService(
13730                 Context.WINDOW_SERVICE)).addView(v, lp);
13731     }
13732
13733     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13734         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13735             return;
13736         }
13737         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13738         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13739         synchronized (stats) {
13740             if (mBatteryStatsService.isOnBattery()) {
13741                 mBatteryStatsService.enforceCallingPermission();
13742                 int MY_UID = Binder.getCallingUid();
13743                 final int uid;
13744                 if (sender == null) {
13745                     uid = sourceUid;
13746                 } else {
13747                     uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13748                 }
13749                 BatteryStatsImpl.Uid.Pkg pkg =
13750                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13751                             sourcePkg != null ? sourcePkg : rec.key.packageName);
13752                 pkg.noteWakeupAlarmLocked(tag);
13753             }
13754         }
13755     }
13756
13757     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13758         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13759             return;
13760         }
13761         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13762         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13763         synchronized (stats) {
13764             mBatteryStatsService.enforceCallingPermission();
13765             int MY_UID = Binder.getCallingUid();
13766             final int uid;
13767             if (sender == null) {
13768                 uid = sourceUid;
13769             } else {
13770                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13771             }
13772             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13773         }
13774     }
13775
13776     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13777         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13778             return;
13779         }
13780         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13781         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13782         synchronized (stats) {
13783             mBatteryStatsService.enforceCallingPermission();
13784             int MY_UID = Binder.getCallingUid();
13785             final int uid;
13786             if (sender == null) {
13787                 uid = sourceUid;
13788             } else {
13789                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13790             }
13791             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13792         }
13793     }
13794
13795     public boolean killPids(int[] pids, String pReason, boolean secure) {
13796         if (Binder.getCallingUid() != SYSTEM_UID) {
13797             throw new SecurityException("killPids only available to the system");
13798         }
13799         String reason = (pReason == null) ? "Unknown" : pReason;
13800         // XXX Note: don't acquire main activity lock here, because the window
13801         // manager calls in with its locks held.
13802
13803         boolean killed = false;
13804         synchronized (mPidsSelfLocked) {
13805             int worstType = 0;
13806             for (int i=0; i<pids.length; i++) {
13807                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13808                 if (proc != null) {
13809                     int type = proc.setAdj;
13810                     if (type > worstType) {
13811                         worstType = type;
13812                     }
13813                 }
13814             }
13815
13816             // If the worst oom_adj is somewhere in the cached proc LRU range,
13817             // then constrain it so we will kill all cached procs.
13818             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13819                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13820                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13821             }
13822
13823             // If this is not a secure call, don't let it kill processes that
13824             // are important.
13825             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13826                 worstType = ProcessList.SERVICE_ADJ;
13827             }
13828
13829             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13830             for (int i=0; i<pids.length; i++) {
13831                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13832                 if (proc == null) {
13833                     continue;
13834                 }
13835                 int adj = proc.setAdj;
13836                 if (adj >= worstType && !proc.killedByAm) {
13837                     proc.kill(reason, true);
13838                     killed = true;
13839                 }
13840             }
13841         }
13842         return killed;
13843     }
13844
13845     @Override
13846     public void killUid(int appId, int userId, String reason) {
13847         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13848         synchronized (this) {
13849             final long identity = Binder.clearCallingIdentity();
13850             try {
13851                 killPackageProcessesLocked(null, appId, userId,
13852                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13853                         reason != null ? reason : "kill uid");
13854             } finally {
13855                 Binder.restoreCallingIdentity(identity);
13856             }
13857         }
13858     }
13859
13860     @Override
13861     public boolean killProcessesBelowForeground(String reason) {
13862         if (Binder.getCallingUid() != SYSTEM_UID) {
13863             throw new SecurityException("killProcessesBelowForeground() only available to system");
13864         }
13865
13866         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13867     }
13868
13869     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13870         if (Binder.getCallingUid() != SYSTEM_UID) {
13871             throw new SecurityException("killProcessesBelowAdj() only available to system");
13872         }
13873
13874         boolean killed = false;
13875         synchronized (mPidsSelfLocked) {
13876             final int size = mPidsSelfLocked.size();
13877             for (int i = 0; i < size; i++) {
13878                 final int pid = mPidsSelfLocked.keyAt(i);
13879                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13880                 if (proc == null) continue;
13881
13882                 final int adj = proc.setAdj;
13883                 if (adj > belowAdj && !proc.killedByAm) {
13884                     proc.kill(reason, true);
13885                     killed = true;
13886                 }
13887             }
13888         }
13889         return killed;
13890     }
13891
13892     @Override
13893     public void hang(final IBinder who, boolean allowRestart) {
13894         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13895                 != PackageManager.PERMISSION_GRANTED) {
13896             throw new SecurityException("Requires permission "
13897                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13898         }
13899
13900         final IBinder.DeathRecipient death = new DeathRecipient() {
13901             @Override
13902             public void binderDied() {
13903                 synchronized (this) {
13904                     notifyAll();
13905                 }
13906             }
13907         };
13908
13909         try {
13910             who.linkToDeath(death, 0);
13911         } catch (RemoteException e) {
13912             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13913             return;
13914         }
13915
13916         synchronized (this) {
13917             Watchdog.getInstance().setAllowRestart(allowRestart);
13918             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13919             synchronized (death) {
13920                 while (who.isBinderAlive()) {
13921                     try {
13922                         death.wait();
13923                     } catch (InterruptedException e) {
13924                     }
13925                 }
13926             }
13927             Watchdog.getInstance().setAllowRestart(true);
13928         }
13929     }
13930
13931     @Override
13932     public void restart() {
13933         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13934                 != PackageManager.PERMISSION_GRANTED) {
13935             throw new SecurityException("Requires permission "
13936                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13937         }
13938
13939         Log.i(TAG, "Sending shutdown broadcast...");
13940
13941         BroadcastReceiver br = new BroadcastReceiver() {
13942             @Override public void onReceive(Context context, Intent intent) {
13943                 // Now the broadcast is done, finish up the low-level shutdown.
13944                 Log.i(TAG, "Shutting down activity manager...");
13945                 shutdown(10000);
13946                 Log.i(TAG, "Shutdown complete, restarting!");
13947                 killProcess(myPid());
13948                 System.exit(10);
13949             }
13950         };
13951
13952         // First send the high-level shut down broadcast.
13953         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13954         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13955         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13956         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13957         mContext.sendOrderedBroadcastAsUser(intent,
13958                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13959         */
13960         br.onReceive(mContext, intent);
13961     }
13962
13963     private long getLowRamTimeSinceIdle(long now) {
13964         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13965     }
13966
13967     @Override
13968     public void performIdleMaintenance() {
13969         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13970                 != PackageManager.PERMISSION_GRANTED) {
13971             throw new SecurityException("Requires permission "
13972                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13973         }
13974
13975         synchronized (this) {
13976             final long now = SystemClock.uptimeMillis();
13977             final long timeSinceLastIdle = now - mLastIdleTime;
13978             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13979             mLastIdleTime = now;
13980             mLowRamTimeSinceLastIdle = 0;
13981             if (mLowRamStartTime != 0) {
13982                 mLowRamStartTime = now;
13983             }
13984
13985             StringBuilder sb = new StringBuilder(128);
13986             sb.append("Idle maintenance over ");
13987             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13988             sb.append(" low RAM for ");
13989             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13990             Slog.i(TAG, sb.toString());
13991
13992             // If at least 1/3 of our time since the last idle period has been spent
13993             // with RAM low, then we want to kill processes.
13994             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13995
13996             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13997                 ProcessRecord proc = mLruProcesses.get(i);
13998                 if (proc.notCachedSinceIdle) {
13999                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14000                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14001                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14002                         if (doKilling && proc.initialIdlePss != 0
14003                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14004                             sb = new StringBuilder(128);
14005                             sb.append("Kill");
14006                             sb.append(proc.processName);
14007                             sb.append(" in idle maint: pss=");
14008                             sb.append(proc.lastPss);
14009                             sb.append(", swapPss=");
14010                             sb.append(proc.lastSwapPss);
14011                             sb.append(", initialPss=");
14012                             sb.append(proc.initialIdlePss);
14013                             sb.append(", period=");
14014                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
14015                             sb.append(", lowRamPeriod=");
14016                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14017                             Slog.wtfQuiet(TAG, sb.toString());
14018                             proc.kill("idle maint (pss " + proc.lastPss
14019                                     + " from " + proc.initialIdlePss + ")", true);
14020                         }
14021                     }
14022                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14023                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14024                     proc.notCachedSinceIdle = true;
14025                     proc.initialIdlePss = 0;
14026                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14027                             mTestPssMode, isSleepingLocked(), now);
14028                 }
14029             }
14030
14031             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14032             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14033         }
14034     }
14035
14036     @Override
14037     public void sendIdleJobTrigger() {
14038         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14039                 != PackageManager.PERMISSION_GRANTED) {
14040             throw new SecurityException("Requires permission "
14041                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14042         }
14043
14044         final long ident = Binder.clearCallingIdentity();
14045         try {
14046             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14047                     .setPackage("android")
14048                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14049             broadcastIntent(null, intent, null, null, 0, null, null, null,
14050                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14051         } finally {
14052             Binder.restoreCallingIdentity(ident);
14053         }
14054     }
14055
14056     private void retrieveSettings() {
14057         final ContentResolver resolver = mContext.getContentResolver();
14058         final boolean freeformWindowManagement =
14059                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14060                         || Settings.Global.getInt(
14061                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14062
14063         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14064         final boolean supportsPictureInPicture = supportsMultiWindow &&
14065                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14066         final boolean supportsSplitScreenMultiWindow =
14067                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14068         final boolean supportsMultiDisplay = mContext.getPackageManager()
14069                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14070         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14071         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14072         final boolean alwaysFinishActivities =
14073                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14074         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14075         final boolean forceResizable = Settings.Global.getInt(
14076                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14077         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14078                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14079         final boolean supportsLeanbackOnly =
14080                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14081
14082         // Transfer any global setting for forcing RTL layout, into a System Property
14083         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14084
14085         final Configuration configuration = new Configuration();
14086         Settings.System.getConfiguration(resolver, configuration);
14087         if (forceRtl) {
14088             // This will take care of setting the correct layout direction flags
14089             configuration.setLayoutDirection(configuration.locale);
14090         }
14091
14092         synchronized (this) {
14093             mDebugApp = mOrigDebugApp = debugApp;
14094             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14095             mAlwaysFinishActivities = alwaysFinishActivities;
14096             mSupportsLeanbackOnly = supportsLeanbackOnly;
14097             mForceResizableActivities = forceResizable;
14098             final boolean multiWindowFormEnabled = freeformWindowManagement
14099                     || supportsSplitScreenMultiWindow
14100                     || supportsPictureInPicture
14101                     || supportsMultiDisplay;
14102             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14103                 mSupportsMultiWindow = true;
14104                 mSupportsFreeformWindowManagement = freeformWindowManagement;
14105                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14106                 mSupportsPictureInPicture = supportsPictureInPicture;
14107                 mSupportsMultiDisplay = supportsMultiDisplay;
14108             } else {
14109                 mSupportsMultiWindow = false;
14110                 mSupportsFreeformWindowManagement = false;
14111                 mSupportsSplitScreenMultiWindow = false;
14112                 mSupportsPictureInPicture = false;
14113                 mSupportsMultiDisplay = false;
14114             }
14115             mWindowManager.setForceResizableTasks(mForceResizableActivities);
14116             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14117             // This happens before any activities are started, so we can change global configuration
14118             // in-place.
14119             updateConfigurationLocked(configuration, null, true);
14120             final Configuration globalConfig = getGlobalConfiguration();
14121             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14122
14123             // Load resources only after the current configuration has been set.
14124             final Resources res = mContext.getResources();
14125             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14126             mThumbnailWidth = res.getDimensionPixelSize(
14127                     com.android.internal.R.dimen.thumbnail_width);
14128             mThumbnailHeight = res.getDimensionPixelSize(
14129                     com.android.internal.R.dimen.thumbnail_height);
14130             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14131                     com.android.internal.R.string.config_appsNotReportingCrashes));
14132             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14133                     com.android.internal.R.bool.config_customUserSwitchUi);
14134             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14135                 mFullscreenThumbnailScale = (float) res
14136                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14137                     (float) globalConfig.screenWidthDp;
14138             } else {
14139                 mFullscreenThumbnailScale = res.getFraction(
14140                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14141             }
14142             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14143         }
14144     }
14145
14146     public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14147         traceLog.traceBegin("PhaseActivityManagerReady");
14148         synchronized(this) {
14149             if (mSystemReady) {
14150                 // If we're done calling all the receivers, run the next "boot phase" passed in
14151                 // by the SystemServer
14152                 if (goingCallback != null) {
14153                     goingCallback.run();
14154                 }
14155                 return;
14156             }
14157
14158             mLocalDeviceIdleController
14159                     = LocalServices.getService(DeviceIdleController.LocalService.class);
14160             mAssistUtils = new AssistUtils(mContext);
14161             mVrController.onSystemReady();
14162             // Make sure we have the current profile info, since it is needed for security checks.
14163             mUserController.onSystemReady();
14164             mRecentTasks.onSystemReadyLocked();
14165             mAppOpsService.systemReady();
14166             mSystemReady = true;
14167         }
14168
14169         try {
14170             sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14171                     ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14172                     .getSerial();
14173         } catch (RemoteException e) {}
14174
14175         ArrayList<ProcessRecord> procsToKill = null;
14176         synchronized(mPidsSelfLocked) {
14177             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14178                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14179                 if (!isAllowedWhileBooting(proc.info)){
14180                     if (procsToKill == null) {
14181                         procsToKill = new ArrayList<ProcessRecord>();
14182                     }
14183                     procsToKill.add(proc);
14184                 }
14185             }
14186         }
14187
14188         synchronized(this) {
14189             if (procsToKill != null) {
14190                 for (int i=procsToKill.size()-1; i>=0; i--) {
14191                     ProcessRecord proc = procsToKill.get(i);
14192                     Slog.i(TAG, "Removing system update proc: " + proc);
14193                     removeProcessLocked(proc, true, false, "system update done");
14194                 }
14195             }
14196
14197             // Now that we have cleaned up any update processes, we
14198             // are ready to start launching real processes and know that
14199             // we won't trample on them any more.
14200             mProcessesReady = true;
14201         }
14202
14203         Slog.i(TAG, "System now ready");
14204         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14205             SystemClock.uptimeMillis());
14206
14207         synchronized(this) {
14208             // Make sure we have no pre-ready processes sitting around.
14209
14210             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14211                 ResolveInfo ri = mContext.getPackageManager()
14212                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14213                                 STOCK_PM_FLAGS);
14214                 CharSequence errorMsg = null;
14215                 if (ri != null) {
14216                     ActivityInfo ai = ri.activityInfo;
14217                     ApplicationInfo app = ai.applicationInfo;
14218                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14219                         mTopAction = Intent.ACTION_FACTORY_TEST;
14220                         mTopData = null;
14221                         mTopComponent = new ComponentName(app.packageName,
14222                                 ai.name);
14223                     } else {
14224                         errorMsg = mContext.getResources().getText(
14225                                 com.android.internal.R.string.factorytest_not_system);
14226                     }
14227                 } else {
14228                     errorMsg = mContext.getResources().getText(
14229                             com.android.internal.R.string.factorytest_no_action);
14230                 }
14231                 if (errorMsg != null) {
14232                     mTopAction = null;
14233                     mTopData = null;
14234                     mTopComponent = null;
14235                     Message msg = Message.obtain();
14236                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14237                     msg.getData().putCharSequence("msg", errorMsg);
14238                     mUiHandler.sendMessage(msg);
14239                 }
14240             }
14241         }
14242
14243         retrieveSettings();
14244         final int currentUserId;
14245         synchronized (this) {
14246             currentUserId = mUserController.getCurrentUserIdLocked();
14247             readGrantedUriPermissionsLocked();
14248         }
14249
14250         if (goingCallback != null) goingCallback.run();
14251         traceLog.traceBegin("ActivityManagerStartApps");
14252         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14253                 Integer.toString(currentUserId), currentUserId);
14254         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14255                 Integer.toString(currentUserId), currentUserId);
14256         mSystemServiceManager.startUser(currentUserId);
14257
14258         synchronized (this) {
14259             // Only start up encryption-aware persistent apps; once user is
14260             // unlocked we'll come back around and start unaware apps
14261             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14262
14263             // Start up initial activity.
14264             mBooting = true;
14265             // Enable home activity for system user, so that the system can always boot. We don't
14266             // do this when the system user is not setup since the setup wizard should be the one
14267             // to handle home activity in this case.
14268             if (UserManager.isSplitSystemUser() &&
14269                     Settings.Secure.getInt(mContext.getContentResolver(),
14270                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14271                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14272                 try {
14273                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14274                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14275                             UserHandle.USER_SYSTEM);
14276                 } catch (RemoteException e) {
14277                     throw e.rethrowAsRuntimeException();
14278                 }
14279             }
14280             startHomeActivityLocked(currentUserId, "systemReady");
14281
14282             try {
14283                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14284                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14285                             + " data partition or your device will be unstable.");
14286                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14287                 }
14288             } catch (RemoteException e) {
14289             }
14290
14291             if (!Build.isBuildConsistent()) {
14292                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14293                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14294             }
14295
14296             long ident = Binder.clearCallingIdentity();
14297             try {
14298                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14299                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14300                         | Intent.FLAG_RECEIVER_FOREGROUND);
14301                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14302                 broadcastIntentLocked(null, null, intent,
14303                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14304                         null, false, false, MY_PID, SYSTEM_UID,
14305                         currentUserId);
14306                 intent = new Intent(Intent.ACTION_USER_STARTING);
14307                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14308                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14309                 broadcastIntentLocked(null, null, intent,
14310                         null, new IIntentReceiver.Stub() {
14311                             @Override
14312                             public void performReceive(Intent intent, int resultCode, String data,
14313                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14314                                     throws RemoteException {
14315                             }
14316                         }, 0, null, null,
14317                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14318                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14319             } catch (Throwable t) {
14320                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14321             } finally {
14322                 Binder.restoreCallingIdentity(ident);
14323             }
14324             mStackSupervisor.resumeFocusedStackTopActivityLocked();
14325             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14326             traceLog.traceEnd(); // ActivityManagerStartApps
14327             traceLog.traceEnd(); // PhaseActivityManagerReady
14328         }
14329     }
14330
14331     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14332         synchronized (this) {
14333             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14334         }
14335     }
14336
14337     void skipCurrentReceiverLocked(ProcessRecord app) {
14338         for (BroadcastQueue queue : mBroadcastQueues) {
14339             queue.skipCurrentReceiverLocked(app);
14340         }
14341     }
14342
14343     /**
14344      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14345      * The application process will exit immediately after this call returns.
14346      * @param app object of the crashing app, null for the system server
14347      * @param crashInfo describing the exception
14348      */
14349     public void handleApplicationCrash(IBinder app,
14350             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14351         ProcessRecord r = findAppProcess(app, "Crash");
14352         final String processName = app == null ? "system_server"
14353                 : (r == null ? "unknown" : r.processName);
14354
14355         handleApplicationCrashInner("crash", r, processName, crashInfo);
14356     }
14357
14358     /* Native crash reporting uses this inner version because it needs to be somewhat
14359      * decoupled from the AM-managed cleanup lifecycle
14360      */
14361     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14362             ApplicationErrorReport.CrashInfo crashInfo) {
14363         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14364                 UserHandle.getUserId(Binder.getCallingUid()), processName,
14365                 r == null ? -1 : r.info.flags,
14366                 crashInfo.exceptionClassName,
14367                 crashInfo.exceptionMessage,
14368                 crashInfo.throwFileName,
14369                 crashInfo.throwLineNumber);
14370
14371         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14372
14373         mAppErrors.crashApplication(r, crashInfo);
14374     }
14375
14376     public void handleApplicationStrictModeViolation(
14377             IBinder app,
14378             int violationMask,
14379             StrictMode.ViolationInfo info) {
14380         ProcessRecord r = findAppProcess(app, "StrictMode");
14381         if (r == null) {
14382             return;
14383         }
14384
14385         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14386             Integer stackFingerprint = info.hashCode();
14387             boolean logIt = true;
14388             synchronized (mAlreadyLoggedViolatedStacks) {
14389                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14390                     logIt = false;
14391                     // TODO: sub-sample into EventLog for these, with
14392                     // the info.durationMillis?  Then we'd get
14393                     // the relative pain numbers, without logging all
14394                     // the stack traces repeatedly.  We'd want to do
14395                     // likewise in the client code, which also does
14396                     // dup suppression, before the Binder call.
14397                 } else {
14398                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14399                         mAlreadyLoggedViolatedStacks.clear();
14400                     }
14401                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14402                 }
14403             }
14404             if (logIt) {
14405                 logStrictModeViolationToDropBox(r, info);
14406             }
14407         }
14408
14409         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14410             AppErrorResult result = new AppErrorResult();
14411             synchronized (this) {
14412                 final long origId = Binder.clearCallingIdentity();
14413
14414                 Message msg = Message.obtain();
14415                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14416                 HashMap<String, Object> data = new HashMap<String, Object>();
14417                 data.put("result", result);
14418                 data.put("app", r);
14419                 data.put("violationMask", violationMask);
14420                 data.put("info", info);
14421                 msg.obj = data;
14422                 mUiHandler.sendMessage(msg);
14423
14424                 Binder.restoreCallingIdentity(origId);
14425             }
14426             int res = result.get();
14427             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14428         }
14429     }
14430
14431     // Depending on the policy in effect, there could be a bunch of
14432     // these in quick succession so we try to batch these together to
14433     // minimize disk writes, number of dropbox entries, and maximize
14434     // compression, by having more fewer, larger records.
14435     private void logStrictModeViolationToDropBox(
14436             ProcessRecord process,
14437             StrictMode.ViolationInfo info) {
14438         if (info == null) {
14439             return;
14440         }
14441         final boolean isSystemApp = process == null ||
14442                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14443                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14444         final String processName = process == null ? "unknown" : process.processName;
14445         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14446         final DropBoxManager dbox = (DropBoxManager)
14447                 mContext.getSystemService(Context.DROPBOX_SERVICE);
14448
14449         // Exit early if the dropbox isn't configured to accept this report type.
14450         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14451
14452         boolean bufferWasEmpty;
14453         boolean needsFlush;
14454         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14455         synchronized (sb) {
14456             bufferWasEmpty = sb.length() == 0;
14457             appendDropBoxProcessHeaders(process, processName, sb);
14458             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14459             sb.append("System-App: ").append(isSystemApp).append("\n");
14460             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14461             if (info.violationNumThisLoop != 0) {
14462                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14463             }
14464             if (info.numAnimationsRunning != 0) {
14465                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14466             }
14467             if (info.broadcastIntentAction != null) {
14468                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14469             }
14470             if (info.durationMillis != -1) {
14471                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14472             }
14473             if (info.numInstances != -1) {
14474                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14475             }
14476             if (info.tags != null) {
14477                 for (String tag : info.tags) {
14478                     sb.append("Span-Tag: ").append(tag).append("\n");
14479                 }
14480             }
14481             sb.append("\n");
14482             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14483                 sb.append(info.crashInfo.stackTrace);
14484                 sb.append("\n");
14485             }
14486             if (info.message != null) {
14487                 sb.append(info.message);
14488                 sb.append("\n");
14489             }
14490
14491             // Only buffer up to ~64k.  Various logging bits truncate
14492             // things at 128k.
14493             needsFlush = (sb.length() > 64 * 1024);
14494         }
14495
14496         // Flush immediately if the buffer's grown too large, or this
14497         // is a non-system app.  Non-system apps are isolated with a
14498         // different tag & policy and not batched.
14499         //
14500         // Batching is useful during internal testing with
14501         // StrictMode settings turned up high.  Without batching,
14502         // thousands of separate files could be created on boot.
14503         if (!isSystemApp || needsFlush) {
14504             new Thread("Error dump: " + dropboxTag) {
14505                 @Override
14506                 public void run() {
14507                     String report;
14508                     synchronized (sb) {
14509                         report = sb.toString();
14510                         sb.delete(0, sb.length());
14511                         sb.trimToSize();
14512                     }
14513                     if (report.length() != 0) {
14514                         dbox.addText(dropboxTag, report);
14515                     }
14516                 }
14517             }.start();
14518             return;
14519         }
14520
14521         // System app batching:
14522         if (!bufferWasEmpty) {
14523             // An existing dropbox-writing thread is outstanding, so
14524             // we don't need to start it up.  The existing thread will
14525             // catch the buffer appends we just did.
14526             return;
14527         }
14528
14529         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14530         // (After this point, we shouldn't access AMS internal data structures.)
14531         new Thread("Error dump: " + dropboxTag) {
14532             @Override
14533             public void run() {
14534                 // 5 second sleep to let stacks arrive and be batched together
14535                 try {
14536                     Thread.sleep(5000);  // 5 seconds
14537                 } catch (InterruptedException e) {}
14538
14539                 String errorReport;
14540                 synchronized (mStrictModeBuffer) {
14541                     errorReport = mStrictModeBuffer.toString();
14542                     if (errorReport.length() == 0) {
14543                         return;
14544                     }
14545                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14546                     mStrictModeBuffer.trimToSize();
14547                 }
14548                 dbox.addText(dropboxTag, errorReport);
14549             }
14550         }.start();
14551     }
14552
14553     /**
14554      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14555      * @param app object of the crashing app, null for the system server
14556      * @param tag reported by the caller
14557      * @param system whether this wtf is coming from the system
14558      * @param crashInfo describing the context of the error
14559      * @return true if the process should exit immediately (WTF is fatal)
14560      */
14561     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14562             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14563         final int callingUid = Binder.getCallingUid();
14564         final int callingPid = Binder.getCallingPid();
14565
14566         if (system) {
14567             // If this is coming from the system, we could very well have low-level
14568             // system locks held, so we want to do this all asynchronously.  And we
14569             // never want this to become fatal, so there is that too.
14570             mHandler.post(new Runnable() {
14571                 @Override public void run() {
14572                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14573                 }
14574             });
14575             return false;
14576         }
14577
14578         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14579                 crashInfo);
14580
14581         final boolean isFatal = Build.IS_ENG || Settings.Global
14582                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14583         final boolean isSystem = (r == null) || r.persistent;
14584
14585         if (isFatal && !isSystem) {
14586             mAppErrors.crashApplication(r, crashInfo);
14587             return true;
14588         } else {
14589             return false;
14590         }
14591     }
14592
14593     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14594             final ApplicationErrorReport.CrashInfo crashInfo) {
14595         final ProcessRecord r = findAppProcess(app, "WTF");
14596         final String processName = app == null ? "system_server"
14597                 : (r == null ? "unknown" : r.processName);
14598
14599         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14600                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14601
14602         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14603
14604         return r;
14605     }
14606
14607     /**
14608      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14609      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14610      */
14611     private ProcessRecord findAppProcess(IBinder app, String reason) {
14612         if (app == null) {
14613             return null;
14614         }
14615
14616         synchronized (this) {
14617             final int NP = mProcessNames.getMap().size();
14618             for (int ip=0; ip<NP; ip++) {
14619                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14620                 final int NA = apps.size();
14621                 for (int ia=0; ia<NA; ia++) {
14622                     ProcessRecord p = apps.valueAt(ia);
14623                     if (p.thread != null && p.thread.asBinder() == app) {
14624                         return p;
14625                     }
14626                 }
14627             }
14628
14629             Slog.w(TAG, "Can't find mystery application for " + reason
14630                     + " from pid=" + Binder.getCallingPid()
14631                     + " uid=" + Binder.getCallingUid() + ": " + app);
14632             return null;
14633         }
14634     }
14635
14636     /**
14637      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14638      * to append various headers to the dropbox log text.
14639      */
14640     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14641             StringBuilder sb) {
14642         // Watchdog thread ends up invoking this function (with
14643         // a null ProcessRecord) to add the stack file to dropbox.
14644         // Do not acquire a lock on this (am) in such cases, as it
14645         // could cause a potential deadlock, if and when watchdog
14646         // is invoked due to unavailability of lock on am and it
14647         // would prevent watchdog from killing system_server.
14648         if (process == null) {
14649             sb.append("Process: ").append(processName).append("\n");
14650             return;
14651         }
14652         // Note: ProcessRecord 'process' is guarded by the service
14653         // instance.  (notably process.pkgList, which could otherwise change
14654         // concurrently during execution of this method)
14655         synchronized (this) {
14656             sb.append("Process: ").append(processName).append("\n");
14657             sb.append("PID: ").append(process.pid).append("\n");
14658             int flags = process.info.flags;
14659             IPackageManager pm = AppGlobals.getPackageManager();
14660             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14661             for (int ip=0; ip<process.pkgList.size(); ip++) {
14662                 String pkg = process.pkgList.keyAt(ip);
14663                 sb.append("Package: ").append(pkg);
14664                 try {
14665                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14666                     if (pi != null) {
14667                         sb.append(" v").append(pi.versionCode);
14668                         if (pi.versionName != null) {
14669                             sb.append(" (").append(pi.versionName).append(")");
14670                         }
14671                     }
14672                 } catch (RemoteException e) {
14673                     Slog.e(TAG, "Error getting package info: " + pkg, e);
14674                 }
14675                 sb.append("\n");
14676             }
14677             if (process.info.isInstantApp()) {
14678                 sb.append("Instant-App: true\n");
14679             }
14680         }
14681     }
14682
14683     private static String processClass(ProcessRecord process) {
14684         if (process == null || process.pid == MY_PID) {
14685             return "system_server";
14686         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14687             return "system_app";
14688         } else {
14689             return "data_app";
14690         }
14691     }
14692
14693     private volatile long mWtfClusterStart;
14694     private volatile int mWtfClusterCount;
14695
14696     /**
14697      * Write a description of an error (crash, WTF, ANR) to the drop box.
14698      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14699      * @param process which caused the error, null means the system server
14700      * @param activity which triggered the error, null if unknown
14701      * @param parent activity related to the error, null if unknown
14702      * @param subject line related to the error, null if absent
14703      * @param report in long form describing the error, null if absent
14704      * @param dataFile text file to include in the report, null if none
14705      * @param crashInfo giving an application stack trace, null if absent
14706      */
14707     public void addErrorToDropBox(String eventType,
14708             ProcessRecord process, String processName, ActivityRecord activity,
14709             ActivityRecord parent, String subject,
14710             final String report, final File dataFile,
14711             final ApplicationErrorReport.CrashInfo crashInfo) {
14712         // NOTE -- this must never acquire the ActivityManagerService lock,
14713         // otherwise the watchdog may be prevented from resetting the system.
14714
14715         // Bail early if not published yet
14716         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14717         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14718
14719         // Exit early if the dropbox isn't configured to accept this report type.
14720         final String dropboxTag = processClass(process) + "_" + eventType;
14721         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14722
14723         // Rate-limit how often we're willing to do the heavy lifting below to
14724         // collect and record logs; currently 5 logs per 10 second period.
14725         final long now = SystemClock.elapsedRealtime();
14726         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14727             mWtfClusterStart = now;
14728             mWtfClusterCount = 1;
14729         } else {
14730             if (mWtfClusterCount++ >= 5) return;
14731         }
14732
14733         final StringBuilder sb = new StringBuilder(1024);
14734         appendDropBoxProcessHeaders(process, processName, sb);
14735         if (process != null) {
14736             sb.append("Foreground: ")
14737                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14738                     .append("\n");
14739         }
14740         if (activity != null) {
14741             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14742         }
14743         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14744             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14745         }
14746         if (parent != null && parent != activity) {
14747             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14748         }
14749         if (subject != null) {
14750             sb.append("Subject: ").append(subject).append("\n");
14751         }
14752         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14753         if (Debug.isDebuggerConnected()) {
14754             sb.append("Debugger: Connected\n");
14755         }
14756         sb.append("\n");
14757
14758         // Do the rest in a worker thread to avoid blocking the caller on I/O
14759         // (After this point, we shouldn't access AMS internal data structures.)
14760         Thread worker = new Thread("Error dump: " + dropboxTag) {
14761             @Override
14762             public void run() {
14763                 if (report != null) {
14764                     sb.append(report);
14765                 }
14766
14767                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14768                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14769                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14770                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14771
14772                 if (dataFile != null && maxDataFileSize > 0) {
14773                     try {
14774                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14775                                     "\n\n[[TRUNCATED]]"));
14776                     } catch (IOException e) {
14777                         Slog.e(TAG, "Error reading " + dataFile, e);
14778                     }
14779                 }
14780                 if (crashInfo != null && crashInfo.stackTrace != null) {
14781                     sb.append(crashInfo.stackTrace);
14782                 }
14783
14784                 if (lines > 0) {
14785                     sb.append("\n");
14786
14787                     // Merge several logcat streams, and take the last N lines
14788                     InputStreamReader input = null;
14789                     try {
14790                         java.lang.Process logcat = new ProcessBuilder(
14791                                 "/system/bin/timeout", "-k", "15s", "10s",
14792                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14793                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14794                                         .redirectErrorStream(true).start();
14795
14796                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
14797                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
14798                         input = new InputStreamReader(logcat.getInputStream());
14799
14800                         int num;
14801                         char[] buf = new char[8192];
14802                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14803                     } catch (IOException e) {
14804                         Slog.e(TAG, "Error running logcat", e);
14805                     } finally {
14806                         if (input != null) try { input.close(); } catch (IOException e) {}
14807                     }
14808                 }
14809
14810                 dbox.addText(dropboxTag, sb.toString());
14811             }
14812         };
14813
14814         if (process == null) {
14815             // If process is null, we are being called from some internal code
14816             // and may be about to die -- run this synchronously.
14817             worker.run();
14818         } else {
14819             worker.start();
14820         }
14821     }
14822
14823     @Override
14824     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14825         enforceNotIsolatedCaller("getProcessesInErrorState");
14826         // assume our apps are happy - lazy create the list
14827         List<ActivityManager.ProcessErrorStateInfo> errList = null;
14828
14829         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14830                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14831         int userId = UserHandle.getUserId(Binder.getCallingUid());
14832
14833         synchronized (this) {
14834
14835             // iterate across all processes
14836             for (int i=mLruProcesses.size()-1; i>=0; i--) {
14837                 ProcessRecord app = mLruProcesses.get(i);
14838                 if (!allUsers && app.userId != userId) {
14839                     continue;
14840                 }
14841                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14842                     // This one's in trouble, so we'll generate a report for it
14843                     // crashes are higher priority (in case there's a crash *and* an anr)
14844                     ActivityManager.ProcessErrorStateInfo report = null;
14845                     if (app.crashing) {
14846                         report = app.crashingReport;
14847                     } else if (app.notResponding) {
14848                         report = app.notRespondingReport;
14849                     }
14850
14851                     if (report != null) {
14852                         if (errList == null) {
14853                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14854                         }
14855                         errList.add(report);
14856                     } else {
14857                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
14858                                 " crashing = " + app.crashing +
14859                                 " notResponding = " + app.notResponding);
14860                     }
14861                 }
14862             }
14863         }
14864
14865         return errList;
14866     }
14867
14868     static int procStateToImportance(int procState, int memAdj,
14869             ActivityManager.RunningAppProcessInfo currApp,
14870             int clientTargetSdk) {
14871         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14872                 procState, clientTargetSdk);
14873         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14874             currApp.lru = memAdj;
14875         } else {
14876             currApp.lru = 0;
14877         }
14878         return imp;
14879     }
14880
14881     private void fillInProcMemInfo(ProcessRecord app,
14882             ActivityManager.RunningAppProcessInfo outInfo,
14883             int clientTargetSdk) {
14884         outInfo.pid = app.pid;
14885         outInfo.uid = app.info.uid;
14886         if (mHeavyWeightProcess == app) {
14887             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14888         }
14889         if (app.persistent) {
14890             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14891         }
14892         if (app.activities.size() > 0) {
14893             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14894         }
14895         outInfo.lastTrimLevel = app.trimMemoryLevel;
14896         int adj = app.curAdj;
14897         int procState = app.curProcState;
14898         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14899         outInfo.importanceReasonCode = app.adjTypeCode;
14900         outInfo.processState = app.curProcState;
14901     }
14902
14903     @Override
14904     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14905         enforceNotIsolatedCaller("getRunningAppProcesses");
14906
14907         final int callingUid = Binder.getCallingUid();
14908         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14909
14910         // Lazy instantiation of list
14911         List<ActivityManager.RunningAppProcessInfo> runList = null;
14912         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14913                 callingUid) == PackageManager.PERMISSION_GRANTED;
14914         final int userId = UserHandle.getUserId(callingUid);
14915         final boolean allUids = isGetTasksAllowed(
14916                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14917
14918         synchronized (this) {
14919             // Iterate across all processes
14920             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14921                 ProcessRecord app = mLruProcesses.get(i);
14922                 if ((!allUsers && app.userId != userId)
14923                         || (!allUids && app.uid != callingUid)) {
14924                     continue;
14925                 }
14926                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14927                     // Generate process state info for running application
14928                     ActivityManager.RunningAppProcessInfo currApp =
14929                         new ActivityManager.RunningAppProcessInfo(app.processName,
14930                                 app.pid, app.getPackageList());
14931                     fillInProcMemInfo(app, currApp, clientTargetSdk);
14932                     if (app.adjSource instanceof ProcessRecord) {
14933                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14934                         currApp.importanceReasonImportance =
14935                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14936                                         app.adjSourceProcState);
14937                     } else if (app.adjSource instanceof ActivityRecord) {
14938                         ActivityRecord r = (ActivityRecord)app.adjSource;
14939                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14940                     }
14941                     if (app.adjTarget instanceof ComponentName) {
14942                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14943                     }
14944                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14945                     //        + " lru=" + currApp.lru);
14946                     if (runList == null) {
14947                         runList = new ArrayList<>();
14948                     }
14949                     runList.add(currApp);
14950                 }
14951             }
14952         }
14953         return runList;
14954     }
14955
14956     @Override
14957     public List<ApplicationInfo> getRunningExternalApplications() {
14958         enforceNotIsolatedCaller("getRunningExternalApplications");
14959         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14960         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14961         if (runningApps != null && runningApps.size() > 0) {
14962             Set<String> extList = new HashSet<String>();
14963             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14964                 if (app.pkgList != null) {
14965                     for (String pkg : app.pkgList) {
14966                         extList.add(pkg);
14967                     }
14968                 }
14969             }
14970             IPackageManager pm = AppGlobals.getPackageManager();
14971             for (String pkg : extList) {
14972                 try {
14973                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14974                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14975                         retList.add(info);
14976                     }
14977                 } catch (RemoteException e) {
14978                 }
14979             }
14980         }
14981         return retList;
14982     }
14983
14984     @Override
14985     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14986         enforceNotIsolatedCaller("getMyMemoryState");
14987
14988         final int callingUid = Binder.getCallingUid();
14989         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14990
14991         synchronized (this) {
14992             ProcessRecord proc;
14993             synchronized (mPidsSelfLocked) {
14994                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14995             }
14996             fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14997         }
14998     }
14999
15000     @Override
15001     public int getMemoryTrimLevel() {
15002         enforceNotIsolatedCaller("getMyMemoryState");
15003         synchronized (this) {
15004             return mLastMemoryLevel;
15005         }
15006     }
15007
15008     @Override
15009     public void onShellCommand(FileDescriptor in, FileDescriptor out,
15010             FileDescriptor err, String[] args, ShellCallback callback,
15011             ResultReceiver resultReceiver) {
15012         (new ActivityManagerShellCommand(this, false)).exec(
15013                 this, in, out, err, args, callback, resultReceiver);
15014     }
15015
15016     SleepToken acquireSleepToken(String tag, int displayId) {
15017         synchronized (this) {
15018             final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15019             updateSleepIfNeededLocked();
15020             return token;
15021         }
15022     }
15023
15024     @Override
15025     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15026         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15027
15028         boolean dumpAll = false;
15029         boolean dumpClient = false;
15030         boolean dumpCheckin = false;
15031         boolean dumpCheckinFormat = false;
15032         boolean dumpVisibleStacksOnly = false;
15033         boolean dumpFocusedStackOnly = false;
15034         String dumpPackage = null;
15035
15036         int opti = 0;
15037         while (opti < args.length) {
15038             String opt = args[opti];
15039             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15040                 break;
15041             }
15042             opti++;
15043             if ("-a".equals(opt)) {
15044                 dumpAll = true;
15045             } else if ("-c".equals(opt)) {
15046                 dumpClient = true;
15047             } else if ("-v".equals(opt)) {
15048                 dumpVisibleStacksOnly = true;
15049             } else if ("-f".equals(opt)) {
15050                 dumpFocusedStackOnly = true;
15051             } else if ("-p".equals(opt)) {
15052                 if (opti < args.length) {
15053                     dumpPackage = args[opti];
15054                     opti++;
15055                 } else {
15056                     pw.println("Error: -p option requires package argument");
15057                     return;
15058                 }
15059                 dumpClient = true;
15060             } else if ("--checkin".equals(opt)) {
15061                 dumpCheckin = dumpCheckinFormat = true;
15062             } else if ("-C".equals(opt)) {
15063                 dumpCheckinFormat = true;
15064             } else if ("-h".equals(opt)) {
15065                 ActivityManagerShellCommand.dumpHelp(pw, true);
15066                 return;
15067             } else {
15068                 pw.println("Unknown argument: " + opt + "; use -h for help");
15069             }
15070         }
15071
15072         long origId = Binder.clearCallingIdentity();
15073         boolean more = false;
15074         // Is the caller requesting to dump a particular piece of data?
15075         if (opti < args.length) {
15076             String cmd = args[opti];
15077             opti++;
15078             if ("activities".equals(cmd) || "a".equals(cmd)) {
15079                 synchronized (this) {
15080                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15081                 }
15082             } else if ("lastanr".equals(cmd)) {
15083                 synchronized (this) {
15084                     dumpLastANRLocked(pw);
15085                 }
15086             } else if ("starter".equals(cmd)) {
15087                 synchronized (this) {
15088                     dumpActivityStarterLocked(pw, dumpPackage);
15089                 }
15090             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15091                 synchronized (this) {
15092                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15093                 }
15094             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15095                 String[] newArgs;
15096                 String name;
15097                 if (opti >= args.length) {
15098                     name = null;
15099                     newArgs = EMPTY_STRING_ARRAY;
15100                 } else {
15101                     dumpPackage = args[opti];
15102                     opti++;
15103                     newArgs = new String[args.length - opti];
15104                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15105                             args.length - opti);
15106                 }
15107                 synchronized (this) {
15108                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15109                 }
15110             } else if ("broadcast-stats".equals(cmd)) {
15111                 String[] newArgs;
15112                 String name;
15113                 if (opti >= args.length) {
15114                     name = null;
15115                     newArgs = EMPTY_STRING_ARRAY;
15116                 } else {
15117                     dumpPackage = args[opti];
15118                     opti++;
15119                     newArgs = new String[args.length - opti];
15120                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15121                             args.length - opti);
15122                 }
15123                 synchronized (this) {
15124                     if (dumpCheckinFormat) {
15125                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15126                                 dumpPackage);
15127                     } else {
15128                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15129                     }
15130                 }
15131             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15132                 String[] newArgs;
15133                 String name;
15134                 if (opti >= args.length) {
15135                     name = null;
15136                     newArgs = EMPTY_STRING_ARRAY;
15137                 } else {
15138                     dumpPackage = args[opti];
15139                     opti++;
15140                     newArgs = new String[args.length - opti];
15141                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15142                             args.length - opti);
15143                 }
15144                 synchronized (this) {
15145                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15146                 }
15147             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15148                 String[] newArgs;
15149                 String name;
15150                 if (opti >= args.length) {
15151                     name = null;
15152                     newArgs = EMPTY_STRING_ARRAY;
15153                 } else {
15154                     dumpPackage = args[opti];
15155                     opti++;
15156                     newArgs = new String[args.length - opti];
15157                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15158                             args.length - opti);
15159                 }
15160                 synchronized (this) {
15161                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15162                 }
15163             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15164                 synchronized (this) {
15165                     dumpOomLocked(fd, pw, args, opti, true);
15166                 }
15167             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15168                 synchronized (this) {
15169                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
15170                 }
15171             } else if ("provider".equals(cmd)) {
15172                 String[] newArgs;
15173                 String name;
15174                 if (opti >= args.length) {
15175                     name = null;
15176                     newArgs = EMPTY_STRING_ARRAY;
15177                 } else {
15178                     name = args[opti];
15179                     opti++;
15180                     newArgs = new String[args.length - opti];
15181                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15182                 }
15183                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15184                     pw.println("No providers match: " + name);
15185                     pw.println("Use -h for help.");
15186                 }
15187             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15188                 synchronized (this) {
15189                     dumpProvidersLocked(fd, pw, args, opti, true, null);
15190                 }
15191             } else if ("service".equals(cmd)) {
15192                 String[] newArgs;
15193                 String name;
15194                 if (opti >= args.length) {
15195                     name = null;
15196                     newArgs = EMPTY_STRING_ARRAY;
15197                 } else {
15198                     name = args[opti];
15199                     opti++;
15200                     newArgs = new String[args.length - opti];
15201                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15202                             args.length - opti);
15203                 }
15204                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15205                     pw.println("No services match: " + name);
15206                     pw.println("Use -h for help.");
15207                 }
15208             } else if ("package".equals(cmd)) {
15209                 String[] newArgs;
15210                 if (opti >= args.length) {
15211                     pw.println("package: no package name specified");
15212                     pw.println("Use -h for help.");
15213                 } else {
15214                     dumpPackage = args[opti];
15215                     opti++;
15216                     newArgs = new String[args.length - opti];
15217                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15218                             args.length - opti);
15219                     args = newArgs;
15220                     opti = 0;
15221                     more = true;
15222                 }
15223             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15224                 synchronized (this) {
15225                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15226                 }
15227             } else if ("settings".equals(cmd)) {
15228                 synchronized (this) {
15229                     mConstants.dump(pw);
15230                 }
15231             } else if ("services".equals(cmd) || "s".equals(cmd)) {
15232                 if (dumpClient) {
15233                     ActiveServices.ServiceDumper dumper;
15234                     synchronized (this) {
15235                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15236                                 dumpPackage);
15237                     }
15238                     dumper.dumpWithClient();
15239                 } else {
15240                     synchronized (this) {
15241                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15242                                 dumpPackage).dumpLocked();
15243                     }
15244                 }
15245             } else if ("locks".equals(cmd)) {
15246                 LockGuard.dump(fd, pw, args);
15247             } else {
15248                 // Dumping a single activity?
15249                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15250                         dumpFocusedStackOnly)) {
15251                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15252                     int res = shell.exec(this, null, fd, null, args, null,
15253                             new ResultReceiver(null));
15254                     if (res < 0) {
15255                         pw.println("Bad activity command, or no activities match: " + cmd);
15256                         pw.println("Use -h for help.");
15257                     }
15258                 }
15259             }
15260             if (!more) {
15261                 Binder.restoreCallingIdentity(origId);
15262                 return;
15263             }
15264         }
15265
15266         // No piece of data specified, dump everything.
15267         if (dumpCheckinFormat) {
15268             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15269         } else if (dumpClient) {
15270             ActiveServices.ServiceDumper sdumper;
15271             synchronized (this) {
15272                 mConstants.dump(pw);
15273                 pw.println();
15274                 if (dumpAll) {
15275                     pw.println("-------------------------------------------------------------------------------");
15276                 }
15277                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15278                 pw.println();
15279                 if (dumpAll) {
15280                     pw.println("-------------------------------------------------------------------------------");
15281                 }
15282                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15283                 pw.println();
15284                 if (dumpAll) {
15285                     pw.println("-------------------------------------------------------------------------------");
15286                 }
15287                 if (dumpAll || dumpPackage != null) {
15288                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15289                     pw.println();
15290                     if (dumpAll) {
15291                         pw.println("-------------------------------------------------------------------------------");
15292                     }
15293                 }
15294                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15295                 pw.println();
15296                 if (dumpAll) {
15297                     pw.println("-------------------------------------------------------------------------------");
15298                 }
15299                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15300                 pw.println();
15301                 if (dumpAll) {
15302                     pw.println("-------------------------------------------------------------------------------");
15303                 }
15304                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15305                         dumpPackage);
15306             }
15307             sdumper.dumpWithClient();
15308             pw.println();
15309             synchronized (this) {
15310                 if (dumpAll) {
15311                     pw.println("-------------------------------------------------------------------------------");
15312                 }
15313                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15314                 pw.println();
15315                 if (dumpAll) {
15316                     pw.println("-------------------------------------------------------------------------------");
15317                 }
15318                 dumpLastANRLocked(pw);
15319                 pw.println();
15320                 if (dumpAll) {
15321                     pw.println("-------------------------------------------------------------------------------");
15322                 }
15323                 dumpActivityStarterLocked(pw, dumpPackage);
15324                 pw.println();
15325                 if (dumpAll) {
15326                     pw.println("-------------------------------------------------------------------------------");
15327                 }
15328                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15329                 if (mAssociations.size() > 0) {
15330                     pw.println();
15331                     if (dumpAll) {
15332                         pw.println("-------------------------------------------------------------------------------");
15333                     }
15334                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15335                 }
15336                 pw.println();
15337                 if (dumpAll) {
15338                     pw.println("-------------------------------------------------------------------------------");
15339                 }
15340                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15341             }
15342
15343         } else {
15344             synchronized (this) {
15345                 mConstants.dump(pw);
15346                 pw.println();
15347                 if (dumpAll) {
15348                     pw.println("-------------------------------------------------------------------------------");
15349                 }
15350                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15351                 pw.println();
15352                 if (dumpAll) {
15353                     pw.println("-------------------------------------------------------------------------------");
15354                 }
15355                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15356                 pw.println();
15357                 if (dumpAll) {
15358                     pw.println("-------------------------------------------------------------------------------");
15359                 }
15360                 if (dumpAll || dumpPackage != null) {
15361                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15362                     pw.println();
15363                     if (dumpAll) {
15364                         pw.println("-------------------------------------------------------------------------------");
15365                     }
15366                 }
15367                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15368                 pw.println();
15369                 if (dumpAll) {
15370                     pw.println("-------------------------------------------------------------------------------");
15371                 }
15372                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15373                 pw.println();
15374                 if (dumpAll) {
15375                     pw.println("-------------------------------------------------------------------------------");
15376                 }
15377                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15378                         .dumpLocked();
15379                 pw.println();
15380                 if (dumpAll) {
15381                     pw.println("-------------------------------------------------------------------------------");
15382                 }
15383                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15384                 pw.println();
15385                 if (dumpAll) {
15386                     pw.println("-------------------------------------------------------------------------------");
15387                 }
15388                 dumpLastANRLocked(pw);
15389                 pw.println();
15390                 if (dumpAll) {
15391                     pw.println("-------------------------------------------------------------------------------");
15392                 }
15393                 dumpActivityStarterLocked(pw, dumpPackage);
15394                 pw.println();
15395                 if (dumpAll) {
15396                     pw.println("-------------------------------------------------------------------------------");
15397                 }
15398                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15399                 if (mAssociations.size() > 0) {
15400                     pw.println();
15401                     if (dumpAll) {
15402                         pw.println("-------------------------------------------------------------------------------");
15403                     }
15404                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15405                 }
15406                 pw.println();
15407                 if (dumpAll) {
15408                     pw.println("-------------------------------------------------------------------------------");
15409                 }
15410                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15411             }
15412         }
15413         Binder.restoreCallingIdentity(origId);
15414     }
15415
15416     private void dumpLastANRLocked(PrintWriter pw) {
15417         pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15418         if (mLastANRState == null) {
15419             pw.println("  <no ANR has occurred since boot>");
15420         } else {
15421             pw.println(mLastANRState);
15422         }
15423     }
15424
15425     private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15426         pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15427         mActivityStarter.dump(pw, "", dumpPackage);
15428     }
15429
15430     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15431             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15432         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15433                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15434     }
15435
15436     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15437             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15438         pw.println(header);
15439
15440         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15441                 dumpPackage);
15442         boolean needSep = printedAnything;
15443
15444         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15445                 mStackSupervisor.getResumedActivityLocked(),
15446                 dumpPackage, needSep, "  ResumedActivity: ");
15447         if (printed) {
15448             printedAnything = true;
15449             needSep = false;
15450         }
15451
15452         if (dumpPackage == null) {
15453             if (needSep) {
15454                 pw.println();
15455             }
15456             printedAnything = true;
15457             mStackSupervisor.dump(pw, "  ");
15458         }
15459
15460         if (!printedAnything) {
15461             pw.println("  (nothing)");
15462         }
15463     }
15464
15465     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15466             int opti, boolean dumpAll, String dumpPackage) {
15467         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15468
15469         boolean printedAnything = false;
15470
15471         if (mRecentTasks != null && mRecentTasks.size() > 0) {
15472             boolean printedHeader = false;
15473
15474             final int N = mRecentTasks.size();
15475             for (int i=0; i<N; i++) {
15476                 TaskRecord tr = mRecentTasks.get(i);
15477                 if (dumpPackage != null) {
15478                     if (tr.realActivity == null ||
15479                             !dumpPackage.equals(tr.realActivity.getPackageName())) {
15480                         continue;
15481                     }
15482                 }
15483                 if (!printedHeader) {
15484                     pw.println("  Recent tasks:");
15485                     printedHeader = true;
15486                     printedAnything = true;
15487                 }
15488                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15489                         pw.println(tr);
15490                 if (dumpAll) {
15491                     mRecentTasks.get(i).dump(pw, "    ");
15492                 }
15493             }
15494         }
15495
15496         if (!printedAnything) {
15497             pw.println("  (nothing)");
15498         }
15499     }
15500
15501     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15502             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15503         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15504
15505         int dumpUid = 0;
15506         if (dumpPackage != null) {
15507             IPackageManager pm = AppGlobals.getPackageManager();
15508             try {
15509                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15510             } catch (RemoteException e) {
15511             }
15512         }
15513
15514         boolean printedAnything = false;
15515
15516         final long now = SystemClock.uptimeMillis();
15517
15518         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15519             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15520                     = mAssociations.valueAt(i1);
15521             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15522                 SparseArray<ArrayMap<String, Association>> sourceUids
15523                         = targetComponents.valueAt(i2);
15524                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15525                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15526                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15527                         Association ass = sourceProcesses.valueAt(i4);
15528                         if (dumpPackage != null) {
15529                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15530                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15531                                 continue;
15532                             }
15533                         }
15534                         printedAnything = true;
15535                         pw.print("  ");
15536                         pw.print(ass.mTargetProcess);
15537                         pw.print("/");
15538                         UserHandle.formatUid(pw, ass.mTargetUid);
15539                         pw.print(" <- ");
15540                         pw.print(ass.mSourceProcess);
15541                         pw.print("/");
15542                         UserHandle.formatUid(pw, ass.mSourceUid);
15543                         pw.println();
15544                         pw.print("    via ");
15545                         pw.print(ass.mTargetComponent.flattenToShortString());
15546                         pw.println();
15547                         pw.print("    ");
15548                         long dur = ass.mTime;
15549                         if (ass.mNesting > 0) {
15550                             dur += now - ass.mStartTime;
15551                         }
15552                         TimeUtils.formatDuration(dur, pw);
15553                         pw.print(" (");
15554                         pw.print(ass.mCount);
15555                         pw.print(" times)");
15556                         pw.print("  ");
15557                         for (int i=0; i<ass.mStateTimes.length; i++) {
15558                             long amt = ass.mStateTimes[i];
15559                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15560                                 amt += now - ass.mLastStateUptime;
15561                             }
15562                             if (amt != 0) {
15563                                 pw.print(" ");
15564                                 pw.print(ProcessList.makeProcStateString(
15565                                             i + ActivityManager.MIN_PROCESS_STATE));
15566                                 pw.print("=");
15567                                 TimeUtils.formatDuration(amt, pw);
15568                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15569                                     pw.print("*");
15570                                 }
15571                             }
15572                         }
15573                         pw.println();
15574                         if (ass.mNesting > 0) {
15575                             pw.print("    Currently active: ");
15576                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
15577                             pw.println();
15578                         }
15579                     }
15580                 }
15581             }
15582
15583         }
15584
15585         if (!printedAnything) {
15586             pw.println("  (nothing)");
15587         }
15588     }
15589
15590     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15591             String header, boolean needSep) {
15592         boolean printed = false;
15593         int whichAppId = -1;
15594         if (dumpPackage != null) {
15595             try {
15596                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15597                         dumpPackage, 0);
15598                 whichAppId = UserHandle.getAppId(info.uid);
15599             } catch (NameNotFoundException e) {
15600                 e.printStackTrace();
15601             }
15602         }
15603         for (int i=0; i<uids.size(); i++) {
15604             UidRecord uidRec = uids.valueAt(i);
15605             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15606                 continue;
15607             }
15608             if (!printed) {
15609                 printed = true;
15610                 if (needSep) {
15611                     pw.println();
15612                 }
15613                 pw.print("  ");
15614                 pw.println(header);
15615                 needSep = true;
15616             }
15617             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15618             pw.print(": "); pw.println(uidRec);
15619         }
15620         return printed;
15621     }
15622
15623     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15624             int opti, boolean dumpAll, String dumpPackage) {
15625         boolean needSep = false;
15626         boolean printedAnything = false;
15627         int numPers = 0;
15628
15629         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15630
15631         if (dumpAll) {
15632             final int NP = mProcessNames.getMap().size();
15633             for (int ip=0; ip<NP; ip++) {
15634                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15635                 final int NA = procs.size();
15636                 for (int ia=0; ia<NA; ia++) {
15637                     ProcessRecord r = procs.valueAt(ia);
15638                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15639                         continue;
15640                     }
15641                     if (!needSep) {
15642                         pw.println("  All known processes:");
15643                         needSep = true;
15644                         printedAnything = true;
15645                     }
15646                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15647                         pw.print(" UID "); pw.print(procs.keyAt(ia));
15648                         pw.print(" "); pw.println(r);
15649                     r.dump(pw, "    ");
15650                     if (r.persistent) {
15651                         numPers++;
15652                     }
15653                 }
15654             }
15655         }
15656
15657         if (mIsolatedProcesses.size() > 0) {
15658             boolean printed = false;
15659             for (int i=0; i<mIsolatedProcesses.size(); i++) {
15660                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15661                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15662                     continue;
15663                 }
15664                 if (!printed) {
15665                     if (needSep) {
15666                         pw.println();
15667                     }
15668                     pw.println("  Isolated process list (sorted by uid):");
15669                     printedAnything = true;
15670                     printed = true;
15671                     needSep = true;
15672                 }
15673                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15674                 pw.println(r);
15675             }
15676         }
15677
15678         if (mActiveInstrumentation.size() > 0) {
15679             boolean printed = false;
15680             for (int i=0; i<mActiveInstrumentation.size(); i++) {
15681                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15682                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15683                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15684                     continue;
15685                 }
15686                 if (!printed) {
15687                     if (needSep) {
15688                         pw.println();
15689                     }
15690                     pw.println("  Active instrumentation:");
15691                     printedAnything = true;
15692                     printed = true;
15693                     needSep = true;
15694                 }
15695                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15696                 pw.println(ai);
15697                 ai.dump(pw, "      ");
15698             }
15699         }
15700
15701         if (mActiveUids.size() > 0) {
15702             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15703                 printedAnything = needSep = true;
15704             }
15705         }
15706         if (dumpAll) {
15707             if (mValidateUids.size() > 0) {
15708                 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15709                     printedAnything = needSep = true;
15710                 }
15711             }
15712         }
15713
15714         if (mLruProcesses.size() > 0) {
15715             if (needSep) {
15716                 pw.println();
15717             }
15718             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15719                     pw.print(" total, non-act at ");
15720                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15721                     pw.print(", non-svc at ");
15722                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15723                     pw.println("):");
15724             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15725             needSep = true;
15726             printedAnything = true;
15727         }
15728
15729         if (dumpAll || dumpPackage != null) {
15730             synchronized (mPidsSelfLocked) {
15731                 boolean printed = false;
15732                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15733                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
15734                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15735                         continue;
15736                     }
15737                     if (!printed) {
15738                         if (needSep) pw.println();
15739                         needSep = true;
15740                         pw.println("  PID mappings:");
15741                         printed = true;
15742                         printedAnything = true;
15743                     }
15744                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15745                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15746                 }
15747             }
15748         }
15749
15750         if (mImportantProcesses.size() > 0) {
15751             synchronized (mPidsSelfLocked) {
15752                 boolean printed = false;
15753                 for (int i = 0; i< mImportantProcesses.size(); i++) {
15754                     ProcessRecord r = mPidsSelfLocked.get(
15755                             mImportantProcesses.valueAt(i).pid);
15756                     if (dumpPackage != null && (r == null
15757                             || !r.pkgList.containsKey(dumpPackage))) {
15758                         continue;
15759                     }
15760                     if (!printed) {
15761                         if (needSep) pw.println();
15762                         needSep = true;
15763                         pw.println("  Foreground Processes:");
15764                         printed = true;
15765                         printedAnything = true;
15766                     }
15767                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15768                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15769                 }
15770             }
15771         }
15772
15773         if (mPersistentStartingProcesses.size() > 0) {
15774             if (needSep) pw.println();
15775             needSep = true;
15776             printedAnything = true;
15777             pw.println("  Persisent processes that are starting:");
15778             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15779                     "Starting Norm", "Restarting PERS", dumpPackage);
15780         }
15781
15782         if (mRemovedProcesses.size() > 0) {
15783             if (needSep) pw.println();
15784             needSep = true;
15785             printedAnything = true;
15786             pw.println("  Processes that are being removed:");
15787             dumpProcessList(pw, this, mRemovedProcesses, "    ",
15788                     "Removed Norm", "Removed PERS", dumpPackage);
15789         }
15790
15791         if (mProcessesOnHold.size() > 0) {
15792             if (needSep) pw.println();
15793             needSep = true;
15794             printedAnything = true;
15795             pw.println("  Processes that are on old until the system is ready:");
15796             dumpProcessList(pw, this, mProcessesOnHold, "    ",
15797                     "OnHold Norm", "OnHold PERS", dumpPackage);
15798         }
15799
15800         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15801
15802         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15803         if (needSep) {
15804             printedAnything = true;
15805         }
15806
15807         if (dumpPackage == null) {
15808             pw.println();
15809             needSep = false;
15810             mUserController.dump(pw, dumpAll);
15811         }
15812         if (mHomeProcess != null && (dumpPackage == null
15813                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15814             if (needSep) {
15815                 pw.println();
15816                 needSep = false;
15817             }
15818             pw.println("  mHomeProcess: " + mHomeProcess);
15819         }
15820         if (mPreviousProcess != null && (dumpPackage == null
15821                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15822             if (needSep) {
15823                 pw.println();
15824                 needSep = false;
15825             }
15826             pw.println("  mPreviousProcess: " + mPreviousProcess);
15827         }
15828         if (dumpAll) {
15829             StringBuilder sb = new StringBuilder(128);
15830             sb.append("  mPreviousProcessVisibleTime: ");
15831             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15832             pw.println(sb);
15833         }
15834         if (mHeavyWeightProcess != null && (dumpPackage == null
15835                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15836             if (needSep) {
15837                 pw.println();
15838                 needSep = false;
15839             }
15840             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15841         }
15842         if (dumpPackage == null) {
15843             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15844             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15845         }
15846         if (dumpAll) {
15847             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15848             if (mCompatModePackages.getPackages().size() > 0) {
15849                 boolean printed = false;
15850                 for (Map.Entry<String, Integer> entry
15851                         : mCompatModePackages.getPackages().entrySet()) {
15852                     String pkg = entry.getKey();
15853                     int mode = entry.getValue();
15854                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15855                         continue;
15856                     }
15857                     if (!printed) {
15858                         pw.println("  mScreenCompatPackages:");
15859                         printed = true;
15860                     }
15861                     pw.print("    "); pw.print(pkg); pw.print(": ");
15862                             pw.print(mode); pw.println();
15863                 }
15864             }
15865             final int NI = mUidObservers.getRegisteredCallbackCount();
15866             boolean printed = false;
15867             for (int i=0; i<NI; i++) {
15868                 final UidObserverRegistration reg = (UidObserverRegistration)
15869                         mUidObservers.getRegisteredCallbackCookie(i);
15870                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15871                     if (!printed) {
15872                         pw.println("  mUidObservers:");
15873                         printed = true;
15874                     }
15875                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15876                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
15877                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15878                         pw.print(" IDLE");
15879                     }
15880                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15881                         pw.print(" ACT" );
15882                     }
15883                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15884                         pw.print(" GONE");
15885                     }
15886                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15887                         pw.print(" STATE");
15888                         pw.print(" (cut="); pw.print(reg.cutpoint);
15889                         pw.print(")");
15890                     }
15891                     pw.println();
15892                     if (reg.lastProcStates != null) {
15893                         final int NJ = reg.lastProcStates.size();
15894                         for (int j=0; j<NJ; j++) {
15895                             pw.print("      Last ");
15896                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15897                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15898                         }
15899                     }
15900                 }
15901             }
15902             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15903             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15904             if (mPendingTempWhitelist.size() > 0) {
15905                 pw.println("  mPendingTempWhitelist:");
15906                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15907                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15908                     pw.print("    ");
15909                     UserHandle.formatUid(pw, ptw.targetUid);
15910                     pw.print(": ");
15911                     TimeUtils.formatDuration(ptw.duration, pw);
15912                     pw.print(" ");
15913                     pw.println(ptw.tag);
15914                 }
15915             }
15916         }
15917         if (dumpPackage == null) {
15918             pw.println("  mWakefulness="
15919                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
15920             pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
15921             pw.println("  mSleeping=" + mSleeping);
15922             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15923             if (mRunningVoice != null) {
15924                 pw.println("  mRunningVoice=" + mRunningVoice);
15925                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15926             }
15927         }
15928         pw.println("  mVrController=" + mVrController);
15929         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15930                 || mOrigWaitForDebugger) {
15931             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15932                     || dumpPackage.equals(mOrigDebugApp)) {
15933                 if (needSep) {
15934                     pw.println();
15935                     needSep = false;
15936                 }
15937                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15938                         + " mDebugTransient=" + mDebugTransient
15939                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15940             }
15941         }
15942         if (mCurAppTimeTracker != null) {
15943             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15944         }
15945         if (mMemWatchProcesses.getMap().size() > 0) {
15946             pw.println("  Mem watch processes:");
15947             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15948                     = mMemWatchProcesses.getMap();
15949             for (int i=0; i<procs.size(); i++) {
15950                 final String proc = procs.keyAt(i);
15951                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15952                 for (int j=0; j<uids.size(); j++) {
15953                     if (needSep) {
15954                         pw.println();
15955                         needSep = false;
15956                     }
15957                     StringBuilder sb = new StringBuilder();
15958                     sb.append("    ").append(proc).append('/');
15959                     UserHandle.formatUid(sb, uids.keyAt(j));
15960                     Pair<Long, String> val = uids.valueAt(j);
15961                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15962                     if (val.second != null) {
15963                         sb.append(", report to ").append(val.second);
15964                     }
15965                     pw.println(sb.toString());
15966                 }
15967             }
15968             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15969             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15970             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15971                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15972         }
15973         if (mTrackAllocationApp != null) {
15974             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15975                 if (needSep) {
15976                     pw.println();
15977                     needSep = false;
15978                 }
15979                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15980             }
15981         }
15982         if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15983                 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15984             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15985                 if (needSep) {
15986                     pw.println();
15987                     needSep = false;
15988                 }
15989                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15990                 if (mProfilerInfo != null) {
15991                     pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
15992                             mProfilerInfo.profileFd);
15993                     pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
15994                             " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
15995                             " mStreamingOutput=" + mProfilerInfo.streamingOutput);
15996                     pw.println("  mProfileType=" + mProfileType);
15997                 }
15998             }
15999         }
16000         if (mNativeDebuggingApp != null) {
16001             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16002                 if (needSep) {
16003                     pw.println();
16004                     needSep = false;
16005                 }
16006                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16007             }
16008         }
16009         if (dumpPackage == null) {
16010             if (mAlwaysFinishActivities) {
16011                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16012             }
16013             if (mController != null) {
16014                 pw.println("  mController=" + mController
16015                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16016             }
16017             if (dumpAll) {
16018                 pw.println("  Total persistent processes: " + numPers);
16019                 pw.println("  mProcessesReady=" + mProcessesReady
16020                         + " mSystemReady=" + mSystemReady
16021                         + " mBooted=" + mBooted
16022                         + " mFactoryTest=" + mFactoryTest);
16023                 pw.println("  mBooting=" + mBooting
16024                         + " mCallFinishBooting=" + mCallFinishBooting
16025                         + " mBootAnimationComplete=" + mBootAnimationComplete);
16026                 pw.print("  mLastPowerCheckUptime=");
16027                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16028                         pw.println("");
16029                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16030                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16031                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16032                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16033                         + " (" + mLruProcesses.size() + " total)"
16034                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16035                         + " mNumServiceProcs=" + mNumServiceProcs
16036                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16037                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16038                         + " mLastMemoryLevel=" + mLastMemoryLevel
16039                         + " mLastNumProcesses=" + mLastNumProcesses);
16040                 long now = SystemClock.uptimeMillis();
16041                 pw.print("  mLastIdleTime=");
16042                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
16043                         pw.print(" mLowRamSinceLastIdle=");
16044                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16045                         pw.println();
16046             }
16047         }
16048
16049         if (!printedAnything) {
16050             pw.println("  (nothing)");
16051         }
16052     }
16053
16054     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16055             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16056         if (mProcessesToGc.size() > 0) {
16057             boolean printed = false;
16058             long now = SystemClock.uptimeMillis();
16059             for (int i=0; i<mProcessesToGc.size(); i++) {
16060                 ProcessRecord proc = mProcessesToGc.get(i);
16061                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16062                     continue;
16063                 }
16064                 if (!printed) {
16065                     if (needSep) pw.println();
16066                     needSep = true;
16067                     pw.println("  Processes that are waiting to GC:");
16068                     printed = true;
16069                 }
16070                 pw.print("    Process "); pw.println(proc);
16071                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16072                         pw.print(", last gced=");
16073                         pw.print(now-proc.lastRequestedGc);
16074                         pw.print(" ms ago, last lowMem=");
16075                         pw.print(now-proc.lastLowMemory);
16076                         pw.println(" ms ago");
16077
16078             }
16079         }
16080         return needSep;
16081     }
16082
16083     void printOomLevel(PrintWriter pw, String name, int adj) {
16084         pw.print("    ");
16085         if (adj >= 0) {
16086             pw.print(' ');
16087             if (adj < 10) pw.print(' ');
16088         } else {
16089             if (adj > -10) pw.print(' ');
16090         }
16091         pw.print(adj);
16092         pw.print(": ");
16093         pw.print(name);
16094         pw.print(" (");
16095         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16096         pw.println(")");
16097     }
16098
16099     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16100             int opti, boolean dumpAll) {
16101         boolean needSep = false;
16102
16103         if (mLruProcesses.size() > 0) {
16104             if (needSep) pw.println();
16105             needSep = true;
16106             pw.println("  OOM levels:");
16107             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16108             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16109             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16110             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16111             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16112             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16113             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16114             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16115             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16116             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16117             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16118             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16119             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16120             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16121
16122             if (needSep) pw.println();
16123             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16124                     pw.print(" total, non-act at ");
16125                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16126                     pw.print(", non-svc at ");
16127                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16128                     pw.println("):");
16129             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16130             needSep = true;
16131         }
16132
16133         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16134
16135         pw.println();
16136         pw.println("  mHomeProcess: " + mHomeProcess);
16137         pw.println("  mPreviousProcess: " + mPreviousProcess);
16138         if (mHeavyWeightProcess != null) {
16139             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16140         }
16141
16142         return true;
16143     }
16144
16145     /**
16146      * There are three ways to call this:
16147      *  - no provider specified: dump all the providers
16148      *  - a flattened component name that matched an existing provider was specified as the
16149      *    first arg: dump that one provider
16150      *  - the first arg isn't the flattened component name of an existing provider:
16151      *    dump all providers whose component contains the first arg as a substring
16152      */
16153     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16154             int opti, boolean dumpAll) {
16155         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16156     }
16157
16158     static class ItemMatcher {
16159         ArrayList<ComponentName> components;
16160         ArrayList<String> strings;
16161         ArrayList<Integer> objects;
16162         boolean all;
16163
16164         ItemMatcher() {
16165             all = true;
16166         }
16167
16168         void build(String name) {
16169             ComponentName componentName = ComponentName.unflattenFromString(name);
16170             if (componentName != null) {
16171                 if (components == null) {
16172                     components = new ArrayList<ComponentName>();
16173                 }
16174                 components.add(componentName);
16175                 all = false;
16176             } else {
16177                 int objectId = 0;
16178                 // Not a '/' separated full component name; maybe an object ID?
16179                 try {
16180                     objectId = Integer.parseInt(name, 16);
16181                     if (objects == null) {
16182                         objects = new ArrayList<Integer>();
16183                     }
16184                     objects.add(objectId);
16185                     all = false;
16186                 } catch (RuntimeException e) {
16187                     // Not an integer; just do string match.
16188                     if (strings == null) {
16189                         strings = new ArrayList<String>();
16190                     }
16191                     strings.add(name);
16192                     all = false;
16193                 }
16194             }
16195         }
16196
16197         int build(String[] args, int opti) {
16198             for (; opti<args.length; opti++) {
16199                 String name = args[opti];
16200                 if ("--".equals(name)) {
16201                     return opti+1;
16202                 }
16203                 build(name);
16204             }
16205             return opti;
16206         }
16207
16208         boolean match(Object object, ComponentName comp) {
16209             if (all) {
16210                 return true;
16211             }
16212             if (components != null) {
16213                 for (int i=0; i<components.size(); i++) {
16214                     if (components.get(i).equals(comp)) {
16215                         return true;
16216                     }
16217                 }
16218             }
16219             if (objects != null) {
16220                 for (int i=0; i<objects.size(); i++) {
16221                     if (System.identityHashCode(object) == objects.get(i)) {
16222                         return true;
16223                     }
16224                 }
16225             }
16226             if (strings != null) {
16227                 String flat = comp.flattenToString();
16228                 for (int i=0; i<strings.size(); i++) {
16229                     if (flat.contains(strings.get(i))) {
16230                         return true;
16231                     }
16232                 }
16233             }
16234             return false;
16235         }
16236     }
16237
16238     /**
16239      * There are three things that cmd can be:
16240      *  - a flattened component name that matches an existing activity
16241      *  - the cmd arg isn't the flattened component name of an existing activity:
16242      *    dump all activity whose component contains the cmd as a substring
16243      *  - A hex number of the ActivityRecord object instance.
16244      *
16245      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16246      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16247      */
16248     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16249             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16250         ArrayList<ActivityRecord> activities;
16251
16252         synchronized (this) {
16253             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16254                     dumpFocusedStackOnly);
16255         }
16256
16257         if (activities.size() <= 0) {
16258             return false;
16259         }
16260
16261         String[] newArgs = new String[args.length - opti];
16262         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16263
16264         TaskRecord lastTask = null;
16265         boolean needSep = false;
16266         for (int i=activities.size()-1; i>=0; i--) {
16267             ActivityRecord r = activities.get(i);
16268             if (needSep) {
16269                 pw.println();
16270             }
16271             needSep = true;
16272             synchronized (this) {
16273                 final TaskRecord task = r.getTask();
16274                 if (lastTask != task) {
16275                     lastTask = task;
16276                     pw.print("TASK "); pw.print(lastTask.affinity);
16277                             pw.print(" id="); pw.print(lastTask.taskId);
16278                             pw.print(" userId="); pw.println(lastTask.userId);
16279                     if (dumpAll) {
16280                         lastTask.dump(pw, "  ");
16281                     }
16282                 }
16283             }
16284             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16285         }
16286         return true;
16287     }
16288
16289     /**
16290      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16291      * there is a thread associated with the activity.
16292      */
16293     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16294             final ActivityRecord r, String[] args, boolean dumpAll) {
16295         String innerPrefix = prefix + "  ";
16296         synchronized (this) {
16297             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16298                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16299                     pw.print(" pid=");
16300                     if (r.app != null) pw.println(r.app.pid);
16301                     else pw.println("(not running)");
16302             if (dumpAll) {
16303                 r.dump(pw, innerPrefix);
16304             }
16305         }
16306         if (r.app != null && r.app.thread != null) {
16307             // flush anything that is already in the PrintWriter since the thread is going
16308             // to write to the file descriptor directly
16309             pw.flush();
16310             try {
16311                 TransferPipe tp = new TransferPipe();
16312                 try {
16313                     r.app.thread.dumpActivity(tp.getWriteFd(),
16314                             r.appToken, innerPrefix, args);
16315                     tp.go(fd);
16316                 } finally {
16317                     tp.kill();
16318                 }
16319             } catch (IOException e) {
16320                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16321             } catch (RemoteException e) {
16322                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16323             }
16324         }
16325     }
16326
16327     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16328             int opti, boolean dumpAll, String dumpPackage) {
16329         boolean needSep = false;
16330         boolean onlyHistory = false;
16331         boolean printedAnything = false;
16332
16333         if ("history".equals(dumpPackage)) {
16334             if (opti < args.length && "-s".equals(args[opti])) {
16335                 dumpAll = false;
16336             }
16337             onlyHistory = true;
16338             dumpPackage = null;
16339         }
16340
16341         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16342         if (!onlyHistory && dumpAll) {
16343             if (mRegisteredReceivers.size() > 0) {
16344                 boolean printed = false;
16345                 Iterator it = mRegisteredReceivers.values().iterator();
16346                 while (it.hasNext()) {
16347                     ReceiverList r = (ReceiverList)it.next();
16348                     if (dumpPackage != null && (r.app == null ||
16349                             !dumpPackage.equals(r.app.info.packageName))) {
16350                         continue;
16351                     }
16352                     if (!printed) {
16353                         pw.println("  Registered Receivers:");
16354                         needSep = true;
16355                         printed = true;
16356                         printedAnything = true;
16357                     }
16358                     pw.print("  * "); pw.println(r);
16359                     r.dump(pw, "    ");
16360                 }
16361             }
16362
16363             if (mReceiverResolver.dump(pw, needSep ?
16364                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16365                     "    ", dumpPackage, false, false)) {
16366                 needSep = true;
16367                 printedAnything = true;
16368             }
16369         }
16370
16371         for (BroadcastQueue q : mBroadcastQueues) {
16372             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16373             printedAnything |= needSep;
16374         }
16375
16376         needSep = true;
16377
16378         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16379             for (int user=0; user<mStickyBroadcasts.size(); user++) {
16380                 if (needSep) {
16381                     pw.println();
16382                 }
16383                 needSep = true;
16384                 printedAnything = true;
16385                 pw.print("  Sticky broadcasts for user ");
16386                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16387                 StringBuilder sb = new StringBuilder(128);
16388                 for (Map.Entry<String, ArrayList<Intent>> ent
16389                         : mStickyBroadcasts.valueAt(user).entrySet()) {
16390                     pw.print("  * Sticky action "); pw.print(ent.getKey());
16391                     if (dumpAll) {
16392                         pw.println(":");
16393                         ArrayList<Intent> intents = ent.getValue();
16394                         final int N = intents.size();
16395                         for (int i=0; i<N; i++) {
16396                             sb.setLength(0);
16397                             sb.append("    Intent: ");
16398                             intents.get(i).toShortString(sb, false, true, false, false);
16399                             pw.println(sb.toString());
16400                             Bundle bundle = intents.get(i).getExtras();
16401                             if (bundle != null) {
16402                                 pw.print("      ");
16403                                 pw.println(bundle.toString());
16404                             }
16405                         }
16406                     } else {
16407                         pw.println("");
16408                     }
16409                 }
16410             }
16411         }
16412
16413         if (!onlyHistory && dumpAll) {
16414             pw.println();
16415             for (BroadcastQueue queue : mBroadcastQueues) {
16416                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16417                         + queue.mBroadcastsScheduled);
16418             }
16419             pw.println("  mHandler:");
16420             mHandler.dump(new PrintWriterPrinter(pw), "    ");
16421             needSep = true;
16422             printedAnything = true;
16423         }
16424
16425         if (!printedAnything) {
16426             pw.println("  (nothing)");
16427         }
16428     }
16429
16430     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16431             int opti, boolean dumpAll, String dumpPackage) {
16432         if (mCurBroadcastStats == null) {
16433             return;
16434         }
16435
16436         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16437         final long now = SystemClock.elapsedRealtime();
16438         if (mLastBroadcastStats != null) {
16439             pw.print("  Last stats (from ");
16440             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16441             pw.print(" to ");
16442             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16443             pw.print(", ");
16444             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16445                     - mLastBroadcastStats.mStartUptime, pw);
16446             pw.println(" uptime):");
16447             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16448                 pw.println("    (nothing)");
16449             }
16450             pw.println();
16451         }
16452         pw.print("  Current stats (from ");
16453         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16454         pw.print(" to now, ");
16455         TimeUtils.formatDuration(SystemClock.uptimeMillis()
16456                 - mCurBroadcastStats.mStartUptime, pw);
16457         pw.println(" uptime):");
16458         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16459             pw.println("    (nothing)");
16460         }
16461     }
16462
16463     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16464             int opti, boolean fullCheckin, String dumpPackage) {
16465         if (mCurBroadcastStats == null) {
16466             return;
16467         }
16468
16469         if (mLastBroadcastStats != null) {
16470             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16471             if (fullCheckin) {
16472                 mLastBroadcastStats = null;
16473                 return;
16474             }
16475         }
16476         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16477         if (fullCheckin) {
16478             mCurBroadcastStats = null;
16479         }
16480     }
16481
16482     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16483             int opti, boolean dumpAll, String dumpPackage) {
16484         boolean needSep;
16485         boolean printedAnything = false;
16486
16487         ItemMatcher matcher = new ItemMatcher();
16488         matcher.build(args, opti);
16489
16490         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16491
16492         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16493         printedAnything |= needSep;
16494
16495         if (mLaunchingProviders.size() > 0) {
16496             boolean printed = false;
16497             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16498                 ContentProviderRecord r = mLaunchingProviders.get(i);
16499                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16500                     continue;
16501                 }
16502                 if (!printed) {
16503                     if (needSep) pw.println();
16504                     needSep = true;
16505                     pw.println("  Launching content providers:");
16506                     printed = true;
16507                     printedAnything = true;
16508                 }
16509                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
16510                         pw.println(r);
16511             }
16512         }
16513
16514         if (!printedAnything) {
16515             pw.println("  (nothing)");
16516         }
16517     }
16518
16519     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16520             int opti, boolean dumpAll, String dumpPackage) {
16521         boolean needSep = false;
16522         boolean printedAnything = false;
16523
16524         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16525
16526         if (mGrantedUriPermissions.size() > 0) {
16527             boolean printed = false;
16528             int dumpUid = -2;
16529             if (dumpPackage != null) {
16530                 try {
16531                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16532                             MATCH_ANY_USER, 0);
16533                 } catch (NameNotFoundException e) {
16534                     dumpUid = -1;
16535                 }
16536             }
16537             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16538                 int uid = mGrantedUriPermissions.keyAt(i);
16539                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16540                     continue;
16541                 }
16542                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16543                 if (!printed) {
16544                     if (needSep) pw.println();
16545                     needSep = true;
16546                     pw.println("  Granted Uri Permissions:");
16547                     printed = true;
16548                     printedAnything = true;
16549                 }
16550                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16551                 for (UriPermission perm : perms.values()) {
16552                     pw.print("    "); pw.println(perm);
16553                     if (dumpAll) {
16554                         perm.dump(pw, "      ");
16555                     }
16556                 }
16557             }
16558         }
16559
16560         if (!printedAnything) {
16561             pw.println("  (nothing)");
16562         }
16563     }
16564
16565     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16566             int opti, boolean dumpAll, String dumpPackage) {
16567         boolean printed = false;
16568
16569         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16570
16571         if (mIntentSenderRecords.size() > 0) {
16572             // Organize these by package name, so they are easier to read.
16573             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16574             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16575             final Iterator<WeakReference<PendingIntentRecord>> it
16576                     = mIntentSenderRecords.values().iterator();
16577             while (it.hasNext()) {
16578                 WeakReference<PendingIntentRecord> ref = it.next();
16579                 PendingIntentRecord rec = ref != null ? ref.get() : null;
16580                 if (rec == null) {
16581                     weakRefs.add(ref);
16582                     continue;
16583                 }
16584                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16585                     continue;
16586                 }
16587                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16588                 if (list == null) {
16589                     list = new ArrayList<>();
16590                     byPackage.put(rec.key.packageName, list);
16591                 }
16592                 list.add(rec);
16593             }
16594             for (int i = 0; i < byPackage.size(); i++) {
16595                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16596                 printed = true;
16597                 pw.print("  * "); pw.print(byPackage.keyAt(i));
16598                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16599                 for (int j = 0; j < intents.size(); j++) {
16600                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16601                     if (dumpAll) {
16602                         intents.get(j).dump(pw, "      ");
16603                     }
16604                 }
16605             }
16606             if (weakRefs.size() > 0) {
16607                 printed = true;
16608                 pw.println("  * WEAK REFS:");
16609                 for (int i = 0; i < weakRefs.size(); i++) {
16610                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16611                 }
16612             }
16613         }
16614
16615         if (!printed) {
16616             pw.println("  (nothing)");
16617         }
16618     }
16619
16620     private static final int dumpProcessList(PrintWriter pw,
16621             ActivityManagerService service, List list,
16622             String prefix, String normalLabel, String persistentLabel,
16623             String dumpPackage) {
16624         int numPers = 0;
16625         final int N = list.size()-1;
16626         for (int i=N; i>=0; i--) {
16627             ProcessRecord r = (ProcessRecord)list.get(i);
16628             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16629                 continue;
16630             }
16631             pw.println(String.format("%s%s #%2d: %s",
16632                     prefix, (r.persistent ? persistentLabel : normalLabel),
16633                     i, r.toString()));
16634             if (r.persistent) {
16635                 numPers++;
16636             }
16637         }
16638         return numPers;
16639     }
16640
16641     private static final boolean dumpProcessOomList(PrintWriter pw,
16642             ActivityManagerService service, List<ProcessRecord> origList,
16643             String prefix, String normalLabel, String persistentLabel,
16644             boolean inclDetails, String dumpPackage) {
16645
16646         ArrayList<Pair<ProcessRecord, Integer>> list
16647                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16648         for (int i=0; i<origList.size(); i++) {
16649             ProcessRecord r = origList.get(i);
16650             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16651                 continue;
16652             }
16653             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16654         }
16655
16656         if (list.size() <= 0) {
16657             return false;
16658         }
16659
16660         Comparator<Pair<ProcessRecord, Integer>> comparator
16661                 = new Comparator<Pair<ProcessRecord, Integer>>() {
16662             @Override
16663             public int compare(Pair<ProcessRecord, Integer> object1,
16664                     Pair<ProcessRecord, Integer> object2) {
16665                 if (object1.first.setAdj != object2.first.setAdj) {
16666                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16667                 }
16668                 if (object1.first.setProcState != object2.first.setProcState) {
16669                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16670                 }
16671                 if (object1.second.intValue() != object2.second.intValue()) {
16672                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16673                 }
16674                 return 0;
16675             }
16676         };
16677
16678         Collections.sort(list, comparator);
16679
16680         final long curUptime = SystemClock.uptimeMillis();
16681         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16682
16683         for (int i=list.size()-1; i>=0; i--) {
16684             ProcessRecord r = list.get(i).first;
16685             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16686             char schedGroup;
16687             switch (r.setSchedGroup) {
16688                 case ProcessList.SCHED_GROUP_BACKGROUND:
16689                     schedGroup = 'B';
16690                     break;
16691                 case ProcessList.SCHED_GROUP_DEFAULT:
16692                     schedGroup = 'F';
16693                     break;
16694                 case ProcessList.SCHED_GROUP_TOP_APP:
16695                     schedGroup = 'T';
16696                     break;
16697                 default:
16698                     schedGroup = '?';
16699                     break;
16700             }
16701             char foreground;
16702             if (r.foregroundActivities) {
16703                 foreground = 'A';
16704             } else if (r.foregroundServices) {
16705                 foreground = 'S';
16706             } else {
16707                 foreground = ' ';
16708             }
16709             String procState = ProcessList.makeProcStateString(r.curProcState);
16710             pw.print(prefix);
16711             pw.print(r.persistent ? persistentLabel : normalLabel);
16712             pw.print(" #");
16713             int num = (origList.size()-1)-list.get(i).second;
16714             if (num < 10) pw.print(' ');
16715             pw.print(num);
16716             pw.print(": ");
16717             pw.print(oomAdj);
16718             pw.print(' ');
16719             pw.print(schedGroup);
16720             pw.print('/');
16721             pw.print(foreground);
16722             pw.print('/');
16723             pw.print(procState);
16724             pw.print(" trm:");
16725             if (r.trimMemoryLevel < 10) pw.print(' ');
16726             pw.print(r.trimMemoryLevel);
16727             pw.print(' ');
16728             pw.print(r.toShortString());
16729             pw.print(" (");
16730             pw.print(r.adjType);
16731             pw.println(')');
16732             if (r.adjSource != null || r.adjTarget != null) {
16733                 pw.print(prefix);
16734                 pw.print("    ");
16735                 if (r.adjTarget instanceof ComponentName) {
16736                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16737                 } else if (r.adjTarget != null) {
16738                     pw.print(r.adjTarget.toString());
16739                 } else {
16740                     pw.print("{null}");
16741                 }
16742                 pw.print("<=");
16743                 if (r.adjSource instanceof ProcessRecord) {
16744                     pw.print("Proc{");
16745                     pw.print(((ProcessRecord)r.adjSource).toShortString());
16746                     pw.println("}");
16747                 } else if (r.adjSource != null) {
16748                     pw.println(r.adjSource.toString());
16749                 } else {
16750                     pw.println("{null}");
16751                 }
16752             }
16753             if (inclDetails) {
16754                 pw.print(prefix);
16755                 pw.print("    ");
16756                 pw.print("oom: max="); pw.print(r.maxAdj);
16757                 pw.print(" curRaw="); pw.print(r.curRawAdj);
16758                 pw.print(" setRaw="); pw.print(r.setRawAdj);
16759                 pw.print(" cur="); pw.print(r.curAdj);
16760                 pw.print(" set="); pw.println(r.setAdj);
16761                 pw.print(prefix);
16762                 pw.print("    ");
16763                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16764                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16765                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16766                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16767                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16768                 pw.println();
16769                 pw.print(prefix);
16770                 pw.print("    ");
16771                 pw.print("cached="); pw.print(r.cached);
16772                 pw.print(" empty="); pw.print(r.empty);
16773                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16774
16775                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16776                     if (r.lastCpuTime != 0) {
16777                         long timeUsed = r.curCpuTime - r.lastCpuTime;
16778                         pw.print(prefix);
16779                         pw.print("    ");
16780                         pw.print("run cpu over ");
16781                         TimeUtils.formatDuration(uptimeSince, pw);
16782                         pw.print(" used ");
16783                         TimeUtils.formatDuration(timeUsed, pw);
16784                         pw.print(" (");
16785                         pw.print((timeUsed*100)/uptimeSince);
16786                         pw.println("%)");
16787                     }
16788                 }
16789             }
16790         }
16791         return true;
16792     }
16793
16794     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16795             String[] args) {
16796         ArrayList<ProcessRecord> procs;
16797         synchronized (this) {
16798             if (args != null && args.length > start
16799                     && args[start].charAt(0) != '-') {
16800                 procs = new ArrayList<ProcessRecord>();
16801                 int pid = -1;
16802                 try {
16803                     pid = Integer.parseInt(args[start]);
16804                 } catch (NumberFormatException e) {
16805                 }
16806                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16807                     ProcessRecord proc = mLruProcesses.get(i);
16808                     if (proc.pid == pid) {
16809                         procs.add(proc);
16810                     } else if (allPkgs && proc.pkgList != null
16811                             && proc.pkgList.containsKey(args[start])) {
16812                         procs.add(proc);
16813                     } else if (proc.processName.equals(args[start])) {
16814                         procs.add(proc);
16815                     }
16816                 }
16817                 if (procs.size() <= 0) {
16818                     return null;
16819                 }
16820             } else {
16821                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16822             }
16823         }
16824         return procs;
16825     }
16826
16827     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16828             PrintWriter pw, String[] args) {
16829         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16830         if (procs == null) {
16831             pw.println("No process found for: " + args[0]);
16832             return;
16833         }
16834
16835         long uptime = SystemClock.uptimeMillis();
16836         long realtime = SystemClock.elapsedRealtime();
16837         pw.println("Applications Graphics Acceleration Info:");
16838         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16839
16840         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16841             ProcessRecord r = procs.get(i);
16842             if (r.thread != null) {
16843                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16844                 pw.flush();
16845                 try {
16846                     TransferPipe tp = new TransferPipe();
16847                     try {
16848                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16849                         tp.go(fd);
16850                     } finally {
16851                         tp.kill();
16852                     }
16853                 } catch (IOException e) {
16854                     pw.println("Failure while dumping the app: " + r);
16855                     pw.flush();
16856                 } catch (RemoteException e) {
16857                     pw.println("Got a RemoteException while dumping the app " + r);
16858                     pw.flush();
16859                 }
16860             }
16861         }
16862     }
16863
16864     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16865         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16866         if (procs == null) {
16867             pw.println("No process found for: " + args[0]);
16868             return;
16869         }
16870
16871         pw.println("Applications Database Info:");
16872
16873         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16874             ProcessRecord r = procs.get(i);
16875             if (r.thread != null) {
16876                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16877                 pw.flush();
16878                 try {
16879                     TransferPipe tp = new TransferPipe();
16880                     try {
16881                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
16882                         tp.go(fd);
16883                     } finally {
16884                         tp.kill();
16885                     }
16886                 } catch (IOException e) {
16887                     pw.println("Failure while dumping the app: " + r);
16888                     pw.flush();
16889                 } catch (RemoteException e) {
16890                     pw.println("Got a RemoteException while dumping the app " + r);
16891                     pw.flush();
16892                 }
16893             }
16894         }
16895     }
16896
16897     final static class MemItem {
16898         final boolean isProc;
16899         final String label;
16900         final String shortLabel;
16901         final long pss;
16902         final long swapPss;
16903         final int id;
16904         final boolean hasActivities;
16905         ArrayList<MemItem> subitems;
16906
16907         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16908                 boolean _hasActivities) {
16909             isProc = true;
16910             label = _label;
16911             shortLabel = _shortLabel;
16912             pss = _pss;
16913             swapPss = _swapPss;
16914             id = _id;
16915             hasActivities = _hasActivities;
16916         }
16917
16918         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16919             isProc = false;
16920             label = _label;
16921             shortLabel = _shortLabel;
16922             pss = _pss;
16923             swapPss = _swapPss;
16924             id = _id;
16925             hasActivities = false;
16926         }
16927     }
16928
16929     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16930             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16931         if (sort && !isCompact) {
16932             Collections.sort(items, new Comparator<MemItem>() {
16933                 @Override
16934                 public int compare(MemItem lhs, MemItem rhs) {
16935                     if (lhs.pss < rhs.pss) {
16936                         return 1;
16937                     } else if (lhs.pss > rhs.pss) {
16938                         return -1;
16939                     }
16940                     return 0;
16941                 }
16942             });
16943         }
16944
16945         for (int i=0; i<items.size(); i++) {
16946             MemItem mi = items.get(i);
16947             if (!isCompact) {
16948                 if (dumpSwapPss) {
16949                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16950                             mi.label, stringifyKBSize(mi.swapPss));
16951                 } else {
16952                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16953                 }
16954             } else if (mi.isProc) {
16955                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16956                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16957                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16958                 pw.println(mi.hasActivities ? ",a" : ",e");
16959             } else {
16960                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16961                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16962             }
16963             if (mi.subitems != null) {
16964                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16965                         true, isCompact, dumpSwapPss);
16966             }
16967         }
16968     }
16969
16970     // These are in KB.
16971     static final long[] DUMP_MEM_BUCKETS = new long[] {
16972         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16973         120*1024, 160*1024, 200*1024,
16974         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16975         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16976     };
16977
16978     static final void appendMemBucket(StringBuilder out, long memKB, String label,
16979             boolean stackLike) {
16980         int start = label.lastIndexOf('.');
16981         if (start >= 0) start++;
16982         else start = 0;
16983         int end = label.length();
16984         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16985             if (DUMP_MEM_BUCKETS[i] >= memKB) {
16986                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16987                 out.append(bucket);
16988                 out.append(stackLike ? "MB." : "MB ");
16989                 out.append(label, start, end);
16990                 return;
16991             }
16992         }
16993         out.append(memKB/1024);
16994         out.append(stackLike ? "MB." : "MB ");
16995         out.append(label, start, end);
16996     }
16997
16998     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16999             ProcessList.NATIVE_ADJ,
17000             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17001             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17002             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17003             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17004             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17005             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17006     };
17007     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17008             "Native",
17009             "System", "Persistent", "Persistent Service", "Foreground",
17010             "Visible", "Perceptible",
17011             "Heavy Weight", "Backup",
17012             "A Services", "Home",
17013             "Previous", "B Services", "Cached"
17014     };
17015     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17016             "native",
17017             "sys", "pers", "persvc", "fore",
17018             "vis", "percept",
17019             "heavy", "backup",
17020             "servicea", "home",
17021             "prev", "serviceb", "cached"
17022     };
17023
17024     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17025             long realtime, boolean isCheckinRequest, boolean isCompact) {
17026         if (isCompact) {
17027             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17028         }
17029         if (isCheckinRequest || isCompact) {
17030             // short checkin version
17031             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17032         } else {
17033             pw.println("Applications Memory Usage (in Kilobytes):");
17034             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17035         }
17036     }
17037
17038     private static final int KSM_SHARED = 0;
17039     private static final int KSM_SHARING = 1;
17040     private static final int KSM_UNSHARED = 2;
17041     private static final int KSM_VOLATILE = 3;
17042
17043     private final long[] getKsmInfo() {
17044         long[] longOut = new long[4];
17045         final int[] SINGLE_LONG_FORMAT = new int[] {
17046             PROC_SPACE_TERM| PROC_OUT_LONG
17047         };
17048         long[] longTmp = new long[1];
17049         readProcFile("/sys/kernel/mm/ksm/pages_shared",
17050                 SINGLE_LONG_FORMAT, null, longTmp, null);
17051         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17052         longTmp[0] = 0;
17053         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17054                 SINGLE_LONG_FORMAT, null, longTmp, null);
17055         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17056         longTmp[0] = 0;
17057         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17058                 SINGLE_LONG_FORMAT, null, longTmp, null);
17059         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17060         longTmp[0] = 0;
17061         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17062                 SINGLE_LONG_FORMAT, null, longTmp, null);
17063         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17064         return longOut;
17065     }
17066
17067     private static String stringifySize(long size, int order) {
17068         Locale locale = Locale.US;
17069         switch (order) {
17070             case 1:
17071                 return String.format(locale, "%,13d", size);
17072             case 1024:
17073                 return String.format(locale, "%,9dK", size / 1024);
17074             case 1024 * 1024:
17075                 return String.format(locale, "%,5dM", size / 1024 / 1024);
17076             case 1024 * 1024 * 1024:
17077                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17078             default:
17079                 throw new IllegalArgumentException("Invalid size order");
17080         }
17081     }
17082
17083     private static String stringifyKBSize(long size) {
17084         return stringifySize(size * 1024, 1024);
17085     }
17086
17087     // Update this version number in case you change the 'compact' format
17088     private static final int MEMINFO_COMPACT_VERSION = 1;
17089
17090     final void dumpApplicationMemoryUsage(FileDescriptor fd,
17091             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17092         boolean dumpDetails = false;
17093         boolean dumpFullDetails = false;
17094         boolean dumpDalvik = false;
17095         boolean dumpSummaryOnly = false;
17096         boolean dumpUnreachable = false;
17097         boolean oomOnly = false;
17098         boolean isCompact = false;
17099         boolean localOnly = false;
17100         boolean packages = false;
17101         boolean isCheckinRequest = false;
17102         boolean dumpSwapPss = false;
17103
17104         int opti = 0;
17105         while (opti < args.length) {
17106             String opt = args[opti];
17107             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17108                 break;
17109             }
17110             opti++;
17111             if ("-a".equals(opt)) {
17112                 dumpDetails = true;
17113                 dumpFullDetails = true;
17114                 dumpDalvik = true;
17115                 dumpSwapPss = true;
17116             } else if ("-d".equals(opt)) {
17117                 dumpDalvik = true;
17118             } else if ("-c".equals(opt)) {
17119                 isCompact = true;
17120             } else if ("-s".equals(opt)) {
17121                 dumpDetails = true;
17122                 dumpSummaryOnly = true;
17123             } else if ("-S".equals(opt)) {
17124                 dumpSwapPss = true;
17125             } else if ("--unreachable".equals(opt)) {
17126                 dumpUnreachable = true;
17127             } else if ("--oom".equals(opt)) {
17128                 oomOnly = true;
17129             } else if ("--local".equals(opt)) {
17130                 localOnly = true;
17131             } else if ("--package".equals(opt)) {
17132                 packages = true;
17133             } else if ("--checkin".equals(opt)) {
17134                 isCheckinRequest = true;
17135
17136             } else if ("-h".equals(opt)) {
17137                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17138                 pw.println("  -a: include all available information for each process.");
17139                 pw.println("  -d: include dalvik details.");
17140                 pw.println("  -c: dump in a compact machine-parseable representation.");
17141                 pw.println("  -s: dump only summary of application memory usage.");
17142                 pw.println("  -S: dump also SwapPss.");
17143                 pw.println("  --oom: only show processes organized by oom adj.");
17144                 pw.println("  --local: only collect details locally, don't call process.");
17145                 pw.println("  --package: interpret process arg as package, dumping all");
17146                 pw.println("             processes that have loaded that package.");
17147                 pw.println("  --checkin: dump data for a checkin");
17148                 pw.println("If [process] is specified it can be the name or ");
17149                 pw.println("pid of a specific process to dump.");
17150                 return;
17151             } else {
17152                 pw.println("Unknown argument: " + opt + "; use -h for help");
17153             }
17154         }
17155
17156         long uptime = SystemClock.uptimeMillis();
17157         long realtime = SystemClock.elapsedRealtime();
17158         final long[] tmpLong = new long[1];
17159
17160         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17161         if (procs == null) {
17162             // No Java processes.  Maybe they want to print a native process.
17163             if (args != null && args.length > opti
17164                     && args[opti].charAt(0) != '-') {
17165                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17166                         = new ArrayList<ProcessCpuTracker.Stats>();
17167                 updateCpuStatsNow();
17168                 int findPid = -1;
17169                 try {
17170                     findPid = Integer.parseInt(args[opti]);
17171                 } catch (NumberFormatException e) {
17172                 }
17173                 synchronized (mProcessCpuTracker) {
17174                     final int N = mProcessCpuTracker.countStats();
17175                     for (int i=0; i<N; i++) {
17176                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17177                         if (st.pid == findPid || (st.baseName != null
17178                                 && st.baseName.equals(args[opti]))) {
17179                             nativeProcs.add(st);
17180                         }
17181                     }
17182                 }
17183                 if (nativeProcs.size() > 0) {
17184                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17185                             isCompact);
17186                     Debug.MemoryInfo mi = null;
17187                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17188                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17189                         final int pid = r.pid;
17190                         if (!isCheckinRequest && dumpDetails) {
17191                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17192                         }
17193                         if (mi == null) {
17194                             mi = new Debug.MemoryInfo();
17195                         }
17196                         if (dumpDetails || (!brief && !oomOnly)) {
17197                             Debug.getMemoryInfo(pid, mi);
17198                         } else {
17199                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17200                             mi.dalvikPrivateDirty = (int)tmpLong[0];
17201                         }
17202                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17203                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17204                         if (isCheckinRequest) {
17205                             pw.println();
17206                         }
17207                     }
17208                     return;
17209                 }
17210             }
17211             pw.println("No process found for: " + args[opti]);
17212             return;
17213         }
17214
17215         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17216             dumpDetails = true;
17217         }
17218
17219         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17220
17221         String[] innerArgs = new String[args.length-opti];
17222         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17223
17224         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17225         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17226         long nativePss = 0;
17227         long nativeSwapPss = 0;
17228         long dalvikPss = 0;
17229         long dalvikSwapPss = 0;
17230         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17231                 EmptyArray.LONG;
17232         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17233                 EmptyArray.LONG;
17234         long otherPss = 0;
17235         long otherSwapPss = 0;
17236         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17237         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17238
17239         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17240         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17241         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17242                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17243
17244         long totalPss = 0;
17245         long totalSwapPss = 0;
17246         long cachedPss = 0;
17247         long cachedSwapPss = 0;
17248         boolean hasSwapPss = false;
17249
17250         Debug.MemoryInfo mi = null;
17251         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17252             final ProcessRecord r = procs.get(i);
17253             final IApplicationThread thread;
17254             final int pid;
17255             final int oomAdj;
17256             final boolean hasActivities;
17257             synchronized (this) {
17258                 thread = r.thread;
17259                 pid = r.pid;
17260                 oomAdj = r.getSetAdjWithServices();
17261                 hasActivities = r.activities.size() > 0;
17262             }
17263             if (thread != null) {
17264                 if (!isCheckinRequest && dumpDetails) {
17265                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17266                 }
17267                 if (mi == null) {
17268                     mi = new Debug.MemoryInfo();
17269                 }
17270                 if (dumpDetails || (!brief && !oomOnly)) {
17271                     Debug.getMemoryInfo(pid, mi);
17272                     hasSwapPss = mi.hasSwappedOutPss;
17273                 } else {
17274                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17275                     mi.dalvikPrivateDirty = (int)tmpLong[0];
17276                 }
17277                 if (dumpDetails) {
17278                     if (localOnly) {
17279                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17280                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17281                         if (isCheckinRequest) {
17282                             pw.println();
17283                         }
17284                     } else {
17285                         pw.flush();
17286                         try {
17287                             TransferPipe tp = new TransferPipe();
17288                             try {
17289                                 thread.dumpMemInfo(tp.getWriteFd(),
17290                                         mi, isCheckinRequest, dumpFullDetails,
17291                                         dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17292                                 tp.go(fd);
17293                             } finally {
17294                                 tp.kill();
17295                             }
17296                         } catch (IOException e) {
17297                             if (!isCheckinRequest) {
17298                                 pw.println("Got IoException! " + e);
17299                                 pw.flush();
17300                             }
17301                         } catch (RemoteException e) {
17302                             if (!isCheckinRequest) {
17303                                 pw.println("Got RemoteException! " + e);
17304                                 pw.flush();
17305                             }
17306                         }
17307                     }
17308                 }
17309
17310                 final long myTotalPss = mi.getTotalPss();
17311                 final long myTotalUss = mi.getTotalUss();
17312                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17313
17314                 synchronized (this) {
17315                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17316                         // Record this for posterity if the process has been stable.
17317                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17318                     }
17319                 }
17320
17321                 if (!isCheckinRequest && mi != null) {
17322                     totalPss += myTotalPss;
17323                     totalSwapPss += myTotalSwapPss;
17324                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17325                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17326                             myTotalSwapPss, pid, hasActivities);
17327                     procMems.add(pssItem);
17328                     procMemsMap.put(pid, pssItem);
17329
17330                     nativePss += mi.nativePss;
17331                     nativeSwapPss += mi.nativeSwappedOutPss;
17332                     dalvikPss += mi.dalvikPss;
17333                     dalvikSwapPss += mi.dalvikSwappedOutPss;
17334                     for (int j=0; j<dalvikSubitemPss.length; j++) {
17335                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17336                         dalvikSubitemSwapPss[j] +=
17337                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17338                     }
17339                     otherPss += mi.otherPss;
17340                     otherSwapPss += mi.otherSwappedOutPss;
17341                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17342                         long mem = mi.getOtherPss(j);
17343                         miscPss[j] += mem;
17344                         otherPss -= mem;
17345                         mem = mi.getOtherSwappedOutPss(j);
17346                         miscSwapPss[j] += mem;
17347                         otherSwapPss -= mem;
17348                     }
17349
17350                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17351                         cachedPss += myTotalPss;
17352                         cachedSwapPss += myTotalSwapPss;
17353                     }
17354
17355                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17356                         if (oomIndex == (oomPss.length - 1)
17357                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17358                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17359                             oomPss[oomIndex] += myTotalPss;
17360                             oomSwapPss[oomIndex] += myTotalSwapPss;
17361                             if (oomProcs[oomIndex] == null) {
17362                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
17363                             }
17364                             oomProcs[oomIndex].add(pssItem);
17365                             break;
17366                         }
17367                     }
17368                 }
17369             }
17370         }
17371
17372         long nativeProcTotalPss = 0;
17373
17374         if (!isCheckinRequest && procs.size() > 1 && !packages) {
17375             // If we are showing aggregations, also look for native processes to
17376             // include so that our aggregations are more accurate.
17377             updateCpuStatsNow();
17378             mi = null;
17379             synchronized (mProcessCpuTracker) {
17380                 final int N = mProcessCpuTracker.countStats();
17381                 for (int i=0; i<N; i++) {
17382                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17383                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17384                         if (mi == null) {
17385                             mi = new Debug.MemoryInfo();
17386                         }
17387                         if (!brief && !oomOnly) {
17388                             Debug.getMemoryInfo(st.pid, mi);
17389                         } else {
17390                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17391                             mi.nativePrivateDirty = (int)tmpLong[0];
17392                         }
17393
17394                         final long myTotalPss = mi.getTotalPss();
17395                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17396                         totalPss += myTotalPss;
17397                         nativeProcTotalPss += myTotalPss;
17398
17399                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17400                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17401                         procMems.add(pssItem);
17402
17403                         nativePss += mi.nativePss;
17404                         nativeSwapPss += mi.nativeSwappedOutPss;
17405                         dalvikPss += mi.dalvikPss;
17406                         dalvikSwapPss += mi.dalvikSwappedOutPss;
17407                         for (int j=0; j<dalvikSubitemPss.length; j++) {
17408                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17409                             dalvikSubitemSwapPss[j] +=
17410                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17411                         }
17412                         otherPss += mi.otherPss;
17413                         otherSwapPss += mi.otherSwappedOutPss;
17414                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17415                             long mem = mi.getOtherPss(j);
17416                             miscPss[j] += mem;
17417                             otherPss -= mem;
17418                             mem = mi.getOtherSwappedOutPss(j);
17419                             miscSwapPss[j] += mem;
17420                             otherSwapPss -= mem;
17421                         }
17422                         oomPss[0] += myTotalPss;
17423                         oomSwapPss[0] += myTotalSwapPss;
17424                         if (oomProcs[0] == null) {
17425                             oomProcs[0] = new ArrayList<MemItem>();
17426                         }
17427                         oomProcs[0].add(pssItem);
17428                     }
17429                 }
17430             }
17431
17432             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17433
17434             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17435             final int dalvikId = -2;
17436             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17437             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17438             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17439                 String label = Debug.MemoryInfo.getOtherLabel(j);
17440                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17441             }
17442             if (dalvikSubitemPss.length > 0) {
17443                 // Add dalvik subitems.
17444                 for (MemItem memItem : catMems) {
17445                     int memItemStart = 0, memItemEnd = 0;
17446                     if (memItem.id == dalvikId) {
17447                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17448                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17449                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17450                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17451                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17452                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17453                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17454                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17455                     } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17456                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17457                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17458                     } else {
17459                         continue;  // No subitems, continue.
17460                     }
17461                     memItem.subitems = new ArrayList<MemItem>();
17462                     for (int j=memItemStart; j<=memItemEnd; j++) {
17463                         final String name = Debug.MemoryInfo.getOtherLabel(
17464                                 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17465                         memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17466                                 dalvikSubitemSwapPss[j], j));
17467                     }
17468                 }
17469             }
17470
17471             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17472             for (int j=0; j<oomPss.length; j++) {
17473                 if (oomPss[j] != 0) {
17474                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17475                             : DUMP_MEM_OOM_LABEL[j];
17476                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17477                             DUMP_MEM_OOM_ADJ[j]);
17478                     item.subitems = oomProcs[j];
17479                     oomMems.add(item);
17480                 }
17481             }
17482
17483             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17484             if (!brief && !oomOnly && !isCompact) {
17485                 pw.println();
17486                 pw.println("Total PSS by process:");
17487                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17488                 pw.println();
17489             }
17490             if (!isCompact) {
17491                 pw.println("Total PSS by OOM adjustment:");
17492             }
17493             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17494             if (!brief && !oomOnly) {
17495                 PrintWriter out = categoryPw != null ? categoryPw : pw;
17496                 if (!isCompact) {
17497                     out.println();
17498                     out.println("Total PSS by category:");
17499                 }
17500                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17501             }
17502             if (!isCompact) {
17503                 pw.println();
17504             }
17505             MemInfoReader memInfo = new MemInfoReader();
17506             memInfo.readMemInfo();
17507             if (nativeProcTotalPss > 0) {
17508                 synchronized (this) {
17509                     final long cachedKb = memInfo.getCachedSizeKb();
17510                     final long freeKb = memInfo.getFreeSizeKb();
17511                     final long zramKb = memInfo.getZramTotalSizeKb();
17512                     final long kernelKb = memInfo.getKernelUsedSizeKb();
17513                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17514                             kernelKb*1024, nativeProcTotalPss*1024);
17515                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17516                             nativeProcTotalPss);
17517                 }
17518             }
17519             if (!brief) {
17520                 if (!isCompact) {
17521                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17522                     pw.print(" (status ");
17523                     switch (mLastMemoryLevel) {
17524                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17525                             pw.println("normal)");
17526                             break;
17527                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17528                             pw.println("moderate)");
17529                             break;
17530                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
17531                             pw.println("low)");
17532                             break;
17533                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17534                             pw.println("critical)");
17535                             break;
17536                         default:
17537                             pw.print(mLastMemoryLevel);
17538                             pw.println(")");
17539                             break;
17540                     }
17541                     pw.print(" Free RAM: ");
17542                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17543                             + memInfo.getFreeSizeKb()));
17544                     pw.print(" (");
17545                     pw.print(stringifyKBSize(cachedPss));
17546                     pw.print(" cached pss + ");
17547                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17548                     pw.print(" cached kernel + ");
17549                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17550                     pw.println(" free)");
17551                 } else {
17552                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17553                     pw.print(cachedPss + memInfo.getCachedSizeKb()
17554                             + memInfo.getFreeSizeKb()); pw.print(",");
17555                     pw.println(totalPss - cachedPss);
17556                 }
17557             }
17558             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17559                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17560                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17561             if (!isCompact) {
17562                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17563                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17564                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17565                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17566                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17567             } else {
17568                 pw.print("lostram,"); pw.println(lostRAM);
17569             }
17570             if (!brief) {
17571                 if (memInfo.getZramTotalSizeKb() != 0) {
17572                     if (!isCompact) {
17573                         pw.print("     ZRAM: ");
17574                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17575                                 pw.print(" physical used for ");
17576                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17577                                         - memInfo.getSwapFreeSizeKb()));
17578                                 pw.print(" in swap (");
17579                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17580                                 pw.println(" total swap)");
17581                     } else {
17582                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17583                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17584                                 pw.println(memInfo.getSwapFreeSizeKb());
17585                     }
17586                 }
17587                 final long[] ksm = getKsmInfo();
17588                 if (!isCompact) {
17589                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17590                             || ksm[KSM_VOLATILE] != 0) {
17591                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17592                                 pw.print(" saved from shared ");
17593                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17594                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17595                                 pw.print(" unshared; ");
17596                                 pw.print(stringifyKBSize(
17597                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
17598                     }
17599                     pw.print("   Tuning: ");
17600                     pw.print(ActivityManager.staticGetMemoryClass());
17601                     pw.print(" (large ");
17602                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17603                     pw.print("), oom ");
17604                     pw.print(stringifySize(
17605                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17606                     pw.print(", restore limit ");
17607                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17608                     if (ActivityManager.isLowRamDeviceStatic()) {
17609                         pw.print(" (low-ram)");
17610                     }
17611                     if (ActivityManager.isHighEndGfx()) {
17612                         pw.print(" (high-end-gfx)");
17613                     }
17614                     pw.println();
17615                 } else {
17616                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17617                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17618                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17619                     pw.print("tuning,");
17620                     pw.print(ActivityManager.staticGetMemoryClass());
17621                     pw.print(',');
17622                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17623                     pw.print(',');
17624                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17625                     if (ActivityManager.isLowRamDeviceStatic()) {
17626                         pw.print(",low-ram");
17627                     }
17628                     if (ActivityManager.isHighEndGfx()) {
17629                         pw.print(",high-end-gfx");
17630                     }
17631                     pw.println();
17632                 }
17633             }
17634         }
17635     }
17636
17637     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17638             long memtrack, String name) {
17639         sb.append("  ");
17640         sb.append(ProcessList.makeOomAdjString(oomAdj));
17641         sb.append(' ');
17642         sb.append(ProcessList.makeProcStateString(procState));
17643         sb.append(' ');
17644         ProcessList.appendRamKb(sb, pss);
17645         sb.append(": ");
17646         sb.append(name);
17647         if (memtrack > 0) {
17648             sb.append(" (");
17649             sb.append(stringifyKBSize(memtrack));
17650             sb.append(" memtrack)");
17651         }
17652     }
17653
17654     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17655         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17656         sb.append(" (pid ");
17657         sb.append(mi.pid);
17658         sb.append(") ");
17659         sb.append(mi.adjType);
17660         sb.append('\n');
17661         if (mi.adjReason != null) {
17662             sb.append("                      ");
17663             sb.append(mi.adjReason);
17664             sb.append('\n');
17665         }
17666     }
17667
17668     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17669         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17670         for (int i=0, N=memInfos.size(); i<N; i++) {
17671             ProcessMemInfo mi = memInfos.get(i);
17672             infoMap.put(mi.pid, mi);
17673         }
17674         updateCpuStatsNow();
17675         long[] memtrackTmp = new long[1];
17676         final List<ProcessCpuTracker.Stats> stats;
17677         // Get a list of Stats that have vsize > 0
17678         synchronized (mProcessCpuTracker) {
17679             stats = mProcessCpuTracker.getStats((st) -> {
17680                 return st.vsize > 0;
17681             });
17682         }
17683         final int statsCount = stats.size();
17684         for (int i = 0; i < statsCount; i++) {
17685             ProcessCpuTracker.Stats st = stats.get(i);
17686             long pss = Debug.getPss(st.pid, null, memtrackTmp);
17687             if (pss > 0) {
17688                 if (infoMap.indexOfKey(st.pid) < 0) {
17689                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17690                             ProcessList.NATIVE_ADJ, -1, "native", null);
17691                     mi.pss = pss;
17692                     mi.memtrack = memtrackTmp[0];
17693                     memInfos.add(mi);
17694                 }
17695             }
17696         }
17697
17698         long totalPss = 0;
17699         long totalMemtrack = 0;
17700         for (int i=0, N=memInfos.size(); i<N; i++) {
17701             ProcessMemInfo mi = memInfos.get(i);
17702             if (mi.pss == 0) {
17703                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17704                 mi.memtrack = memtrackTmp[0];
17705             }
17706             totalPss += mi.pss;
17707             totalMemtrack += mi.memtrack;
17708         }
17709         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17710             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17711                 if (lhs.oomAdj != rhs.oomAdj) {
17712                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17713                 }
17714                 if (lhs.pss != rhs.pss) {
17715                     return lhs.pss < rhs.pss ? 1 : -1;
17716                 }
17717                 return 0;
17718             }
17719         });
17720
17721         StringBuilder tag = new StringBuilder(128);
17722         StringBuilder stack = new StringBuilder(128);
17723         tag.append("Low on memory -- ");
17724         appendMemBucket(tag, totalPss, "total", false);
17725         appendMemBucket(stack, totalPss, "total", true);
17726
17727         StringBuilder fullNativeBuilder = new StringBuilder(1024);
17728         StringBuilder shortNativeBuilder = new StringBuilder(1024);
17729         StringBuilder fullJavaBuilder = new StringBuilder(1024);
17730
17731         boolean firstLine = true;
17732         int lastOomAdj = Integer.MIN_VALUE;
17733         long extraNativeRam = 0;
17734         long extraNativeMemtrack = 0;
17735         long cachedPss = 0;
17736         for (int i=0, N=memInfos.size(); i<N; i++) {
17737             ProcessMemInfo mi = memInfos.get(i);
17738
17739             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17740                 cachedPss += mi.pss;
17741             }
17742
17743             if (mi.oomAdj != ProcessList.NATIVE_ADJ
17744                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
17745                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
17746                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17747                 if (lastOomAdj != mi.oomAdj) {
17748                     lastOomAdj = mi.oomAdj;
17749                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17750                         tag.append(" / ");
17751                     }
17752                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17753                         if (firstLine) {
17754                             stack.append(":");
17755                             firstLine = false;
17756                         }
17757                         stack.append("\n\t at ");
17758                     } else {
17759                         stack.append("$");
17760                     }
17761                 } else {
17762                     tag.append(" ");
17763                     stack.append("$");
17764                 }
17765                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17766                     appendMemBucket(tag, mi.pss, mi.name, false);
17767                 }
17768                 appendMemBucket(stack, mi.pss, mi.name, true);
17769                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17770                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17771                     stack.append("(");
17772                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17773                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17774                             stack.append(DUMP_MEM_OOM_LABEL[k]);
17775                             stack.append(":");
17776                             stack.append(DUMP_MEM_OOM_ADJ[k]);
17777                         }
17778                     }
17779                     stack.append(")");
17780                 }
17781             }
17782
17783             appendMemInfo(fullNativeBuilder, mi);
17784             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17785                 // The short form only has native processes that are >= 512K.
17786                 if (mi.pss >= 512) {
17787                     appendMemInfo(shortNativeBuilder, mi);
17788                 } else {
17789                     extraNativeRam += mi.pss;
17790                     extraNativeMemtrack += mi.memtrack;
17791                 }
17792             } else {
17793                 // Short form has all other details, but if we have collected RAM
17794                 // from smaller native processes let's dump a summary of that.
17795                 if (extraNativeRam > 0) {
17796                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17797                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17798                     shortNativeBuilder.append('\n');
17799                     extraNativeRam = 0;
17800                 }
17801                 appendMemInfo(fullJavaBuilder, mi);
17802             }
17803         }
17804
17805         fullJavaBuilder.append("           ");
17806         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17807         fullJavaBuilder.append(": TOTAL");
17808         if (totalMemtrack > 0) {
17809             fullJavaBuilder.append(" (");
17810             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17811             fullJavaBuilder.append(" memtrack)");
17812         } else {
17813         }
17814         fullJavaBuilder.append("\n");
17815
17816         MemInfoReader memInfo = new MemInfoReader();
17817         memInfo.readMemInfo();
17818         final long[] infos = memInfo.getRawInfo();
17819
17820         StringBuilder memInfoBuilder = new StringBuilder(1024);
17821         Debug.getMemInfo(infos);
17822         memInfoBuilder.append("  MemInfo: ");
17823         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17824         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17825         memInfoBuilder.append(stringifyKBSize(
17826                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17827         memInfoBuilder.append(stringifyKBSize(
17828                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17829         memInfoBuilder.append(stringifyKBSize(
17830                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17831         memInfoBuilder.append("           ");
17832         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17833         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17834         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17835         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17836         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17837             memInfoBuilder.append("  ZRAM: ");
17838             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17839             memInfoBuilder.append(" RAM, ");
17840             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17841             memInfoBuilder.append(" swap total, ");
17842             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17843             memInfoBuilder.append(" swap free\n");
17844         }
17845         final long[] ksm = getKsmInfo();
17846         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17847                 || ksm[KSM_VOLATILE] != 0) {
17848             memInfoBuilder.append("  KSM: ");
17849             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17850             memInfoBuilder.append(" saved from shared ");
17851             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17852             memInfoBuilder.append("\n       ");
17853             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17854             memInfoBuilder.append(" unshared; ");
17855             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17856             memInfoBuilder.append(" volatile\n");
17857         }
17858         memInfoBuilder.append("  Free RAM: ");
17859         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17860                 + memInfo.getFreeSizeKb()));
17861         memInfoBuilder.append("\n");
17862         memInfoBuilder.append("  Used RAM: ");
17863         memInfoBuilder.append(stringifyKBSize(
17864                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17865         memInfoBuilder.append("\n");
17866         memInfoBuilder.append("  Lost RAM: ");
17867         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17868                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17869                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17870         memInfoBuilder.append("\n");
17871         Slog.i(TAG, "Low on memory:");
17872         Slog.i(TAG, shortNativeBuilder.toString());
17873         Slog.i(TAG, fullJavaBuilder.toString());
17874         Slog.i(TAG, memInfoBuilder.toString());
17875
17876         StringBuilder dropBuilder = new StringBuilder(1024);
17877         /*
17878         StringWriter oomSw = new StringWriter();
17879         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17880         StringWriter catSw = new StringWriter();
17881         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17882         String[] emptyArgs = new String[] { };
17883         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17884         oomPw.flush();
17885         String oomString = oomSw.toString();
17886         */
17887         dropBuilder.append("Low on memory:");
17888         dropBuilder.append(stack);
17889         dropBuilder.append('\n');
17890         dropBuilder.append(fullNativeBuilder);
17891         dropBuilder.append(fullJavaBuilder);
17892         dropBuilder.append('\n');
17893         dropBuilder.append(memInfoBuilder);
17894         dropBuilder.append('\n');
17895         /*
17896         dropBuilder.append(oomString);
17897         dropBuilder.append('\n');
17898         */
17899         StringWriter catSw = new StringWriter();
17900         synchronized (ActivityManagerService.this) {
17901             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17902             String[] emptyArgs = new String[] { };
17903             catPw.println();
17904             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17905             catPw.println();
17906             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17907                     false, null).dumpLocked();
17908             catPw.println();
17909             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17910             catPw.flush();
17911         }
17912         dropBuilder.append(catSw.toString());
17913         addErrorToDropBox("lowmem", null, "system_server", null,
17914                 null, tag.toString(), dropBuilder.toString(), null, null);
17915         //Slog.i(TAG, "Sent to dropbox:");
17916         //Slog.i(TAG, dropBuilder.toString());
17917         synchronized (ActivityManagerService.this) {
17918             long now = SystemClock.uptimeMillis();
17919             if (mLastMemUsageReportTime < now) {
17920                 mLastMemUsageReportTime = now;
17921             }
17922         }
17923     }
17924
17925     /**
17926      * Searches array of arguments for the specified string
17927      * @param args array of argument strings
17928      * @param value value to search for
17929      * @return true if the value is contained in the array
17930      */
17931     private static boolean scanArgs(String[] args, String value) {
17932         if (args != null) {
17933             for (String arg : args) {
17934                 if (value.equals(arg)) {
17935                     return true;
17936                 }
17937             }
17938         }
17939         return false;
17940     }
17941
17942     private final boolean removeDyingProviderLocked(ProcessRecord proc,
17943             ContentProviderRecord cpr, boolean always) {
17944         final boolean inLaunching = mLaunchingProviders.contains(cpr);
17945
17946         if (!inLaunching || always) {
17947             synchronized (cpr) {
17948                 cpr.launchingApp = null;
17949                 cpr.notifyAll();
17950             }
17951             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17952             String names[] = cpr.info.authority.split(";");
17953             for (int j = 0; j < names.length; j++) {
17954                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17955             }
17956         }
17957
17958         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17959             ContentProviderConnection conn = cpr.connections.get(i);
17960             if (conn.waiting) {
17961                 // If this connection is waiting for the provider, then we don't
17962                 // need to mess with its process unless we are always removing
17963                 // or for some reason the provider is not currently launching.
17964                 if (inLaunching && !always) {
17965                     continue;
17966                 }
17967             }
17968             ProcessRecord capp = conn.client;
17969             conn.dead = true;
17970             if (conn.stableCount > 0) {
17971                 if (!capp.persistent && capp.thread != null
17972                         && capp.pid != 0
17973                         && capp.pid != MY_PID) {
17974                     capp.kill("depends on provider "
17975                             + cpr.name.flattenToShortString()
17976                             + " in dying proc " + (proc != null ? proc.processName : "??")
17977                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17978                 }
17979             } else if (capp.thread != null && conn.provider.provider != null) {
17980                 try {
17981                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17982                 } catch (RemoteException e) {
17983                 }
17984                 // In the protocol here, we don't expect the client to correctly
17985                 // clean up this connection, we'll just remove it.
17986                 cpr.connections.remove(i);
17987                 if (conn.client.conProviders.remove(conn)) {
17988                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17989                 }
17990             }
17991         }
17992
17993         if (inLaunching && always) {
17994             mLaunchingProviders.remove(cpr);
17995         }
17996         return inLaunching;
17997     }
17998
17999     /**
18000      * Main code for cleaning up a process when it has gone away.  This is
18001      * called both as a result of the process dying, or directly when stopping
18002      * a process when running in single process mode.
18003      *
18004      * @return Returns true if the given process has been restarted, so the
18005      * app that was passed in must remain on the process lists.
18006      */
18007     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18008             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18009         if (index >= 0) {
18010             removeLruProcessLocked(app);
18011             ProcessList.remove(app.pid);
18012         }
18013
18014         mProcessesToGc.remove(app);
18015         mPendingPssProcesses.remove(app);
18016
18017         // Dismiss any open dialogs.
18018         if (app.crashDialog != null && !app.forceCrashReport) {
18019             app.crashDialog.dismiss();
18020             app.crashDialog = null;
18021         }
18022         if (app.anrDialog != null) {
18023             app.anrDialog.dismiss();
18024             app.anrDialog = null;
18025         }
18026         if (app.waitDialog != null) {
18027             app.waitDialog.dismiss();
18028             app.waitDialog = null;
18029         }
18030
18031         app.crashing = false;
18032         app.notResponding = false;
18033
18034         app.resetPackageList(mProcessStats);
18035         app.unlinkDeathRecipient();
18036         app.makeInactive(mProcessStats);
18037         app.waitingToKill = null;
18038         app.forcingToImportant = null;
18039         updateProcessForegroundLocked(app, false, false);
18040         app.foregroundActivities = false;
18041         app.hasShownUi = false;
18042         app.treatLikeActivity = false;
18043         app.hasAboveClient = false;
18044         app.hasClientActivities = false;
18045
18046         mServices.killServicesLocked(app, allowRestart);
18047
18048         boolean restart = false;
18049
18050         // Remove published content providers.
18051         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18052             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18053             final boolean always = app.bad || !allowRestart;
18054             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18055             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18056                 // We left the provider in the launching list, need to
18057                 // restart it.
18058                 restart = true;
18059             }
18060
18061             cpr.provider = null;
18062             cpr.proc = null;
18063         }
18064         app.pubProviders.clear();
18065
18066         // Take care of any launching providers waiting for this process.
18067         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18068             restart = true;
18069         }
18070
18071         // Unregister from connected content providers.
18072         if (!app.conProviders.isEmpty()) {
18073             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18074                 ContentProviderConnection conn = app.conProviders.get(i);
18075                 conn.provider.connections.remove(conn);
18076                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18077                         conn.provider.name);
18078             }
18079             app.conProviders.clear();
18080         }
18081
18082         // At this point there may be remaining entries in mLaunchingProviders
18083         // where we were the only one waiting, so they are no longer of use.
18084         // Look for these and clean up if found.
18085         // XXX Commented out for now.  Trying to figure out a way to reproduce
18086         // the actual situation to identify what is actually going on.
18087         if (false) {
18088             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18089                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18090                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18091                     synchronized (cpr) {
18092                         cpr.launchingApp = null;
18093                         cpr.notifyAll();
18094                     }
18095                 }
18096             }
18097         }
18098
18099         skipCurrentReceiverLocked(app);
18100
18101         // Unregister any receivers.
18102         for (int i = app.receivers.size() - 1; i >= 0; i--) {
18103             removeReceiverLocked(app.receivers.valueAt(i));
18104         }
18105         app.receivers.clear();
18106
18107         // If the app is undergoing backup, tell the backup manager about it
18108         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18109             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18110                     + mBackupTarget.appInfo + " died during backup");
18111             mHandler.post(new Runnable() {
18112                 @Override
18113                 public void run(){
18114                     try {
18115                         IBackupManager bm = IBackupManager.Stub.asInterface(
18116                                 ServiceManager.getService(Context.BACKUP_SERVICE));
18117                         bm.agentDisconnected(app.info.packageName);
18118                     } catch (RemoteException e) {
18119                         // can't happen; backup manager is local
18120                     }
18121                 }
18122             });
18123         }
18124
18125         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18126             ProcessChangeItem item = mPendingProcessChanges.get(i);
18127             if (item.pid == app.pid) {
18128                 mPendingProcessChanges.remove(i);
18129                 mAvailProcessChanges.add(item);
18130             }
18131         }
18132         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18133                 null).sendToTarget();
18134
18135         // If the caller is restarting this app, then leave it in its
18136         // current lists and let the caller take care of it.
18137         if (restarting) {
18138             return false;
18139         }
18140
18141         if (!app.persistent || app.isolated) {
18142             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18143                     "Removing non-persistent process during cleanup: " + app);
18144             if (!replacingPid) {
18145                 removeProcessNameLocked(app.processName, app.uid, app);
18146             }
18147             if (mHeavyWeightProcess == app) {
18148                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18149                         mHeavyWeightProcess.userId, 0));
18150                 mHeavyWeightProcess = null;
18151             }
18152         } else if (!app.removed) {
18153             // This app is persistent, so we need to keep its record around.
18154             // If it is not already on the pending app list, add it there
18155             // and start a new process for it.
18156             if (mPersistentStartingProcesses.indexOf(app) < 0) {
18157                 mPersistentStartingProcesses.add(app);
18158                 restart = true;
18159             }
18160         }
18161         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18162                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18163         mProcessesOnHold.remove(app);
18164
18165         if (app == mHomeProcess) {
18166             mHomeProcess = null;
18167         }
18168         if (app == mPreviousProcess) {
18169             mPreviousProcess = null;
18170         }
18171
18172         if (restart && !app.isolated) {
18173             // We have components that still need to be running in the
18174             // process, so re-launch it.
18175             if (index < 0) {
18176                 ProcessList.remove(app.pid);
18177             }
18178             addProcessNameLocked(app);
18179             startProcessLocked(app, "restart", app.processName);
18180             return true;
18181         } else if (app.pid > 0 && app.pid != MY_PID) {
18182             // Goodbye!
18183             boolean removed;
18184             synchronized (mPidsSelfLocked) {
18185                 mPidsSelfLocked.remove(app.pid);
18186                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18187             }
18188             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18189             if (app.isolated) {
18190                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18191             }
18192             app.setPid(0);
18193         }
18194         return false;
18195     }
18196
18197     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18198         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18199             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18200             if (cpr.launchingApp == app) {
18201                 return true;
18202             }
18203         }
18204         return false;
18205     }
18206
18207     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18208         // Look through the content providers we are waiting to have launched,
18209         // and if any run in this process then either schedule a restart of
18210         // the process or kill the client waiting for it if this process has
18211         // gone bad.
18212         boolean restart = false;
18213         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18214             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18215             if (cpr.launchingApp == app) {
18216                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18217                     restart = true;
18218                 } else {
18219                     removeDyingProviderLocked(app, cpr, true);
18220                 }
18221             }
18222         }
18223         return restart;
18224     }
18225
18226     // =========================================================
18227     // SERVICES
18228     // =========================================================
18229
18230     @Override
18231     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18232             int flags) {
18233         enforceNotIsolatedCaller("getServices");
18234
18235         final int callingUid = Binder.getCallingUid();
18236         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18237             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18238         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18239             callingUid);
18240         synchronized (this) {
18241             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18242                 allowed, canInteractAcrossUsers);
18243         }
18244     }
18245
18246     @Override
18247     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18248         enforceNotIsolatedCaller("getRunningServiceControlPanel");
18249         synchronized (this) {
18250             return mServices.getRunningServiceControlPanelLocked(name);
18251         }
18252     }
18253
18254     @Override
18255     public ComponentName startService(IApplicationThread caller, Intent service,
18256             String resolvedType, boolean requireForeground, String callingPackage, int userId)
18257             throws TransactionTooLargeException {
18258         enforceNotIsolatedCaller("startService");
18259         // Refuse possible leaked file descriptors
18260         if (service != null && service.hasFileDescriptors() == true) {
18261             throw new IllegalArgumentException("File descriptors passed in Intent");
18262         }
18263
18264         if (callingPackage == null) {
18265             throw new IllegalArgumentException("callingPackage cannot be null");
18266         }
18267
18268         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18269                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18270         synchronized(this) {
18271             final int callingPid = Binder.getCallingPid();
18272             final int callingUid = Binder.getCallingUid();
18273             final long origId = Binder.clearCallingIdentity();
18274             ComponentName res;
18275             try {
18276                 res = mServices.startServiceLocked(caller, service,
18277                         resolvedType, callingPid, callingUid,
18278                         requireForeground, callingPackage, userId);
18279             } finally {
18280                 Binder.restoreCallingIdentity(origId);
18281             }
18282             return res;
18283         }
18284     }
18285
18286     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18287             boolean fgRequired, String callingPackage, int userId)
18288             throws TransactionTooLargeException {
18289         synchronized(this) {
18290             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18291                     "startServiceInPackage: " + service + " type=" + resolvedType);
18292             final long origId = Binder.clearCallingIdentity();
18293             ComponentName res;
18294             try {
18295                 res = mServices.startServiceLocked(null, service,
18296                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
18297             } finally {
18298                 Binder.restoreCallingIdentity(origId);
18299             }
18300             return res;
18301         }
18302     }
18303
18304     @Override
18305     public int stopService(IApplicationThread caller, Intent service,
18306             String resolvedType, int userId) {
18307         enforceNotIsolatedCaller("stopService");
18308         // Refuse possible leaked file descriptors
18309         if (service != null && service.hasFileDescriptors() == true) {
18310             throw new IllegalArgumentException("File descriptors passed in Intent");
18311         }
18312
18313         synchronized(this) {
18314             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18315         }
18316     }
18317
18318     @Override
18319     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18320         enforceNotIsolatedCaller("peekService");
18321         // Refuse possible leaked file descriptors
18322         if (service != null && service.hasFileDescriptors() == true) {
18323             throw new IllegalArgumentException("File descriptors passed in Intent");
18324         }
18325
18326         if (callingPackage == null) {
18327             throw new IllegalArgumentException("callingPackage cannot be null");
18328         }
18329
18330         synchronized(this) {
18331             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18332         }
18333     }
18334
18335     @Override
18336     public boolean stopServiceToken(ComponentName className, IBinder token,
18337             int startId) {
18338         synchronized(this) {
18339             return mServices.stopServiceTokenLocked(className, token, startId);
18340         }
18341     }
18342
18343     @Override
18344     public void setServiceForeground(ComponentName className, IBinder token,
18345             int id, Notification notification, int flags) {
18346         synchronized(this) {
18347             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18348         }
18349     }
18350
18351     @Override
18352     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18353             boolean requireFull, String name, String callerPackage) {
18354         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18355                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18356     }
18357
18358     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18359             String className, int flags) {
18360         boolean result = false;
18361         // For apps that don't have pre-defined UIDs, check for permission
18362         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18363             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18364                 if (ActivityManager.checkUidPermission(
18365                         INTERACT_ACROSS_USERS,
18366                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18367                     ComponentName comp = new ComponentName(aInfo.packageName, className);
18368                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
18369                             + " requests FLAG_SINGLE_USER, but app does not hold "
18370                             + INTERACT_ACROSS_USERS;
18371                     Slog.w(TAG, msg);
18372                     throw new SecurityException(msg);
18373                 }
18374                 // Permission passed
18375                 result = true;
18376             }
18377         } else if ("system".equals(componentProcessName)) {
18378             result = true;
18379         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18380             // Phone app and persistent apps are allowed to export singleuser providers.
18381             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18382                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18383         }
18384         if (DEBUG_MU) Slog.v(TAG_MU,
18385                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18386                 + Integer.toHexString(flags) + ") = " + result);
18387         return result;
18388     }
18389
18390     /**
18391      * Checks to see if the caller is in the same app as the singleton
18392      * component, or the component is in a special app. It allows special apps
18393      * to export singleton components but prevents exporting singleton
18394      * components for regular apps.
18395      */
18396     boolean isValidSingletonCall(int callingUid, int componentUid) {
18397         int componentAppId = UserHandle.getAppId(componentUid);
18398         return UserHandle.isSameApp(callingUid, componentUid)
18399                 || componentAppId == SYSTEM_UID
18400                 || componentAppId == PHONE_UID
18401                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18402                         == PackageManager.PERMISSION_GRANTED;
18403     }
18404
18405     public int bindService(IApplicationThread caller, IBinder token, Intent service,
18406             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18407             int userId) throws TransactionTooLargeException {
18408         enforceNotIsolatedCaller("bindService");
18409
18410         // Refuse possible leaked file descriptors
18411         if (service != null && service.hasFileDescriptors() == true) {
18412             throw new IllegalArgumentException("File descriptors passed in Intent");
18413         }
18414
18415         if (callingPackage == null) {
18416             throw new IllegalArgumentException("callingPackage cannot be null");
18417         }
18418
18419         synchronized(this) {
18420             return mServices.bindServiceLocked(caller, token, service,
18421                     resolvedType, connection, flags, callingPackage, userId);
18422         }
18423     }
18424
18425     public boolean unbindService(IServiceConnection connection) {
18426         synchronized (this) {
18427             return mServices.unbindServiceLocked(connection);
18428         }
18429     }
18430
18431     public void publishService(IBinder token, Intent intent, IBinder service) {
18432         // Refuse possible leaked file descriptors
18433         if (intent != null && intent.hasFileDescriptors() == true) {
18434             throw new IllegalArgumentException("File descriptors passed in Intent");
18435         }
18436
18437         synchronized(this) {
18438             if (!(token instanceof ServiceRecord)) {
18439                 throw new IllegalArgumentException("Invalid service token");
18440             }
18441             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18442         }
18443     }
18444
18445     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18446         // Refuse possible leaked file descriptors
18447         if (intent != null && intent.hasFileDescriptors() == true) {
18448             throw new IllegalArgumentException("File descriptors passed in Intent");
18449         }
18450
18451         synchronized(this) {
18452             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18453         }
18454     }
18455
18456     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18457         synchronized(this) {
18458             if (!(token instanceof ServiceRecord)) {
18459                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18460                 throw new IllegalArgumentException("Invalid service token");
18461             }
18462             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18463         }
18464     }
18465
18466     // =========================================================
18467     // BACKUP AND RESTORE
18468     // =========================================================
18469
18470     // Cause the target app to be launched if necessary and its backup agent
18471     // instantiated.  The backup agent will invoke backupAgentCreated() on the
18472     // activity manager to announce its creation.
18473     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18474         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18475         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18476
18477         IPackageManager pm = AppGlobals.getPackageManager();
18478         ApplicationInfo app = null;
18479         try {
18480             app = pm.getApplicationInfo(packageName, 0, userId);
18481         } catch (RemoteException e) {
18482             // can't happen; package manager is process-local
18483         }
18484         if (app == null) {
18485             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18486             return false;
18487         }
18488
18489         int oldBackupUid;
18490         int newBackupUid;
18491
18492         synchronized(this) {
18493             // !!! TODO: currently no check here that we're already bound
18494             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18495             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18496             synchronized (stats) {
18497                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18498             }
18499
18500             // Backup agent is now in use, its package can't be stopped.
18501             try {
18502                 AppGlobals.getPackageManager().setPackageStoppedState(
18503                         app.packageName, false, UserHandle.getUserId(app.uid));
18504             } catch (RemoteException e) {
18505             } catch (IllegalArgumentException e) {
18506                 Slog.w(TAG, "Failed trying to unstop package "
18507                         + app.packageName + ": " + e);
18508             }
18509
18510             BackupRecord r = new BackupRecord(ss, app, backupMode);
18511             ComponentName hostingName =
18512                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18513                             ? new ComponentName(app.packageName, app.backupAgentName)
18514                             : new ComponentName("android", "FullBackupAgent");
18515             // startProcessLocked() returns existing proc's record if it's already running
18516             ProcessRecord proc = startProcessLocked(app.processName, app,
18517                     false, 0, "backup", hostingName, false, false, false);
18518             if (proc == null) {
18519                 Slog.e(TAG, "Unable to start backup agent process " + r);
18520                 return false;
18521             }
18522
18523             // If the app is a regular app (uid >= 10000) and not the system server or phone
18524             // process, etc, then mark it as being in full backup so that certain calls to the
18525             // process can be blocked. This is not reset to false anywhere because we kill the
18526             // process after the full backup is done and the ProcessRecord will vaporize anyway.
18527             if (UserHandle.isApp(app.uid) &&
18528                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18529                 proc.inFullBackup = true;
18530             }
18531             r.app = proc;
18532             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18533             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18534             mBackupTarget = r;
18535             mBackupAppName = app.packageName;
18536
18537             // Try not to kill the process during backup
18538             updateOomAdjLocked(proc, true);
18539
18540             // If the process is already attached, schedule the creation of the backup agent now.
18541             // If it is not yet live, this will be done when it attaches to the framework.
18542             if (proc.thread != null) {
18543                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18544                 try {
18545                     proc.thread.scheduleCreateBackupAgent(app,
18546                             compatibilityInfoForPackageLocked(app), backupMode);
18547                 } catch (RemoteException e) {
18548                     // Will time out on the backup manager side
18549                 }
18550             } else {
18551                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18552             }
18553             // Invariants: at this point, the target app process exists and the application
18554             // is either already running or in the process of coming up.  mBackupTarget and
18555             // mBackupAppName describe the app, so that when it binds back to the AM we
18556             // know that it's scheduled for a backup-agent operation.
18557         }
18558
18559         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18560         if (oldBackupUid != -1) {
18561             js.removeBackingUpUid(oldBackupUid);
18562         }
18563         if (newBackupUid != -1) {
18564             js.addBackingUpUid(newBackupUid);
18565         }
18566
18567         return true;
18568     }
18569
18570     @Override
18571     public void clearPendingBackup() {
18572         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18573         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18574
18575         synchronized (this) {
18576             mBackupTarget = null;
18577             mBackupAppName = null;
18578         }
18579
18580         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18581         js.clearAllBackingUpUids();
18582     }
18583
18584     // A backup agent has just come up
18585     public void backupAgentCreated(String agentPackageName, IBinder agent) {
18586         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18587                 + " = " + agent);
18588
18589         synchronized(this) {
18590             if (!agentPackageName.equals(mBackupAppName)) {
18591                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18592                 return;
18593             }
18594         }
18595
18596         long oldIdent = Binder.clearCallingIdentity();
18597         try {
18598             IBackupManager bm = IBackupManager.Stub.asInterface(
18599                     ServiceManager.getService(Context.BACKUP_SERVICE));
18600             bm.agentConnected(agentPackageName, agent);
18601         } catch (RemoteException e) {
18602             // can't happen; the backup manager service is local
18603         } catch (Exception e) {
18604             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18605             e.printStackTrace();
18606         } finally {
18607             Binder.restoreCallingIdentity(oldIdent);
18608         }
18609     }
18610
18611     // done with this agent
18612     public void unbindBackupAgent(ApplicationInfo appInfo) {
18613         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18614         if (appInfo == null) {
18615             Slog.w(TAG, "unbind backup agent for null app");
18616             return;
18617         }
18618
18619         int oldBackupUid;
18620
18621         synchronized(this) {
18622             try {
18623                 if (mBackupAppName == null) {
18624                     Slog.w(TAG, "Unbinding backup agent with no active backup");
18625                     return;
18626                 }
18627
18628                 if (!mBackupAppName.equals(appInfo.packageName)) {
18629                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18630                     return;
18631                 }
18632
18633                 // Not backing this app up any more; reset its OOM adjustment
18634                 final ProcessRecord proc = mBackupTarget.app;
18635                 updateOomAdjLocked(proc, true);
18636                 proc.inFullBackup = false;
18637
18638                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18639
18640                 // If the app crashed during backup, 'thread' will be null here
18641                 if (proc.thread != null) {
18642                     try {
18643                         proc.thread.scheduleDestroyBackupAgent(appInfo,
18644                                 compatibilityInfoForPackageLocked(appInfo));
18645                     } catch (Exception e) {
18646                         Slog.e(TAG, "Exception when unbinding backup agent:");
18647                         e.printStackTrace();
18648                     }
18649                 }
18650             } finally {
18651                 mBackupTarget = null;
18652                 mBackupAppName = null;
18653             }
18654         }
18655
18656         if (oldBackupUid != -1) {
18657             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18658             js.removeBackingUpUid(oldBackupUid);
18659         }
18660     }
18661
18662     // =========================================================
18663     // BROADCASTS
18664     // =========================================================
18665
18666     private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18667         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18668             return false;
18669         }
18670         // Easy case -- we have the app's ProcessRecord.
18671         if (record != null) {
18672             return record.info.isInstantApp();
18673         }
18674         // Otherwise check with PackageManager.
18675         if (callerPackage == null) {
18676             Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18677             throw new IllegalArgumentException("Calling application did not provide package name");
18678         }
18679         mAppOpsService.checkPackage(uid, callerPackage);
18680         try {
18681             IPackageManager pm = AppGlobals.getPackageManager();
18682             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18683         } catch (RemoteException e) {
18684             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18685             return true;
18686         }
18687     }
18688
18689     boolean isPendingBroadcastProcessLocked(int pid) {
18690         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18691                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18692     }
18693
18694     void skipPendingBroadcastLocked(int pid) {
18695             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18696             for (BroadcastQueue queue : mBroadcastQueues) {
18697                 queue.skipPendingBroadcastLocked(pid);
18698             }
18699     }
18700
18701     // The app just attached; send any pending broadcasts that it should receive
18702     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18703         boolean didSomething = false;
18704         for (BroadcastQueue queue : mBroadcastQueues) {
18705             didSomething |= queue.sendPendingBroadcastsLocked(app);
18706         }
18707         return didSomething;
18708     }
18709
18710     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18711             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18712             int flags) {
18713         enforceNotIsolatedCaller("registerReceiver");
18714         ArrayList<Intent> stickyIntents = null;
18715         ProcessRecord callerApp = null;
18716         final boolean visibleToInstantApps
18717                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18718         int callingUid;
18719         int callingPid;
18720         boolean instantApp;
18721         synchronized(this) {
18722             if (caller != null) {
18723                 callerApp = getRecordForAppLocked(caller);
18724                 if (callerApp == null) {
18725                     throw new SecurityException(
18726                             "Unable to find app for caller " + caller
18727                             + " (pid=" + Binder.getCallingPid()
18728                             + ") when registering receiver " + receiver);
18729                 }
18730                 if (callerApp.info.uid != SYSTEM_UID &&
18731                         !callerApp.pkgList.containsKey(callerPackage) &&
18732                         !"android".equals(callerPackage)) {
18733                     throw new SecurityException("Given caller package " + callerPackage
18734                             + " is not running in process " + callerApp);
18735                 }
18736                 callingUid = callerApp.info.uid;
18737                 callingPid = callerApp.pid;
18738             } else {
18739                 callerPackage = null;
18740                 callingUid = Binder.getCallingUid();
18741                 callingPid = Binder.getCallingPid();
18742             }
18743
18744             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18745             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18746                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18747
18748             Iterator<String> actions = filter.actionsIterator();
18749             if (actions == null) {
18750                 ArrayList<String> noAction = new ArrayList<String>(1);
18751                 noAction.add(null);
18752                 actions = noAction.iterator();
18753             }
18754
18755             // Collect stickies of users
18756             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18757             while (actions.hasNext()) {
18758                 String action = actions.next();
18759                 for (int id : userIds) {
18760                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18761                     if (stickies != null) {
18762                         ArrayList<Intent> intents = stickies.get(action);
18763                         if (intents != null) {
18764                             if (stickyIntents == null) {
18765                                 stickyIntents = new ArrayList<Intent>();
18766                             }
18767                             stickyIntents.addAll(intents);
18768                         }
18769                     }
18770                 }
18771             }
18772         }
18773
18774         ArrayList<Intent> allSticky = null;
18775         if (stickyIntents != null) {
18776             final ContentResolver resolver = mContext.getContentResolver();
18777             // Look for any matching sticky broadcasts...
18778             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18779                 Intent intent = stickyIntents.get(i);
18780                 // Don't provided intents that aren't available to instant apps.
18781                 if (instantApp &&
18782                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18783                     continue;
18784                 }
18785                 // If intent has scheme "content", it will need to acccess
18786                 // provider that needs to lock mProviderMap in ActivityThread
18787                 // and also it may need to wait application response, so we
18788                 // cannot lock ActivityManagerService here.
18789                 if (filter.match(resolver, intent, true, TAG) >= 0) {
18790                     if (allSticky == null) {
18791                         allSticky = new ArrayList<Intent>();
18792                     }
18793                     allSticky.add(intent);
18794                 }
18795             }
18796         }
18797
18798         // The first sticky in the list is returned directly back to the client.
18799         Intent sticky = allSticky != null ? allSticky.get(0) : null;
18800         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18801         if (receiver == null) {
18802             return sticky;
18803         }
18804
18805         synchronized (this) {
18806             if (callerApp != null && (callerApp.thread == null
18807                     || callerApp.thread.asBinder() != caller.asBinder())) {
18808                 // Original caller already died
18809                 return null;
18810             }
18811             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18812             if (rl == null) {
18813                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18814                         userId, receiver);
18815                 if (rl.app != null) {
18816                     rl.app.receivers.add(rl);
18817                 } else {
18818                     try {
18819                         receiver.asBinder().linkToDeath(rl, 0);
18820                     } catch (RemoteException e) {
18821                         return sticky;
18822                     }
18823                     rl.linkedToDeath = true;
18824                 }
18825                 mRegisteredReceivers.put(receiver.asBinder(), rl);
18826             } else if (rl.uid != callingUid) {
18827                 throw new IllegalArgumentException(
18828                         "Receiver requested to register for uid " + callingUid
18829                         + " was previously registered for uid " + rl.uid
18830                         + " callerPackage is " + callerPackage);
18831             } else if (rl.pid != callingPid) {
18832                 throw new IllegalArgumentException(
18833                         "Receiver requested to register for pid " + callingPid
18834                         + " was previously registered for pid " + rl.pid
18835                         + " callerPackage is " + callerPackage);
18836             } else if (rl.userId != userId) {
18837                 throw new IllegalArgumentException(
18838                         "Receiver requested to register for user " + userId
18839                         + " was previously registered for user " + rl.userId
18840                         + " callerPackage is " + callerPackage);
18841             }
18842             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18843                     permission, callingUid, userId, instantApp, visibleToInstantApps);
18844             rl.add(bf);
18845             if (!bf.debugCheck()) {
18846                 Slog.w(TAG, "==> For Dynamic broadcast");
18847             }
18848             mReceiverResolver.addFilter(bf);
18849
18850             // Enqueue broadcasts for all existing stickies that match
18851             // this filter.
18852             if (allSticky != null) {
18853                 ArrayList receivers = new ArrayList();
18854                 receivers.add(bf);
18855
18856                 final int stickyCount = allSticky.size();
18857                 for (int i = 0; i < stickyCount; i++) {
18858                     Intent intent = allSticky.get(i);
18859                     BroadcastQueue queue = broadcastQueueForIntent(intent);
18860                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18861                             null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18862                             null, 0, null, null, false, true, true, -1);
18863                     queue.enqueueParallelBroadcastLocked(r);
18864                     queue.scheduleBroadcastsLocked();
18865                 }
18866             }
18867
18868             return sticky;
18869         }
18870     }
18871
18872     public void unregisterReceiver(IIntentReceiver receiver) {
18873         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18874
18875         final long origId = Binder.clearCallingIdentity();
18876         try {
18877             boolean doTrim = false;
18878
18879             synchronized(this) {
18880                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18881                 if (rl != null) {
18882                     final BroadcastRecord r = rl.curBroadcast;
18883                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18884                         final boolean doNext = r.queue.finishReceiverLocked(
18885                                 r, r.resultCode, r.resultData, r.resultExtras,
18886                                 r.resultAbort, false);
18887                         if (doNext) {
18888                             doTrim = true;
18889                             r.queue.processNextBroadcast(false);
18890                         }
18891                     }
18892
18893                     if (rl.app != null) {
18894                         rl.app.receivers.remove(rl);
18895                     }
18896                     removeReceiverLocked(rl);
18897                     if (rl.linkedToDeath) {
18898                         rl.linkedToDeath = false;
18899                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
18900                     }
18901                 }
18902             }
18903
18904             // If we actually concluded any broadcasts, we might now be able
18905             // to trim the recipients' apps from our working set
18906             if (doTrim) {
18907                 trimApplications();
18908                 return;
18909             }
18910
18911         } finally {
18912             Binder.restoreCallingIdentity(origId);
18913         }
18914     }
18915
18916     void removeReceiverLocked(ReceiverList rl) {
18917         mRegisteredReceivers.remove(rl.receiver.asBinder());
18918         for (int i = rl.size() - 1; i >= 0; i--) {
18919             mReceiverResolver.removeFilter(rl.get(i));
18920         }
18921     }
18922
18923     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18924         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18925             ProcessRecord r = mLruProcesses.get(i);
18926             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18927                 try {
18928                     r.thread.dispatchPackageBroadcast(cmd, packages);
18929                 } catch (RemoteException ex) {
18930                 }
18931             }
18932         }
18933     }
18934
18935     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18936             int callingUid, int[] users) {
18937         // TODO: come back and remove this assumption to triage all broadcasts
18938         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18939
18940         List<ResolveInfo> receivers = null;
18941         try {
18942             HashSet<ComponentName> singleUserReceivers = null;
18943             boolean scannedFirstReceivers = false;
18944             for (int user : users) {
18945                 // Skip users that have Shell restrictions, with exception of always permitted
18946                 // Shell broadcasts
18947                 if (callingUid == SHELL_UID
18948                         && mUserController.hasUserRestriction(
18949                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18950                         && !isPermittedShellBroadcast(intent)) {
18951                     continue;
18952                 }
18953                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18954                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18955                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18956                     // If this is not the system user, we need to check for
18957                     // any receivers that should be filtered out.
18958                     for (int i=0; i<newReceivers.size(); i++) {
18959                         ResolveInfo ri = newReceivers.get(i);
18960                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18961                             newReceivers.remove(i);
18962                             i--;
18963                         }
18964                     }
18965                 }
18966                 if (newReceivers != null && newReceivers.size() == 0) {
18967                     newReceivers = null;
18968                 }
18969                 if (receivers == null) {
18970                     receivers = newReceivers;
18971                 } else if (newReceivers != null) {
18972                     // We need to concatenate the additional receivers
18973                     // found with what we have do far.  This would be easy,
18974                     // but we also need to de-dup any receivers that are
18975                     // singleUser.
18976                     if (!scannedFirstReceivers) {
18977                         // Collect any single user receivers we had already retrieved.
18978                         scannedFirstReceivers = true;
18979                         for (int i=0; i<receivers.size(); i++) {
18980                             ResolveInfo ri = receivers.get(i);
18981                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18982                                 ComponentName cn = new ComponentName(
18983                                         ri.activityInfo.packageName, ri.activityInfo.name);
18984                                 if (singleUserReceivers == null) {
18985                                     singleUserReceivers = new HashSet<ComponentName>();
18986                                 }
18987                                 singleUserReceivers.add(cn);
18988                             }
18989                         }
18990                     }
18991                     // Add the new results to the existing results, tracking
18992                     // and de-dupping single user receivers.
18993                     for (int i=0; i<newReceivers.size(); i++) {
18994                         ResolveInfo ri = newReceivers.get(i);
18995                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18996                             ComponentName cn = new ComponentName(
18997                                     ri.activityInfo.packageName, ri.activityInfo.name);
18998                             if (singleUserReceivers == null) {
18999                                 singleUserReceivers = new HashSet<ComponentName>();
19000                             }
19001                             if (!singleUserReceivers.contains(cn)) {
19002                                 singleUserReceivers.add(cn);
19003                                 receivers.add(ri);
19004                             }
19005                         } else {
19006                             receivers.add(ri);
19007                         }
19008                     }
19009                 }
19010             }
19011         } catch (RemoteException ex) {
19012             // pm is in same process, this will never happen.
19013         }
19014         return receivers;
19015     }
19016
19017     private boolean isPermittedShellBroadcast(Intent intent) {
19018         // remote bugreport should always be allowed to be taken
19019         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19020     }
19021
19022     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19023             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19024         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19025             // Don't yell about broadcasts sent via shell
19026             return;
19027         }
19028
19029         final String action = intent.getAction();
19030         if (isProtectedBroadcast
19031                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19032                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19033                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19034                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19035                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19036                 || Intent.ACTION_MASTER_CLEAR.equals(action)
19037                 || Intent.ACTION_FACTORY_RESET.equals(action)
19038                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19039                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19040                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19041                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19042                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19043                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19044                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19045             // Broadcast is either protected, or it's a public action that
19046             // we've relaxed, so it's fine for system internals to send.
19047             return;
19048         }
19049
19050         // This broadcast may be a problem...  but there are often system components that
19051         // want to send an internal broadcast to themselves, which is annoying to have to
19052         // explicitly list each action as a protected broadcast, so we will check for that
19053         // one safe case and allow it: an explicit broadcast, only being received by something
19054         // that has protected itself.
19055         if (receivers != null && receivers.size() > 0
19056                 && (intent.getPackage() != null || intent.getComponent() != null)) {
19057             boolean allProtected = true;
19058             for (int i = receivers.size()-1; i >= 0; i--) {
19059                 Object target = receivers.get(i);
19060                 if (target instanceof ResolveInfo) {
19061                     ResolveInfo ri = (ResolveInfo)target;
19062                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19063                         allProtected = false;
19064                         break;
19065                     }
19066                 } else {
19067                     BroadcastFilter bf = (BroadcastFilter)target;
19068                     if (bf.requiredPermission == null) {
19069                         allProtected = false;
19070                         break;
19071                     }
19072                 }
19073             }
19074             if (allProtected) {
19075                 // All safe!
19076                 return;
19077             }
19078         }
19079
19080         // The vast majority of broadcasts sent from system internals
19081         // should be protected to avoid security holes, so yell loudly
19082         // to ensure we examine these cases.
19083         if (callerApp != null) {
19084             Log.wtf(TAG, "Sending non-protected broadcast " + action
19085                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19086                     new Throwable());
19087         } else {
19088             Log.wtf(TAG, "Sending non-protected broadcast " + action
19089                             + " from system uid " + UserHandle.formatUid(callingUid)
19090                             + " pkg " + callerPackage,
19091                     new Throwable());
19092         }
19093     }
19094
19095     final int broadcastIntentLocked(ProcessRecord callerApp,
19096             String callerPackage, Intent intent, String resolvedType,
19097             IIntentReceiver resultTo, int resultCode, String resultData,
19098             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19099             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19100         intent = new Intent(intent);
19101
19102         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19103         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19104         if (callerInstantApp) {
19105             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19106         }
19107
19108         // By default broadcasts do not go to stopped apps.
19109         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19110
19111         // If we have not finished booting, don't allow this to launch new processes.
19112         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19113             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19114         }
19115
19116         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19117                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19118                 + " ordered=" + ordered + " userid=" + userId);
19119         if ((resultTo != null) && !ordered) {
19120             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19121         }
19122
19123         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19124                 ALLOW_NON_FULL, "broadcast", callerPackage);
19125
19126         // Make sure that the user who is receiving this broadcast is running.
19127         // If not, we will just skip it. Make an exception for shutdown broadcasts
19128         // and upgrade steps.
19129
19130         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19131             if ((callingUid != SYSTEM_UID
19132                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19133                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19134                 Slog.w(TAG, "Skipping broadcast of " + intent
19135                         + ": user " + userId + " is stopped");
19136                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19137             }
19138         }
19139
19140         BroadcastOptions brOptions = null;
19141         if (bOptions != null) {
19142             brOptions = new BroadcastOptions(bOptions);
19143             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19144                 // See if the caller is allowed to do this.  Note we are checking against
19145                 // the actual real caller (not whoever provided the operation as say a
19146                 // PendingIntent), because that who is actually supplied the arguments.
19147                 if (checkComponentPermission(
19148                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19149                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19150                         != PackageManager.PERMISSION_GRANTED) {
19151                     String msg = "Permission Denial: " + intent.getAction()
19152                             + " broadcast from " + callerPackage + " (pid=" + callingPid
19153                             + ", uid=" + callingUid + ")"
19154                             + " requires "
19155                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19156                     Slog.w(TAG, msg);
19157                     throw new SecurityException(msg);
19158                 }
19159             }
19160         }
19161
19162         // Verify that protected broadcasts are only being sent by system code,
19163         // and that system code is only sending protected broadcasts.
19164         final String action = intent.getAction();
19165         final boolean isProtectedBroadcast;
19166         try {
19167             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19168         } catch (RemoteException e) {
19169             Slog.w(TAG, "Remote exception", e);
19170             return ActivityManager.BROADCAST_SUCCESS;
19171         }
19172
19173         final boolean isCallerSystem;
19174         switch (UserHandle.getAppId(callingUid)) {
19175             case ROOT_UID:
19176             case SYSTEM_UID:
19177             case PHONE_UID:
19178             case BLUETOOTH_UID:
19179             case NFC_UID:
19180                 isCallerSystem = true;
19181                 break;
19182             default:
19183                 isCallerSystem = (callerApp != null) && callerApp.persistent;
19184                 break;
19185         }
19186
19187         // First line security check before anything else: stop non-system apps from
19188         // sending protected broadcasts.
19189         if (!isCallerSystem) {
19190             if (isProtectedBroadcast) {
19191                 String msg = "Permission Denial: not allowed to send broadcast "
19192                         + action + " from pid="
19193                         + callingPid + ", uid=" + callingUid;
19194                 Slog.w(TAG, msg);
19195                 throw new SecurityException(msg);
19196
19197             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19198                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19199                 // Special case for compatibility: we don't want apps to send this,
19200                 // but historically it has not been protected and apps may be using it
19201                 // to poke their own app widget.  So, instead of making it protected,
19202                 // just limit it to the caller.
19203                 if (callerPackage == null) {
19204                     String msg = "Permission Denial: not allowed to send broadcast "
19205                             + action + " from unknown caller.";
19206                     Slog.w(TAG, msg);
19207                     throw new SecurityException(msg);
19208                 } else if (intent.getComponent() != null) {
19209                     // They are good enough to send to an explicit component...  verify
19210                     // it is being sent to the calling app.
19211                     if (!intent.getComponent().getPackageName().equals(
19212                             callerPackage)) {
19213                         String msg = "Permission Denial: not allowed to send broadcast "
19214                                 + action + " to "
19215                                 + intent.getComponent().getPackageName() + " from "
19216                                 + callerPackage;
19217                         Slog.w(TAG, msg);
19218                         throw new SecurityException(msg);
19219                     }
19220                 } else {
19221                     // Limit broadcast to their own package.
19222                     intent.setPackage(callerPackage);
19223                 }
19224             }
19225         }
19226
19227         if (action != null) {
19228             if (getBackgroundLaunchBroadcasts().contains(action)) {
19229                 if (DEBUG_BACKGROUND_CHECK) {
19230                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19231                 }
19232                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19233             }
19234
19235             switch (action) {
19236                 case Intent.ACTION_UID_REMOVED:
19237                 case Intent.ACTION_PACKAGE_REMOVED:
19238                 case Intent.ACTION_PACKAGE_CHANGED:
19239                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19240                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19241                 case Intent.ACTION_PACKAGES_SUSPENDED:
19242                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19243                     // Handle special intents: if this broadcast is from the package
19244                     // manager about a package being removed, we need to remove all of
19245                     // its activities from the history stack.
19246                     if (checkComponentPermission(
19247                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19248                             callingPid, callingUid, -1, true)
19249                             != PackageManager.PERMISSION_GRANTED) {
19250                         String msg = "Permission Denial: " + intent.getAction()
19251                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
19252                                 + ", uid=" + callingUid + ")"
19253                                 + " requires "
19254                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19255                         Slog.w(TAG, msg);
19256                         throw new SecurityException(msg);
19257                     }
19258                     switch (action) {
19259                         case Intent.ACTION_UID_REMOVED:
19260                             final int uid = getUidFromIntent(intent);
19261                             if (uid >= 0) {
19262                                 mBatteryStatsService.removeUid(uid);
19263                                 mAppOpsService.uidRemoved(uid);
19264                             }
19265                             break;
19266                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19267                             // If resources are unavailable just force stop all those packages
19268                             // and flush the attribute cache as well.
19269                             String list[] =
19270                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19271                             if (list != null && list.length > 0) {
19272                                 for (int i = 0; i < list.length; i++) {
19273                                     forceStopPackageLocked(list[i], -1, false, true, true,
19274                                             false, false, userId, "storage unmount");
19275                                 }
19276                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19277                                 sendPackageBroadcastLocked(
19278                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19279                                         list, userId);
19280                             }
19281                             break;
19282                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19283                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19284                             break;
19285                         case Intent.ACTION_PACKAGE_REMOVED:
19286                         case Intent.ACTION_PACKAGE_CHANGED:
19287                             Uri data = intent.getData();
19288                             String ssp;
19289                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19290                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19291                                 final boolean replacing =
19292                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19293                                 final boolean killProcess =
19294                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19295                                 final boolean fullUninstall = removed && !replacing;
19296                                 if (removed) {
19297                                     if (killProcess) {
19298                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
19299                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19300                                                 false, true, true, false, fullUninstall, userId,
19301                                                 removed ? "pkg removed" : "pkg changed");
19302                                     }
19303                                     final int cmd = killProcess
19304                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
19305                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19306                                     sendPackageBroadcastLocked(cmd,
19307                                             new String[] {ssp}, userId);
19308                                     if (fullUninstall) {
19309                                         mAppOpsService.packageRemoved(
19310                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19311
19312                                         // Remove all permissions granted from/to this package
19313                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
19314
19315                                         removeTasksByPackageNameLocked(ssp, userId);
19316
19317                                         mServices.forceStopPackageLocked(ssp, userId);
19318
19319                                         // Hide the "unsupported display" dialog if necessary.
19320                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19321                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19322                                             mUnsupportedDisplaySizeDialog.dismiss();
19323                                             mUnsupportedDisplaySizeDialog = null;
19324                                         }
19325                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
19326                                         mBatteryStatsService.notePackageUninstalled(ssp);
19327                                     }
19328                                 } else {
19329                                     if (killProcess) {
19330                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
19331                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19332                                                 userId, ProcessList.INVALID_ADJ,
19333                                                 false, true, true, false, "change " + ssp);
19334                                     }
19335                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19336                                             intent.getStringArrayExtra(
19337                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19338                                 }
19339                             }
19340                             break;
19341                         case Intent.ACTION_PACKAGES_SUSPENDED:
19342                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
19343                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19344                                     intent.getAction());
19345                             final String[] packageNames = intent.getStringArrayExtra(
19346                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
19347                             final int userHandle = intent.getIntExtra(
19348                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19349
19350                             synchronized(ActivityManagerService.this) {
19351                                 mRecentTasks.onPackagesSuspendedChanged(
19352                                         packageNames, suspended, userHandle);
19353                             }
19354                             break;
19355                     }
19356                     break;
19357                 case Intent.ACTION_PACKAGE_REPLACED:
19358                 {
19359                     final Uri data = intent.getData();
19360                     final String ssp;
19361                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19362                         ApplicationInfo aInfo = null;
19363                         try {
19364                             aInfo = AppGlobals.getPackageManager()
19365                                     .getApplicationInfo(ssp, 0 /*flags*/, userId);
19366                         } catch (RemoteException ignore) {}
19367                         if (aInfo == null) {
19368                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19369                                     + " ssp=" + ssp + " data=" + data);
19370                             return ActivityManager.BROADCAST_SUCCESS;
19371                         }
19372                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19373                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19374                                 new String[] {ssp}, userId);
19375                     }
19376                     break;
19377                 }
19378                 case Intent.ACTION_PACKAGE_ADDED:
19379                 {
19380                     // Special case for adding a package: by default turn on compatibility mode.
19381                     Uri data = intent.getData();
19382                     String ssp;
19383                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19384                         final boolean replacing =
19385                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19386                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19387
19388                         try {
19389                             ApplicationInfo ai = AppGlobals.getPackageManager().
19390                                     getApplicationInfo(ssp, 0, 0);
19391                             mBatteryStatsService.notePackageInstalled(ssp,
19392                                     ai != null ? ai.versionCode : 0);
19393                         } catch (RemoteException e) {
19394                         }
19395                     }
19396                     break;
19397                 }
19398                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19399                 {
19400                     Uri data = intent.getData();
19401                     String ssp;
19402                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19403                         // Hide the "unsupported display" dialog if necessary.
19404                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19405                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19406                             mUnsupportedDisplaySizeDialog.dismiss();
19407                             mUnsupportedDisplaySizeDialog = null;
19408                         }
19409                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
19410                     }
19411                     break;
19412                 }
19413                 case Intent.ACTION_TIMEZONE_CHANGED:
19414                     // If this is the time zone changed action, queue up a message that will reset
19415                     // the timezone of all currently running processes. This message will get
19416                     // queued up before the broadcast happens.
19417                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19418                     break;
19419                 case Intent.ACTION_TIME_CHANGED:
19420                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19421                     // the tri-state value it may contain and "unknown".
19422                     // For convenience we re-use the Intent extra values.
19423                     final int NO_EXTRA_VALUE_FOUND = -1;
19424                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19425                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19426                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
19427                     // Only send a message if the time preference is available.
19428                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19429                         Message updateTimePreferenceMsg =
19430                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19431                                         timeFormatPreferenceMsgValue, 0);
19432                         mHandler.sendMessage(updateTimePreferenceMsg);
19433                     }
19434                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19435                     synchronized (stats) {
19436                         stats.noteCurrentTimeChangedLocked();
19437                     }
19438                     break;
19439                 case Intent.ACTION_CLEAR_DNS_CACHE:
19440                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19441                     break;
19442                 case Proxy.PROXY_CHANGE_ACTION:
19443                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19444                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19445                     break;
19446                 case android.hardware.Camera.ACTION_NEW_PICTURE:
19447                 case android.hardware.Camera.ACTION_NEW_VIDEO:
19448                     // In N we just turned these off; in O we are turing them back on partly,
19449                     // only for registered receivers.  This will still address the main problem
19450                     // (a spam of apps waking up when a picture is taken putting significant
19451                     // memory pressure on the system at a bad point), while still allowing apps
19452                     // that are already actively running to know about this happening.
19453                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19454                     break;
19455                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19456                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19457                     break;
19458                 case "com.android.launcher.action.INSTALL_SHORTCUT":
19459                     // As of O, we no longer support this broadcasts, even for pre-O apps.
19460                     // Apps should now be using ShortcutManager.pinRequestShortcut().
19461                     Log.w(TAG, "Broadcast " + action
19462                             + " no longer supported. It will not be delivered.");
19463                     return ActivityManager.BROADCAST_SUCCESS;
19464             }
19465
19466             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19467                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19468                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19469                 final int uid = getUidFromIntent(intent);
19470                 if (uid != -1) {
19471                     final UidRecord uidRec = mActiveUids.get(uid);
19472                     if (uidRec != null) {
19473                         uidRec.updateHasInternetPermission();
19474                     }
19475                 }
19476             }
19477         }
19478
19479         // Add to the sticky list if requested.
19480         if (sticky) {
19481             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19482                     callingPid, callingUid)
19483                     != PackageManager.PERMISSION_GRANTED) {
19484                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19485                         + callingPid + ", uid=" + callingUid
19486                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19487                 Slog.w(TAG, msg);
19488                 throw new SecurityException(msg);
19489             }
19490             if (requiredPermissions != null && requiredPermissions.length > 0) {
19491                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19492                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
19493                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19494             }
19495             if (intent.getComponent() != null) {
19496                 throw new SecurityException(
19497                         "Sticky broadcasts can't target a specific component");
19498             }
19499             // We use userId directly here, since the "all" target is maintained
19500             // as a separate set of sticky broadcasts.
19501             if (userId != UserHandle.USER_ALL) {
19502                 // But first, if this is not a broadcast to all users, then
19503                 // make sure it doesn't conflict with an existing broadcast to
19504                 // all users.
19505                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19506                         UserHandle.USER_ALL);
19507                 if (stickies != null) {
19508                     ArrayList<Intent> list = stickies.get(intent.getAction());
19509                     if (list != null) {
19510                         int N = list.size();
19511                         int i;
19512                         for (i=0; i<N; i++) {
19513                             if (intent.filterEquals(list.get(i))) {
19514                                 throw new IllegalArgumentException(
19515                                         "Sticky broadcast " + intent + " for user "
19516                                         + userId + " conflicts with existing global broadcast");
19517                             }
19518                         }
19519                     }
19520                 }
19521             }
19522             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19523             if (stickies == null) {
19524                 stickies = new ArrayMap<>();
19525                 mStickyBroadcasts.put(userId, stickies);
19526             }
19527             ArrayList<Intent> list = stickies.get(intent.getAction());
19528             if (list == null) {
19529                 list = new ArrayList<>();
19530                 stickies.put(intent.getAction(), list);
19531             }
19532             final int stickiesCount = list.size();
19533             int i;
19534             for (i = 0; i < stickiesCount; i++) {
19535                 if (intent.filterEquals(list.get(i))) {
19536                     // This sticky already exists, replace it.
19537                     list.set(i, new Intent(intent));
19538                     break;
19539                 }
19540             }
19541             if (i >= stickiesCount) {
19542                 list.add(new Intent(intent));
19543             }
19544         }
19545
19546         int[] users;
19547         if (userId == UserHandle.USER_ALL) {
19548             // Caller wants broadcast to go to all started users.
19549             users = mUserController.getStartedUserArrayLocked();
19550         } else {
19551             // Caller wants broadcast to go to one specific user.
19552             users = new int[] {userId};
19553         }
19554
19555         // Figure out who all will receive this broadcast.
19556         List receivers = null;
19557         List<BroadcastFilter> registeredReceivers = null;
19558         // Need to resolve the intent to interested receivers...
19559         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19560                  == 0) {
19561             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19562         }
19563         if (intent.getComponent() == null) {
19564             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19565                 // Query one target user at a time, excluding shell-restricted users
19566                 for (int i = 0; i < users.length; i++) {
19567                     if (mUserController.hasUserRestriction(
19568                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19569                         continue;
19570                     }
19571                     List<BroadcastFilter> registeredReceiversForUser =
19572                             mReceiverResolver.queryIntent(intent,
19573                                     resolvedType, false /*defaultOnly*/, users[i]);
19574                     if (registeredReceivers == null) {
19575                         registeredReceivers = registeredReceiversForUser;
19576                     } else if (registeredReceiversForUser != null) {
19577                         registeredReceivers.addAll(registeredReceiversForUser);
19578                     }
19579                 }
19580             } else {
19581                 registeredReceivers = mReceiverResolver.queryIntent(intent,
19582                         resolvedType, false /*defaultOnly*/, userId);
19583             }
19584         }
19585
19586         final boolean replacePending =
19587                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19588
19589         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19590                 + " replacePending=" + replacePending);
19591
19592         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19593         if (!ordered && NR > 0) {
19594             // If we are not serializing this broadcast, then send the
19595             // registered receivers separately so they don't wait for the
19596             // components to be launched.
19597             if (isCallerSystem) {
19598                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19599                         isProtectedBroadcast, registeredReceivers);
19600             }
19601             final BroadcastQueue queue = broadcastQueueForIntent(intent);
19602             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19603                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19604                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19605                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19606             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19607             final boolean replaced = replacePending
19608                     && (queue.replaceParallelBroadcastLocked(r) != null);
19609             // Note: We assume resultTo is null for non-ordered broadcasts.
19610             if (!replaced) {
19611                 queue.enqueueParallelBroadcastLocked(r);
19612                 queue.scheduleBroadcastsLocked();
19613             }
19614             registeredReceivers = null;
19615             NR = 0;
19616         }
19617
19618         // Merge into one list.
19619         int ir = 0;
19620         if (receivers != null) {
19621             // A special case for PACKAGE_ADDED: do not allow the package
19622             // being added to see this broadcast.  This prevents them from
19623             // using this as a back door to get run as soon as they are
19624             // installed.  Maybe in the future we want to have a special install
19625             // broadcast or such for apps, but we'd like to deliberately make
19626             // this decision.
19627             String skipPackages[] = null;
19628             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19629                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19630                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19631                 Uri data = intent.getData();
19632                 if (data != null) {
19633                     String pkgName = data.getSchemeSpecificPart();
19634                     if (pkgName != null) {
19635                         skipPackages = new String[] { pkgName };
19636                     }
19637                 }
19638             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19639                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19640             }
19641             if (skipPackages != null && (skipPackages.length > 0)) {
19642                 for (String skipPackage : skipPackages) {
19643                     if (skipPackage != null) {
19644                         int NT = receivers.size();
19645                         for (int it=0; it<NT; it++) {
19646                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
19647                             if (curt.activityInfo.packageName.equals(skipPackage)) {
19648                                 receivers.remove(it);
19649                                 it--;
19650                                 NT--;
19651                             }
19652                         }
19653                     }
19654                 }
19655             }
19656
19657             int NT = receivers != null ? receivers.size() : 0;
19658             int it = 0;
19659             ResolveInfo curt = null;
19660             BroadcastFilter curr = null;
19661             while (it < NT && ir < NR) {
19662                 if (curt == null) {
19663                     curt = (ResolveInfo)receivers.get(it);
19664                 }
19665                 if (curr == null) {
19666                     curr = registeredReceivers.get(ir);
19667                 }
19668                 if (curr.getPriority() >= curt.priority) {
19669                     // Insert this broadcast record into the final list.
19670                     receivers.add(it, curr);
19671                     ir++;
19672                     curr = null;
19673                     it++;
19674                     NT++;
19675                 } else {
19676                     // Skip to the next ResolveInfo in the final list.
19677                     it++;
19678                     curt = null;
19679                 }
19680             }
19681         }
19682         while (ir < NR) {
19683             if (receivers == null) {
19684                 receivers = new ArrayList();
19685             }
19686             receivers.add(registeredReceivers.get(ir));
19687             ir++;
19688         }
19689
19690         if (isCallerSystem) {
19691             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19692                     isProtectedBroadcast, receivers);
19693         }
19694
19695         if ((receivers != null && receivers.size() > 0)
19696                 || resultTo != null) {
19697             BroadcastQueue queue = broadcastQueueForIntent(intent);
19698             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19699                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19700                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19701                     resultData, resultExtras, ordered, sticky, false, userId);
19702
19703             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19704                     + ": prev had " + queue.mOrderedBroadcasts.size());
19705             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19706                     "Enqueueing broadcast " + r.intent.getAction());
19707
19708             final BroadcastRecord oldRecord =
19709                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19710             if (oldRecord != null) {
19711                 // Replaced, fire the result-to receiver.
19712                 if (oldRecord.resultTo != null) {
19713                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19714                     try {
19715                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19716                                 oldRecord.intent,
19717                                 Activity.RESULT_CANCELED, null, null,
19718                                 false, false, oldRecord.userId);
19719                     } catch (RemoteException e) {
19720                         Slog.w(TAG, "Failure ["
19721                                 + queue.mQueueName + "] sending broadcast result of "
19722                                 + intent, e);
19723
19724                     }
19725                 }
19726             } else {
19727                 queue.enqueueOrderedBroadcastLocked(r);
19728                 queue.scheduleBroadcastsLocked();
19729             }
19730         } else {
19731             // There was nobody interested in the broadcast, but we still want to record
19732             // that it happened.
19733             if (intent.getComponent() == null && intent.getPackage() == null
19734                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19735                 // This was an implicit broadcast... let's record it for posterity.
19736                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19737             }
19738         }
19739
19740         return ActivityManager.BROADCAST_SUCCESS;
19741     }
19742
19743     /**
19744      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19745      */
19746     private int getUidFromIntent(Intent intent) {
19747         if (intent == null) {
19748             return -1;
19749         }
19750         final Bundle intentExtras = intent.getExtras();
19751         return intent.hasExtra(Intent.EXTRA_UID)
19752                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19753     }
19754
19755     final void rotateBroadcastStatsIfNeededLocked() {
19756         final long now = SystemClock.elapsedRealtime();
19757         if (mCurBroadcastStats == null ||
19758                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19759             mLastBroadcastStats = mCurBroadcastStats;
19760             if (mLastBroadcastStats != null) {
19761                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19762                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19763             }
19764             mCurBroadcastStats = new BroadcastStats();
19765         }
19766     }
19767
19768     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19769             int skipCount, long dispatchTime) {
19770         rotateBroadcastStatsIfNeededLocked();
19771         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19772     }
19773
19774     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19775         rotateBroadcastStatsIfNeededLocked();
19776         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19777     }
19778
19779     final Intent verifyBroadcastLocked(Intent intent) {
19780         // Refuse possible leaked file descriptors
19781         if (intent != null && intent.hasFileDescriptors() == true) {
19782             throw new IllegalArgumentException("File descriptors passed in Intent");
19783         }
19784
19785         int flags = intent.getFlags();
19786
19787         if (!mProcessesReady) {
19788             // if the caller really truly claims to know what they're doing, go
19789             // ahead and allow the broadcast without launching any receivers
19790             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19791                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19792             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19793                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19794                         + " before boot completion");
19795                 throw new IllegalStateException("Cannot broadcast before boot completed");
19796             }
19797         }
19798
19799         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19800             throw new IllegalArgumentException(
19801                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19802         }
19803
19804         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19805             switch (Binder.getCallingUid()) {
19806                 case ROOT_UID:
19807                 case SHELL_UID:
19808                     break;
19809                 default:
19810                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19811                             + Binder.getCallingUid());
19812                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19813                     break;
19814             }
19815         }
19816
19817         return intent;
19818     }
19819
19820     public final int broadcastIntent(IApplicationThread caller,
19821             Intent intent, String resolvedType, IIntentReceiver resultTo,
19822             int resultCode, String resultData, Bundle resultExtras,
19823             String[] requiredPermissions, int appOp, Bundle bOptions,
19824             boolean serialized, boolean sticky, int userId) {
19825         enforceNotIsolatedCaller("broadcastIntent");
19826         synchronized(this) {
19827             intent = verifyBroadcastLocked(intent);
19828
19829             final ProcessRecord callerApp = getRecordForAppLocked(caller);
19830             final int callingPid = Binder.getCallingPid();
19831             final int callingUid = Binder.getCallingUid();
19832             final long origId = Binder.clearCallingIdentity();
19833             int res = broadcastIntentLocked(callerApp,
19834                     callerApp != null ? callerApp.info.packageName : null,
19835                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19836                     requiredPermissions, appOp, bOptions, serialized, sticky,
19837                     callingPid, callingUid, userId);
19838             Binder.restoreCallingIdentity(origId);
19839             return res;
19840         }
19841     }
19842
19843
19844     int broadcastIntentInPackage(String packageName, int uid,
19845             Intent intent, String resolvedType, IIntentReceiver resultTo,
19846             int resultCode, String resultData, Bundle resultExtras,
19847             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19848             int userId) {
19849         synchronized(this) {
19850             intent = verifyBroadcastLocked(intent);
19851
19852             final long origId = Binder.clearCallingIdentity();
19853             String[] requiredPermissions = requiredPermission == null ? null
19854                     : new String[] {requiredPermission};
19855             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19856                     resultTo, resultCode, resultData, resultExtras,
19857                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19858                     sticky, -1, uid, userId);
19859             Binder.restoreCallingIdentity(origId);
19860             return res;
19861         }
19862     }
19863
19864     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19865         // Refuse possible leaked file descriptors
19866         if (intent != null && intent.hasFileDescriptors() == true) {
19867             throw new IllegalArgumentException("File descriptors passed in Intent");
19868         }
19869
19870         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19871                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19872
19873         synchronized(this) {
19874             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19875                     != PackageManager.PERMISSION_GRANTED) {
19876                 String msg = "Permission Denial: unbroadcastIntent() from pid="
19877                         + Binder.getCallingPid()
19878                         + ", uid=" + Binder.getCallingUid()
19879                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19880                 Slog.w(TAG, msg);
19881                 throw new SecurityException(msg);
19882             }
19883             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19884             if (stickies != null) {
19885                 ArrayList<Intent> list = stickies.get(intent.getAction());
19886                 if (list != null) {
19887                     int N = list.size();
19888                     int i;
19889                     for (i=0; i<N; i++) {
19890                         if (intent.filterEquals(list.get(i))) {
19891                             list.remove(i);
19892                             break;
19893                         }
19894                     }
19895                     if (list.size() <= 0) {
19896                         stickies.remove(intent.getAction());
19897                     }
19898                 }
19899                 if (stickies.size() <= 0) {
19900                     mStickyBroadcasts.remove(userId);
19901                 }
19902             }
19903         }
19904     }
19905
19906     void backgroundServicesFinishedLocked(int userId) {
19907         for (BroadcastQueue queue : mBroadcastQueues) {
19908             queue.backgroundServicesFinishedLocked(userId);
19909         }
19910     }
19911
19912     public void finishReceiver(IBinder who, int resultCode, String resultData,
19913             Bundle resultExtras, boolean resultAbort, int flags) {
19914         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19915
19916         // Refuse possible leaked file descriptors
19917         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19918             throw new IllegalArgumentException("File descriptors passed in Bundle");
19919         }
19920
19921         final long origId = Binder.clearCallingIdentity();
19922         try {
19923             boolean doNext = false;
19924             BroadcastRecord r;
19925
19926             synchronized(this) {
19927                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19928                         ? mFgBroadcastQueue : mBgBroadcastQueue;
19929                 r = queue.getMatchingOrderedReceiver(who);
19930                 if (r != null) {
19931                     doNext = r.queue.finishReceiverLocked(r, resultCode,
19932                         resultData, resultExtras, resultAbort, true);
19933                 }
19934             }
19935
19936             if (doNext) {
19937                 r.queue.processNextBroadcast(false);
19938             }
19939             trimApplications();
19940         } finally {
19941             Binder.restoreCallingIdentity(origId);
19942         }
19943     }
19944
19945     // =========================================================
19946     // INSTRUMENTATION
19947     // =========================================================
19948
19949     public boolean startInstrumentation(ComponentName className,
19950             String profileFile, int flags, Bundle arguments,
19951             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19952             int userId, String abiOverride) {
19953         enforceNotIsolatedCaller("startInstrumentation");
19954         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19955                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19956         // Refuse possible leaked file descriptors
19957         if (arguments != null && arguments.hasFileDescriptors()) {
19958             throw new IllegalArgumentException("File descriptors passed in Bundle");
19959         }
19960
19961         synchronized(this) {
19962             InstrumentationInfo ii = null;
19963             ApplicationInfo ai = null;
19964             try {
19965                 ii = mContext.getPackageManager().getInstrumentationInfo(
19966                     className, STOCK_PM_FLAGS);
19967                 ai = AppGlobals.getPackageManager().getApplicationInfo(
19968                         ii.targetPackage, STOCK_PM_FLAGS, userId);
19969             } catch (PackageManager.NameNotFoundException e) {
19970             } catch (RemoteException e) {
19971             }
19972             if (ii == null) {
19973                 reportStartInstrumentationFailureLocked(watcher, className,
19974                         "Unable to find instrumentation info for: " + className);
19975                 return false;
19976             }
19977             if (ai == null) {
19978                 reportStartInstrumentationFailureLocked(watcher, className,
19979                         "Unable to find instrumentation target package: " + ii.targetPackage);
19980                 return false;
19981             }
19982             if (!ai.hasCode()) {
19983                 reportStartInstrumentationFailureLocked(watcher, className,
19984                         "Instrumentation target has no code: " + ii.targetPackage);
19985                 return false;
19986             }
19987
19988             int match = mContext.getPackageManager().checkSignatures(
19989                     ii.targetPackage, ii.packageName);
19990             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19991                 String msg = "Permission Denial: starting instrumentation "
19992                         + className + " from pid="
19993                         + Binder.getCallingPid()
19994                         + ", uid=" + Binder.getCallingPid()
19995                         + " not allowed because package " + ii.packageName
19996                         + " does not have a signature matching the target "
19997                         + ii.targetPackage;
19998                 reportStartInstrumentationFailureLocked(watcher, className, msg);
19999                 throw new SecurityException(msg);
20000             }
20001
20002             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20003             activeInstr.mClass = className;
20004             String defProcess = ai.processName;;
20005             if (ii.targetProcesses == null) {
20006                 activeInstr.mTargetProcesses = new String[]{ai.processName};
20007             } else if (ii.targetProcesses.equals("*")) {
20008                 activeInstr.mTargetProcesses = new String[0];
20009             } else {
20010                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20011                 defProcess = activeInstr.mTargetProcesses[0];
20012             }
20013             activeInstr.mTargetInfo = ai;
20014             activeInstr.mProfileFile = profileFile;
20015             activeInstr.mArguments = arguments;
20016             activeInstr.mWatcher = watcher;
20017             activeInstr.mUiAutomationConnection = uiAutomationConnection;
20018             activeInstr.mResultClass = className;
20019
20020             final long origId = Binder.clearCallingIdentity();
20021             // Instrumentation can kill and relaunch even persistent processes
20022             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20023                     "start instr");
20024             ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20025             app.instr = activeInstr;
20026             activeInstr.mFinished = false;
20027             activeInstr.mRunningProcesses.add(app);
20028             if (!mActiveInstrumentation.contains(activeInstr)) {
20029                 mActiveInstrumentation.add(activeInstr);
20030             }
20031             Binder.restoreCallingIdentity(origId);
20032         }
20033
20034         return true;
20035     }
20036
20037     /**
20038      * Report errors that occur while attempting to start Instrumentation.  Always writes the
20039      * error to the logs, but if somebody is watching, send the report there too.  This enables
20040      * the "am" command to report errors with more information.
20041      *
20042      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
20043      * @param cn The component name of the instrumentation.
20044      * @param report The error report.
20045      */
20046     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20047             ComponentName cn, String report) {
20048         Slog.w(TAG, report);
20049         if (watcher != null) {
20050             Bundle results = new Bundle();
20051             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20052             results.putString("Error", report);
20053             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20054         }
20055     }
20056
20057     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20058         if (app.instr == null) {
20059             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20060             return;
20061         }
20062
20063         if (!app.instr.mFinished && results != null) {
20064             if (app.instr.mCurResults == null) {
20065                 app.instr.mCurResults = new Bundle(results);
20066             } else {
20067                 app.instr.mCurResults.putAll(results);
20068             }
20069         }
20070     }
20071
20072     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20073         int userId = UserHandle.getCallingUserId();
20074         // Refuse possible leaked file descriptors
20075         if (results != null && results.hasFileDescriptors()) {
20076             throw new IllegalArgumentException("File descriptors passed in Intent");
20077         }
20078
20079         synchronized(this) {
20080             ProcessRecord app = getRecordForAppLocked(target);
20081             if (app == null) {
20082                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20083                 return;
20084             }
20085             final long origId = Binder.clearCallingIdentity();
20086             addInstrumentationResultsLocked(app, results);
20087             Binder.restoreCallingIdentity(origId);
20088         }
20089     }
20090
20091     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20092         if (app.instr == null) {
20093             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20094             return;
20095         }
20096
20097         if (!app.instr.mFinished) {
20098             if (app.instr.mWatcher != null) {
20099                 Bundle finalResults = app.instr.mCurResults;
20100                 if (finalResults != null) {
20101                     if (app.instr.mCurResults != null && results != null) {
20102                         finalResults.putAll(results);
20103                     }
20104                 } else {
20105                     finalResults = results;
20106                 }
20107                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20108                         app.instr.mClass, resultCode, finalResults);
20109             }
20110
20111             // Can't call out of the system process with a lock held, so post a message.
20112             if (app.instr.mUiAutomationConnection != null) {
20113                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20114                         app.instr.mUiAutomationConnection).sendToTarget();
20115             }
20116             app.instr.mFinished = true;
20117         }
20118
20119         app.instr.removeProcess(app);
20120         app.instr = null;
20121
20122         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20123                 "finished inst");
20124     }
20125
20126     public void finishInstrumentation(IApplicationThread target,
20127             int resultCode, Bundle results) {
20128         int userId = UserHandle.getCallingUserId();
20129         // Refuse possible leaked file descriptors
20130         if (results != null && results.hasFileDescriptors()) {
20131             throw new IllegalArgumentException("File descriptors passed in Intent");
20132         }
20133
20134         synchronized(this) {
20135             ProcessRecord app = getRecordForAppLocked(target);
20136             if (app == null) {
20137                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20138                 return;
20139             }
20140             final long origId = Binder.clearCallingIdentity();
20141             finishInstrumentationLocked(app, resultCode, results);
20142             Binder.restoreCallingIdentity(origId);
20143         }
20144     }
20145
20146     // =========================================================
20147     // CONFIGURATION
20148     // =========================================================
20149
20150     public ConfigurationInfo getDeviceConfigurationInfo() {
20151         ConfigurationInfo config = new ConfigurationInfo();
20152         synchronized (this) {
20153             final Configuration globalConfig = getGlobalConfiguration();
20154             config.reqTouchScreen = globalConfig.touchscreen;
20155             config.reqKeyboardType = globalConfig.keyboard;
20156             config.reqNavigation = globalConfig.navigation;
20157             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20158                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20159                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20160             }
20161             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20162                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20163                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20164             }
20165             config.reqGlEsVersion = GL_ES_VERSION;
20166         }
20167         return config;
20168     }
20169
20170     ActivityStack getFocusedStack() {
20171         return mStackSupervisor.getFocusedStack();
20172     }
20173
20174     @Override
20175     public int getFocusedStackId() throws RemoteException {
20176         ActivityStack focusedStack = getFocusedStack();
20177         if (focusedStack != null) {
20178             return focusedStack.getStackId();
20179         }
20180         return -1;
20181     }
20182
20183     public Configuration getConfiguration() {
20184         Configuration ci;
20185         synchronized(this) {
20186             ci = new Configuration(getGlobalConfiguration());
20187             ci.userSetLocale = false;
20188         }
20189         return ci;
20190     }
20191
20192     @Override
20193     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20194         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20195         synchronized (this) {
20196             mSuppressResizeConfigChanges = suppress;
20197         }
20198     }
20199
20200     /**
20201      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20202      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20203      *       activity and clearing the task at the same time.
20204      */
20205     @Override
20206     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20207         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20208         if (StackId.isHomeOrRecentsStack(fromStackId)) {
20209             throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20210         }
20211         synchronized (this) {
20212             final long origId = Binder.clearCallingIdentity();
20213             try {
20214                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20215             } finally {
20216                 Binder.restoreCallingIdentity(origId);
20217             }
20218         }
20219     }
20220
20221     @Override
20222     public void updatePersistentConfiguration(Configuration values) {
20223         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20224         enforceWriteSettingsPermission("updatePersistentConfiguration()");
20225         if (values == null) {
20226             throw new NullPointerException("Configuration must not be null");
20227         }
20228
20229         int userId = UserHandle.getCallingUserId();
20230
20231         synchronized(this) {
20232             updatePersistentConfigurationLocked(values, userId);
20233         }
20234     }
20235
20236     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20237         final long origId = Binder.clearCallingIdentity();
20238         try {
20239             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20240         } finally {
20241             Binder.restoreCallingIdentity(origId);
20242         }
20243     }
20244
20245     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20246         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20247                 FONT_SCALE, 1.0f, userId);
20248
20249         synchronized (this) {
20250             if (getGlobalConfiguration().fontScale == scaleFactor) {
20251                 return;
20252             }
20253
20254             final Configuration configuration
20255                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20256             configuration.fontScale = scaleFactor;
20257             updatePersistentConfigurationLocked(configuration, userId);
20258         }
20259     }
20260
20261     private void enforceWriteSettingsPermission(String func) {
20262         int uid = Binder.getCallingUid();
20263         if (uid == ROOT_UID) {
20264             return;
20265         }
20266
20267         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20268                 Settings.getPackageNameForUid(mContext, uid), false)) {
20269             return;
20270         }
20271
20272         String msg = "Permission Denial: " + func + " from pid="
20273                 + Binder.getCallingPid()
20274                 + ", uid=" + uid
20275                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20276         Slog.w(TAG, msg);
20277         throw new SecurityException(msg);
20278     }
20279
20280     @Override
20281     public boolean updateConfiguration(Configuration values) {
20282         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20283
20284         synchronized(this) {
20285             if (values == null && mWindowManager != null) {
20286                 // sentinel: fetch the current configuration from the window manager
20287                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20288             }
20289
20290             if (mWindowManager != null) {
20291                 // Update OOM levels based on display size.
20292                 mProcessList.applyDisplaySize(mWindowManager);
20293             }
20294
20295             final long origId = Binder.clearCallingIdentity();
20296             try {
20297                 if (values != null) {
20298                     Settings.System.clearConfiguration(values);
20299                 }
20300                 updateConfigurationLocked(values, null, false, false /* persistent */,
20301                         UserHandle.USER_NULL, false /* deferResume */,
20302                         mTmpUpdateConfigurationResult);
20303                 return mTmpUpdateConfigurationResult.changes != 0;
20304             } finally {
20305                 Binder.restoreCallingIdentity(origId);
20306             }
20307         }
20308     }
20309
20310     void updateUserConfigurationLocked() {
20311         final Configuration configuration = new Configuration(getGlobalConfiguration());
20312         final int currentUserId = mUserController.getCurrentUserIdLocked();
20313         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20314                 currentUserId, Settings.System.canWrite(mContext));
20315         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20316                 false /* persistent */, currentUserId, false /* deferResume */);
20317     }
20318
20319     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20320             boolean initLocale) {
20321         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20322     }
20323
20324     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20325             boolean initLocale, boolean deferResume) {
20326         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20327         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20328                 UserHandle.USER_NULL, deferResume);
20329     }
20330
20331     // To cache the list of supported system locales
20332     private String[] mSupportedSystemLocales = null;
20333
20334     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20335             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20336         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20337                 deferResume, null /* result */);
20338     }
20339
20340     /**
20341      * Do either or both things: (1) change the current configuration, and (2)
20342      * make sure the given activity is running with the (now) current
20343      * configuration.  Returns true if the activity has been left running, or
20344      * false if <var>starting</var> is being destroyed to match the new
20345      * configuration.
20346      *
20347      * @param userId is only used when persistent parameter is set to true to persist configuration
20348      *               for that particular user
20349      */
20350     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20351             boolean initLocale, boolean persistent, int userId, boolean deferResume,
20352             UpdateConfigurationResult result) {
20353         int changes = 0;
20354         boolean kept = true;
20355
20356         if (mWindowManager != null) {
20357             mWindowManager.deferSurfaceLayout();
20358         }
20359         try {
20360             if (values != null) {
20361                 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20362                         deferResume);
20363             }
20364
20365             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20366         } finally {
20367             if (mWindowManager != null) {
20368                 mWindowManager.continueSurfaceLayout();
20369             }
20370         }
20371
20372         if (result != null) {
20373             result.changes = changes;
20374             result.activityRelaunched = !kept;
20375         }
20376         return kept;
20377     }
20378
20379     /** Update default (global) configuration and notify listeners about changes. */
20380     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20381             boolean persistent, int userId, boolean deferResume) {
20382         mTempConfig.setTo(getGlobalConfiguration());
20383         final int changes = mTempConfig.updateFrom(values);
20384         if (changes == 0) {
20385             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20386             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20387             // performDisplayOverrideConfigUpdate in order to send the new display configuration
20388             // (even if there are no actual changes) to unfreeze the window.
20389             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20390             return 0;
20391         }
20392
20393         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20394                 "Updating global configuration to: " + values);
20395
20396         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20397
20398         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20399             final LocaleList locales = values.getLocales();
20400             int bestLocaleIndex = 0;
20401             if (locales.size() > 1) {
20402                 if (mSupportedSystemLocales == null) {
20403                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20404                 }
20405                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20406             }
20407             SystemProperties.set("persist.sys.locale",
20408                     locales.get(bestLocaleIndex).toLanguageTag());
20409             LocaleList.setDefault(locales, bestLocaleIndex);
20410             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20411                     locales.get(bestLocaleIndex)));
20412         }
20413
20414         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20415         mTempConfig.seq = mConfigurationSeq;
20416
20417         // Update stored global config and notify everyone about the change.
20418         mStackSupervisor.onConfigurationChanged(mTempConfig);
20419
20420         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20421         // TODO(multi-display): Update UsageEvents#Event to include displayId.
20422         mUsageStatsService.reportConfigurationChange(mTempConfig,
20423                 mUserController.getCurrentUserIdLocked());
20424
20425         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20426         mShowDialogs = shouldShowDialogs(mTempConfig);
20427
20428         AttributeCache ac = AttributeCache.instance();
20429         if (ac != null) {
20430             ac.updateConfiguration(mTempConfig);
20431         }
20432
20433         // Make sure all resources in our process are updated right now, so that anyone who is going
20434         // to retrieve resource values after we return will be sure to get the new ones. This is
20435         // especially important during boot, where the first config change needs to guarantee all
20436         // resources have that config before following boot code is executed.
20437         mSystemThread.applyConfigurationToResources(mTempConfig);
20438
20439         // We need another copy of global config because we're scheduling some calls instead of
20440         // running them in place. We need to be sure that object we send will be handled unchanged.
20441         final Configuration configCopy = new Configuration(mTempConfig);
20442         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20443             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20444             msg.obj = configCopy;
20445             msg.arg1 = userId;
20446             mHandler.sendMessage(msg);
20447         }
20448
20449         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20450             ProcessRecord app = mLruProcesses.get(i);
20451             try {
20452                 if (app.thread != null) {
20453                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20454                             + app.processName + " new config " + configCopy);
20455                     app.thread.scheduleConfigurationChanged(configCopy);
20456                 }
20457             } catch (Exception e) {
20458             }
20459         }
20460
20461         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20462         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20463                 | Intent.FLAG_RECEIVER_FOREGROUND
20464                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20465         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20466                 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20467                 UserHandle.USER_ALL);
20468         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20469             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20470             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20471                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20472                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20473             if (initLocale || !mProcessesReady) {
20474                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20475             }
20476             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20477                     AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20478                     UserHandle.USER_ALL);
20479         }
20480
20481         // Override configuration of the default display duplicates global config, so we need to
20482         // update it also. This will also notify WindowManager about changes.
20483         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20484                 DEFAULT_DISPLAY);
20485
20486         return changes;
20487     }
20488
20489     @Override
20490     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20491         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20492
20493         synchronized (this) {
20494             // Check if display is initialized in AM.
20495             if (!mStackSupervisor.isDisplayAdded(displayId)) {
20496                 // Call might come when display is not yet added or has already been removed.
20497                 if (DEBUG_CONFIGURATION) {
20498                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20499                             + displayId);
20500                 }
20501                 return false;
20502             }
20503
20504             if (values == null && mWindowManager != null) {
20505                 // sentinel: fetch the current configuration from the window manager
20506                 values = mWindowManager.computeNewConfiguration(displayId);
20507             }
20508
20509             if (mWindowManager != null) {
20510                 // Update OOM levels based on display size.
20511                 mProcessList.applyDisplaySize(mWindowManager);
20512             }
20513
20514             final long origId = Binder.clearCallingIdentity();
20515             try {
20516                 if (values != null) {
20517                     Settings.System.clearConfiguration(values);
20518                 }
20519                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20520                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20521                 return mTmpUpdateConfigurationResult.changes != 0;
20522             } finally {
20523                 Binder.restoreCallingIdentity(origId);
20524             }
20525         }
20526     }
20527
20528     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20529             boolean deferResume, int displayId) {
20530         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20531                 displayId, null /* result */);
20532     }
20533
20534     /**
20535      * Updates override configuration specific for the selected display. If no config is provided,
20536      * new one will be computed in WM based on current display info.
20537      */
20538     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20539             ActivityRecord starting, boolean deferResume, int displayId,
20540             UpdateConfigurationResult result) {
20541         int changes = 0;
20542         boolean kept = true;
20543
20544         if (mWindowManager != null) {
20545             mWindowManager.deferSurfaceLayout();
20546         }
20547         try {
20548             if (values != null) {
20549                 if (displayId == DEFAULT_DISPLAY) {
20550                     // Override configuration of the default display duplicates global config, so
20551                     // we're calling global config update instead for default display. It will also
20552                     // apply the correct override config.
20553                     changes = updateGlobalConfiguration(values, false /* initLocale */,
20554                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20555                 } else {
20556                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20557                 }
20558             }
20559
20560             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20561         } finally {
20562             if (mWindowManager != null) {
20563                 mWindowManager.continueSurfaceLayout();
20564             }
20565         }
20566
20567         if (result != null) {
20568             result.changes = changes;
20569             result.activityRelaunched = !kept;
20570         }
20571         return kept;
20572     }
20573
20574     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20575             int displayId) {
20576         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20577         final int changes = mTempConfig.updateFrom(values);
20578         if (changes != 0) {
20579             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20580                     + mTempConfig + " for displayId=" + displayId);
20581             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20582
20583             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20584             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20585                 // Reset the unsupported display size dialog.
20586                 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20587
20588                 killAllBackgroundProcessesExcept(N,
20589                         ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20590             }
20591         }
20592
20593         // Update the configuration with WM first and check if any of the stacks need to be resized
20594         // due to the configuration change. If so, resize the stacks now and do any relaunches if
20595         // necessary. This way we don't need to relaunch again afterwards in
20596         // ensureActivityConfigurationLocked().
20597         if (mWindowManager != null) {
20598             final int[] resizedStacks =
20599                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20600             if (resizedStacks != null) {
20601                 for (int stackId : resizedStacks) {
20602                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20603                 }
20604             }
20605         }
20606
20607         return changes;
20608     }
20609
20610     /** Applies latest configuration and/or visibility updates if needed. */
20611     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20612         boolean kept = true;
20613         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20614         // mainStack is null during startup.
20615         if (mainStack != null) {
20616             if (changes != 0 && starting == null) {
20617                 // If the configuration changed, and the caller is not already
20618                 // in the process of starting an activity, then find the top
20619                 // activity to check if its configuration needs to change.
20620                 starting = mainStack.topRunningActivityLocked();
20621             }
20622
20623             if (starting != null) {
20624                 kept = starting.ensureActivityConfigurationLocked(changes,
20625                         false /* preserveWindow */);
20626                 // And we need to make sure at this point that all other activities
20627                 // are made visible with the correct configuration.
20628                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20629                         !PRESERVE_WINDOWS);
20630             }
20631         }
20632
20633         return kept;
20634     }
20635
20636     /** Helper method that requests bounds from WM and applies them to stack. */
20637     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20638         final Rect newStackBounds = new Rect();
20639         mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20640         mStackSupervisor.resizeStackLocked(
20641                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20642                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20643                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20644     }
20645
20646     /**
20647      * Decide based on the configuration whether we should show the ANR,
20648      * crash, etc dialogs.  The idea is that if there is no affordance to
20649      * press the on-screen buttons, or the user experience would be more
20650      * greatly impacted than the crash itself, we shouldn't show the dialog.
20651      *
20652      * A thought: SystemUI might also want to get told about this, the Power
20653      * dialog / global actions also might want different behaviors.
20654      */
20655     private static boolean shouldShowDialogs(Configuration config) {
20656         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20657                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20658                                    && config.navigation == Configuration.NAVIGATION_NONAV);
20659         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20660         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20661                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20662                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20663                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20664         return inputMethodExists && uiModeSupportsDialogs;
20665     }
20666
20667     @Override
20668     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20669         synchronized (this) {
20670             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20671             if (srec != null) {
20672                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20673             }
20674         }
20675         return false;
20676     }
20677
20678     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20679             Intent resultData) {
20680
20681         synchronized (this) {
20682             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20683             if (r != null) {
20684                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20685             }
20686             return false;
20687         }
20688     }
20689
20690     public int getLaunchedFromUid(IBinder activityToken) {
20691         ActivityRecord srec;
20692         synchronized (this) {
20693             srec = ActivityRecord.forTokenLocked(activityToken);
20694         }
20695         if (srec == null) {
20696             return -1;
20697         }
20698         return srec.launchedFromUid;
20699     }
20700
20701     public String getLaunchedFromPackage(IBinder activityToken) {
20702         ActivityRecord srec;
20703         synchronized (this) {
20704             srec = ActivityRecord.forTokenLocked(activityToken);
20705         }
20706         if (srec == null) {
20707             return null;
20708         }
20709         return srec.launchedFromPackage;
20710     }
20711
20712     // =========================================================
20713     // LIFETIME MANAGEMENT
20714     // =========================================================
20715
20716     // Returns whether the app is receiving broadcast.
20717     // If receiving, fetch all broadcast queues which the app is
20718     // the current [or imminent] receiver on.
20719     private boolean isReceivingBroadcastLocked(ProcessRecord app,
20720             ArraySet<BroadcastQueue> receivingQueues) {
20721         if (!app.curReceivers.isEmpty()) {
20722             for (BroadcastRecord r : app.curReceivers) {
20723                 receivingQueues.add(r.queue);
20724             }
20725             return true;
20726         }
20727
20728         // It's not the current receiver, but it might be starting up to become one
20729         for (BroadcastQueue queue : mBroadcastQueues) {
20730             final BroadcastRecord r = queue.mPendingBroadcast;
20731             if (r != null && r.curApp == app) {
20732                 // found it; report which queue it's in
20733                 receivingQueues.add(queue);
20734             }
20735         }
20736
20737         return !receivingQueues.isEmpty();
20738     }
20739
20740     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20741             int targetUid, ComponentName targetComponent, String targetProcess) {
20742         if (!mTrackingAssociations) {
20743             return null;
20744         }
20745         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20746                 = mAssociations.get(targetUid);
20747         if (components == null) {
20748             components = new ArrayMap<>();
20749             mAssociations.put(targetUid, components);
20750         }
20751         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20752         if (sourceUids == null) {
20753             sourceUids = new SparseArray<>();
20754             components.put(targetComponent, sourceUids);
20755         }
20756         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20757         if (sourceProcesses == null) {
20758             sourceProcesses = new ArrayMap<>();
20759             sourceUids.put(sourceUid, sourceProcesses);
20760         }
20761         Association ass = sourceProcesses.get(sourceProcess);
20762         if (ass == null) {
20763             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20764                     targetProcess);
20765             sourceProcesses.put(sourceProcess, ass);
20766         }
20767         ass.mCount++;
20768         ass.mNesting++;
20769         if (ass.mNesting == 1) {
20770             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20771             ass.mLastState = sourceState;
20772         }
20773         return ass;
20774     }
20775
20776     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20777             ComponentName targetComponent) {
20778         if (!mTrackingAssociations) {
20779             return;
20780         }
20781         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20782                 = mAssociations.get(targetUid);
20783         if (components == null) {
20784             return;
20785         }
20786         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20787         if (sourceUids == null) {
20788             return;
20789         }
20790         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20791         if (sourceProcesses == null) {
20792             return;
20793         }
20794         Association ass = sourceProcesses.get(sourceProcess);
20795         if (ass == null || ass.mNesting <= 0) {
20796             return;
20797         }
20798         ass.mNesting--;
20799         if (ass.mNesting == 0) {
20800             long uptime = SystemClock.uptimeMillis();
20801             ass.mTime += uptime - ass.mStartTime;
20802             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20803                     += uptime - ass.mLastStateUptime;
20804             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20805         }
20806     }
20807
20808     private void noteUidProcessState(final int uid, final int state) {
20809         mBatteryStatsService.noteUidProcessState(uid, state);
20810         if (mTrackingAssociations) {
20811             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20812                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20813                         = mAssociations.valueAt(i1);
20814                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20815                     SparseArray<ArrayMap<String, Association>> sourceUids
20816                             = targetComponents.valueAt(i2);
20817                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20818                     if (sourceProcesses != null) {
20819                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20820                             Association ass = sourceProcesses.valueAt(i4);
20821                             if (ass.mNesting >= 1) {
20822                                 // currently associated
20823                                 long uptime = SystemClock.uptimeMillis();
20824                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20825                                         += uptime - ass.mLastStateUptime;
20826                                 ass.mLastState = state;
20827                                 ass.mLastStateUptime = uptime;
20828                             }
20829                         }
20830                     }
20831                 }
20832             }
20833         }
20834     }
20835
20836     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20837             boolean doingAll, long now) {
20838         if (mAdjSeq == app.adjSeq) {
20839             // This adjustment has already been computed.
20840             return app.curRawAdj;
20841         }
20842
20843         if (app.thread == null) {
20844             app.adjSeq = mAdjSeq;
20845             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20846             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20847             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20848         }
20849
20850         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20851         app.adjSource = null;
20852         app.adjTarget = null;
20853         app.empty = false;
20854         app.cached = false;
20855
20856         final int activitiesSize = app.activities.size();
20857
20858         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20859             // The max adjustment doesn't allow this app to be anything
20860             // below foreground, so it is not worth doing work for it.
20861             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20862             app.adjType = "fixed";
20863             app.adjSeq = mAdjSeq;
20864             app.curRawAdj = app.maxAdj;
20865             app.foregroundActivities = false;
20866             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20867             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20868             // System processes can do UI, and when they do we want to have
20869             // them trim their memory after the user leaves the UI.  To
20870             // facilitate this, here we need to determine whether or not it
20871             // is currently showing UI.
20872             app.systemNoUi = true;
20873             if (app == TOP_APP) {
20874                 app.systemNoUi = false;
20875                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20876                 app.adjType = "pers-top-activity";
20877             } else if (app.hasTopUi) {
20878                 app.systemNoUi = false;
20879                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20880                 app.adjType = "pers-top-ui";
20881             } else if (activitiesSize > 0) {
20882                 for (int j = 0; j < activitiesSize; j++) {
20883                     final ActivityRecord r = app.activities.get(j);
20884                     if (r.visible) {
20885                         app.systemNoUi = false;
20886                     }
20887                 }
20888             }
20889             if (!app.systemNoUi) {
20890                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20891             }
20892             return (app.curAdj=app.maxAdj);
20893         }
20894
20895         app.systemNoUi = false;
20896
20897         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20898
20899         // Determine the importance of the process, starting with most
20900         // important to least, and assign an appropriate OOM adjustment.
20901         int adj;
20902         int schedGroup;
20903         int procState;
20904         boolean foregroundActivities = false;
20905         mTmpBroadcastQueue.clear();
20906         if (app == TOP_APP) {
20907             // The last app on the list is the foreground app.
20908             adj = ProcessList.FOREGROUND_APP_ADJ;
20909             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20910             app.adjType = "top-activity";
20911             foregroundActivities = true;
20912             procState = PROCESS_STATE_CUR_TOP;
20913             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20914         } else if (app.instr != null) {
20915             // Don't want to kill running instrumentation.
20916             adj = ProcessList.FOREGROUND_APP_ADJ;
20917             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20918             app.adjType = "instrumentation";
20919             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20920             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20921         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20922             // An app that is currently receiving a broadcast also
20923             // counts as being in the foreground for OOM killer purposes.
20924             // It's placed in a sched group based on the nature of the
20925             // broadcast as reflected by which queue it's active in.
20926             adj = ProcessList.FOREGROUND_APP_ADJ;
20927             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20928                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20929             app.adjType = "broadcast";
20930             procState = ActivityManager.PROCESS_STATE_RECEIVER;
20931             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20932         } else if (app.executingServices.size() > 0) {
20933             // An app that is currently executing a service callback also
20934             // counts as being in the foreground.
20935             adj = ProcessList.FOREGROUND_APP_ADJ;
20936             schedGroup = app.execServicesFg ?
20937                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20938             app.adjType = "exec-service";
20939             procState = ActivityManager.PROCESS_STATE_SERVICE;
20940             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20941             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20942         } else {
20943             // As far as we know the process is empty.  We may change our mind later.
20944             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20945             // At this point we don't actually know the adjustment.  Use the cached adj
20946             // value that the caller wants us to.
20947             adj = cachedAdj;
20948             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20949             app.cached = true;
20950             app.empty = true;
20951             app.adjType = "cch-empty";
20952             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20953         }
20954
20955         // Examine all activities if not already foreground.
20956         if (!foregroundActivities && activitiesSize > 0) {
20957             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20958             for (int j = 0; j < activitiesSize; j++) {
20959                 final ActivityRecord r = app.activities.get(j);
20960                 if (r.app != app) {
20961                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20962                             + " instead of expected " + app);
20963                     if (r.app == null || (r.app.uid == app.uid)) {
20964                         // Only fix things up when they look sane
20965                         r.app = app;
20966                     } else {
20967                         continue;
20968                     }
20969                 }
20970                 if (r.visible) {
20971                     // App has a visible activity; only upgrade adjustment.
20972                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
20973                         adj = ProcessList.VISIBLE_APP_ADJ;
20974                         app.adjType = "vis-activity";
20975                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20976                     }
20977                     if (procState > PROCESS_STATE_CUR_TOP) {
20978                         procState = PROCESS_STATE_CUR_TOP;
20979                         app.adjType = "vis-activity";
20980                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20981                     }
20982                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20983                     app.cached = false;
20984                     app.empty = false;
20985                     foregroundActivities = true;
20986                     final TaskRecord task = r.getTask();
20987                     if (task != null && minLayer > 0) {
20988                         final int layer = task.mLayerRank;
20989                         if (layer >= 0 && minLayer > layer) {
20990                             minLayer = layer;
20991                         }
20992                     }
20993                     break;
20994                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20995                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20996                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20997                         app.adjType = "pause-activity";
20998                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20999                     }
21000                     if (procState > PROCESS_STATE_CUR_TOP) {
21001                         procState = PROCESS_STATE_CUR_TOP;
21002                         app.adjType = "pause-activity";
21003                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21004                     }
21005                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21006                     app.cached = false;
21007                     app.empty = false;
21008                     foregroundActivities = true;
21009                 } else if (r.state == ActivityState.STOPPING) {
21010                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21011                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21012                         app.adjType = "stop-activity";
21013                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21014                     }
21015                     // For the process state, we will at this point consider the
21016                     // process to be cached.  It will be cached either as an activity
21017                     // or empty depending on whether the activity is finishing.  We do
21018                     // this so that we can treat the process as cached for purposes of
21019                     // memory trimming (determing current memory level, trim command to
21020                     // send to process) since there can be an arbitrary number of stopping
21021                     // processes and they should soon all go into the cached state.
21022                     if (!r.finishing) {
21023                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21024                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21025                             app.adjType = "stop-activity";
21026                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21027                         }
21028                     }
21029                     app.cached = false;
21030                     app.empty = false;
21031                     foregroundActivities = true;
21032                 } else {
21033                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21034                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21035                         app.adjType = "cch-act";
21036                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21037                     }
21038                 }
21039             }
21040             if (adj == ProcessList.VISIBLE_APP_ADJ) {
21041                 adj += minLayer;
21042             }
21043         }
21044
21045         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21046                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21047             if (app.foregroundServices) {
21048                 // The user is aware of this app, so make it visible.
21049                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21050                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21051                 app.cached = false;
21052                 app.adjType = "fg-service";
21053                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21054                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21055             } else if (app.hasOverlayUi) {
21056                 // The process is display an overlay UI.
21057                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21058                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21059                 app.cached = false;
21060                 app.adjType = "has-overlay-ui";
21061                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21062                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21063             }
21064         }
21065
21066         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21067                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21068             if (app.forcingToImportant != null) {
21069                 // This is currently used for toasts...  they are not interactive, and
21070                 // we don't want them to cause the app to become fully foreground (and
21071                 // thus out of background check), so we yes the best background level we can.
21072                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21073                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21074                 app.cached = false;
21075                 app.adjType = "force-imp";
21076                 app.adjSource = app.forcingToImportant;
21077                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21078                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21079             }
21080         }
21081
21082         if (app == mHeavyWeightProcess) {
21083             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21084                 // We don't want to kill the current heavy-weight process.
21085                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21086                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21087                 app.cached = false;
21088                 app.adjType = "heavy";
21089                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21090             }
21091             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21092                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21093                 app.adjType = "heavy";
21094                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21095             }
21096         }
21097
21098         if (app == mHomeProcess) {
21099             if (adj > ProcessList.HOME_APP_ADJ) {
21100                 // This process is hosting what we currently consider to be the
21101                 // home app, so we don't want to let it go into the background.
21102                 adj = ProcessList.HOME_APP_ADJ;
21103                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21104                 app.cached = false;
21105                 app.adjType = "home";
21106                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21107             }
21108             if (procState > ActivityManager.PROCESS_STATE_HOME) {
21109                 procState = ActivityManager.PROCESS_STATE_HOME;
21110                 app.adjType = "home";
21111                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21112             }
21113         }
21114
21115         if (app == mPreviousProcess && app.activities.size() > 0) {
21116             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21117                 // This was the previous process that showed UI to the user.
21118                 // We want to try to keep it around more aggressively, to give
21119                 // a good experience around switching between two apps.
21120                 adj = ProcessList.PREVIOUS_APP_ADJ;
21121                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21122                 app.cached = false;
21123                 app.adjType = "previous";
21124                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21125             }
21126             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21127                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21128                 app.adjType = "previous";
21129                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21130             }
21131         }
21132
21133         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21134                 + " reason=" + app.adjType);
21135
21136         // By default, we use the computed adjustment.  It may be changed if
21137         // there are applications dependent on our services or providers, but
21138         // this gives us a baseline and makes sure we don't get into an
21139         // infinite recursion.
21140         app.adjSeq = mAdjSeq;
21141         app.curRawAdj = adj;
21142         app.hasStartedServices = false;
21143
21144         if (mBackupTarget != null && app == mBackupTarget.app) {
21145             // If possible we want to avoid killing apps while they're being backed up
21146             if (adj > ProcessList.BACKUP_APP_ADJ) {
21147                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21148                 adj = ProcessList.BACKUP_APP_ADJ;
21149                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21150                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21151                 }
21152                 app.adjType = "backup";
21153                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21154                 app.cached = false;
21155             }
21156             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21157                 procState = ActivityManager.PROCESS_STATE_BACKUP;
21158                 app.adjType = "backup";
21159                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21160             }
21161         }
21162
21163         boolean mayBeTop = false;
21164         String mayBeTopType = null;
21165         Object mayBeTopSource = null;
21166         Object mayBeTopTarget = null;
21167
21168         for (int is = app.services.size()-1;
21169                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21170                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21171                         || procState > ActivityManager.PROCESS_STATE_TOP);
21172                 is--) {
21173             ServiceRecord s = app.services.valueAt(is);
21174             if (s.startRequested) {
21175                 app.hasStartedServices = true;
21176                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21177                     procState = ActivityManager.PROCESS_STATE_SERVICE;
21178                     app.adjType = "started-services";
21179                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21180                 }
21181                 if (app.hasShownUi && app != mHomeProcess) {
21182                     // If this process has shown some UI, let it immediately
21183                     // go to the LRU list because it may be pretty heavy with
21184                     // UI stuff.  We'll tag it with a label just to help
21185                     // debug and understand what is going on.
21186                     if (adj > ProcessList.SERVICE_ADJ) {
21187                         app.adjType = "cch-started-ui-services";
21188                     }
21189                 } else {
21190                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21191                         // This service has seen some activity within
21192                         // recent memory, so we will keep its process ahead
21193                         // of the background processes.
21194                         if (adj > ProcessList.SERVICE_ADJ) {
21195                             adj = ProcessList.SERVICE_ADJ;
21196                             app.adjType = "started-services";
21197                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21198                             app.cached = false;
21199                         }
21200                     }
21201                     // If we have let the service slide into the background
21202                     // state, still have some text describing what it is doing
21203                     // even though the service no longer has an impact.
21204                     if (adj > ProcessList.SERVICE_ADJ) {
21205                         app.adjType = "cch-started-services";
21206                     }
21207                 }
21208             }
21209
21210             for (int conni = s.connections.size()-1;
21211                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21212                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21213                             || procState > ActivityManager.PROCESS_STATE_TOP);
21214                     conni--) {
21215                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21216                 for (int i = 0;
21217                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21218                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21219                                 || procState > ActivityManager.PROCESS_STATE_TOP);
21220                         i++) {
21221                     // XXX should compute this based on the max of
21222                     // all connected clients.
21223                     ConnectionRecord cr = clist.get(i);
21224                     if (cr.binding.client == app) {
21225                         // Binding to ourself is not interesting.
21226                         continue;
21227                     }
21228
21229                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21230                         ProcessRecord client = cr.binding.client;
21231                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
21232                                 TOP_APP, doingAll, now);
21233                         int clientProcState = client.curProcState;
21234                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21235                             // If the other app is cached for any reason, for purposes here
21236                             // we are going to consider it empty.  The specific cached state
21237                             // doesn't propagate except under certain conditions.
21238                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21239                         }
21240                         String adjType = null;
21241                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21242                             // Not doing bind OOM management, so treat
21243                             // this guy more like a started service.
21244                             if (app.hasShownUi && app != mHomeProcess) {
21245                                 // If this process has shown some UI, let it immediately
21246                                 // go to the LRU list because it may be pretty heavy with
21247                                 // UI stuff.  We'll tag it with a label just to help
21248                                 // debug and understand what is going on.
21249                                 if (adj > clientAdj) {
21250                                     adjType = "cch-bound-ui-services";
21251                                 }
21252                                 app.cached = false;
21253                                 clientAdj = adj;
21254                                 clientProcState = procState;
21255                             } else {
21256                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21257                                     // This service has not seen activity within
21258                                     // recent memory, so allow it to drop to the
21259                                     // LRU list if there is no other reason to keep
21260                                     // it around.  We'll also tag it with a label just
21261                                     // to help debug and undertand what is going on.
21262                                     if (adj > clientAdj) {
21263                                         adjType = "cch-bound-services";
21264                                     }
21265                                     clientAdj = adj;
21266                                 }
21267                             }
21268                         }
21269                         if (adj > clientAdj) {
21270                             // If this process has recently shown UI, and
21271                             // the process that is binding to it is less
21272                             // important than being visible, then we don't
21273                             // care about the binding as much as we care
21274                             // about letting this process get into the LRU
21275                             // list to be killed and restarted if needed for
21276                             // memory.
21277                             if (app.hasShownUi && app != mHomeProcess
21278                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21279                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21280                                     adjType = "cch-bound-ui-services";
21281                                 }
21282                             } else {
21283                                 int newAdj;
21284                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21285                                         |Context.BIND_IMPORTANT)) != 0) {
21286                                     newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21287                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21288                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21289                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21290                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21291                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21292                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21293                                     newAdj = clientAdj;
21294                                 } else {
21295                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
21296                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21297                                     } else {
21298                                         newAdj = adj;
21299                                     }
21300                                 }
21301                                 if (!client.cached) {
21302                                     app.cached = false;
21303                                 }
21304                                 if (adj >  newAdj) {
21305                                     adj = newAdj;
21306                                     adjType = "service";
21307                                 }
21308                             }
21309                         }
21310                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21311                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21312                             // This will treat important bound services identically to
21313                             // the top app, which may behave differently than generic
21314                             // foreground work.
21315                             if (client.curSchedGroup > schedGroup) {
21316                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21317                                     schedGroup = client.curSchedGroup;
21318                                 } else {
21319                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21320                                 }
21321                             }
21322                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21323                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21324                                     // Special handling of clients who are in the top state.
21325                                     // We *may* want to consider this process to be in the
21326                                     // top state as well, but only if there is not another
21327                                     // reason for it to be running.  Being on the top is a
21328                                     // special state, meaning you are specifically running
21329                                     // for the current top app.  If the process is already
21330                                     // running in the background for some other reason, it
21331                                     // is more important to continue considering it to be
21332                                     // in the background state.
21333                                     mayBeTop = true;
21334                                     mayBeTopType = "service";
21335                                     mayBeTopSource = cr.binding.client;
21336                                     mayBeTopTarget = s.name;
21337                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21338                                 } else {
21339                                     // Special handling for above-top states (persistent
21340                                     // processes).  These should not bring the current process
21341                                     // into the top state, since they are not on top.  Instead
21342                                     // give them the best state after that.
21343                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21344                                         clientProcState =
21345                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21346                                     } else if (mWakefulness
21347                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21348                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21349                                                     != 0) {
21350                                         clientProcState =
21351                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21352                                     } else {
21353                                         clientProcState =
21354                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21355                                     }
21356                                 }
21357                             }
21358                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21359                             if (clientProcState <
21360                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21361                                 clientProcState =
21362                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21363                             }
21364                         } else {
21365                             if (clientProcState <
21366                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21367                                 clientProcState =
21368                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21369                             }
21370                         }
21371                         if (procState > clientProcState) {
21372                             procState = clientProcState;
21373                             if (adjType == null) {
21374                                 adjType = "service";
21375                             }
21376                         }
21377                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21378                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21379                             app.pendingUiClean = true;
21380                         }
21381                         if (adjType != null) {
21382                             app.adjType = adjType;
21383                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21384                                     .REASON_SERVICE_IN_USE;
21385                             app.adjSource = cr.binding.client;
21386                             app.adjSourceProcState = clientProcState;
21387                             app.adjTarget = s.name;
21388                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21389                                     + ": " + app + ", due to " + cr.binding.client
21390                                     + " adj=" + adj + " procState=" + procState);
21391                         }
21392                     }
21393                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21394                         app.treatLikeActivity = true;
21395                     }
21396                     final ActivityRecord a = cr.activity;
21397                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21398                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21399                             (a.visible || a.state == ActivityState.RESUMED ||
21400                              a.state == ActivityState.PAUSING)) {
21401                             adj = ProcessList.FOREGROUND_APP_ADJ;
21402                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21403                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21404                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21405                                 } else {
21406                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21407                                 }
21408                             }
21409                             app.cached = false;
21410                             app.adjType = "service";
21411                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21412                                     .REASON_SERVICE_IN_USE;
21413                             app.adjSource = a;
21414                             app.adjSourceProcState = procState;
21415                             app.adjTarget = s.name;
21416                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21417                                     + app);
21418                         }
21419                     }
21420                 }
21421             }
21422         }
21423
21424         for (int provi = app.pubProviders.size()-1;
21425                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21426                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21427                         || procState > ActivityManager.PROCESS_STATE_TOP);
21428                 provi--) {
21429             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21430             for (int i = cpr.connections.size()-1;
21431                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21432                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21433                             || procState > ActivityManager.PROCESS_STATE_TOP);
21434                     i--) {
21435                 ContentProviderConnection conn = cpr.connections.get(i);
21436                 ProcessRecord client = conn.client;
21437                 if (client == app) {
21438                     // Being our own client is not interesting.
21439                     continue;
21440                 }
21441                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21442                 int clientProcState = client.curProcState;
21443                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21444                     // If the other app is cached for any reason, for purposes here
21445                     // we are going to consider it empty.
21446                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21447                 }
21448                 String adjType = null;
21449                 if (adj > clientAdj) {
21450                     if (app.hasShownUi && app != mHomeProcess
21451                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21452                         adjType = "cch-ui-provider";
21453                     } else {
21454                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21455                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21456                         adjType = "provider";
21457                     }
21458                     app.cached &= client.cached;
21459                 }
21460                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21461                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21462                         // Special handling of clients who are in the top state.
21463                         // We *may* want to consider this process to be in the
21464                         // top state as well, but only if there is not another
21465                         // reason for it to be running.  Being on the top is a
21466                         // special state, meaning you are specifically running
21467                         // for the current top app.  If the process is already
21468                         // running in the background for some other reason, it
21469                         // is more important to continue considering it to be
21470                         // in the background state.
21471                         mayBeTop = true;
21472                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21473                         mayBeTopType = adjType = "provider-top";
21474                         mayBeTopSource = client;
21475                         mayBeTopTarget = cpr.name;
21476                     } else {
21477                         // Special handling for above-top states (persistent
21478                         // processes).  These should not bring the current process
21479                         // into the top state, since they are not on top.  Instead
21480                         // give them the best state after that.
21481                         clientProcState =
21482                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21483                         if (adjType == null) {
21484                             adjType = "provider";
21485                         }
21486                     }
21487                 }
21488                 if (procState > clientProcState) {
21489                     procState = clientProcState;
21490                 }
21491                 if (client.curSchedGroup > schedGroup) {
21492                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21493                 }
21494                 if (adjType != null) {
21495                     app.adjType = adjType;
21496                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21497                             .REASON_PROVIDER_IN_USE;
21498                     app.adjSource = client;
21499                     app.adjSourceProcState = clientProcState;
21500                     app.adjTarget = cpr.name;
21501                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21502                             + ": " + app + ", due to " + client
21503                             + " adj=" + adj + " procState=" + procState);
21504                 }
21505             }
21506             // If the provider has external (non-framework) process
21507             // dependencies, ensure that its adjustment is at least
21508             // FOREGROUND_APP_ADJ.
21509             if (cpr.hasExternalProcessHandles()) {
21510                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21511                     adj = ProcessList.FOREGROUND_APP_ADJ;
21512                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21513                     app.cached = false;
21514                     app.adjType = "ext-provider";
21515                     app.adjTarget = cpr.name;
21516                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21517                 }
21518                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21519                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21520                 }
21521             }
21522         }
21523
21524         if (app.lastProviderTime > 0 &&
21525                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21526             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21527                 adj = ProcessList.PREVIOUS_APP_ADJ;
21528                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21529                 app.cached = false;
21530                 app.adjType = "recent-provider";
21531                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21532             }
21533             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21534                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21535                 app.adjType = "recent-provider";
21536                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21537             }
21538         }
21539
21540         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21541             // A client of one of our services or providers is in the top state.  We
21542             // *may* want to be in the top state, but not if we are already running in
21543             // the background for some other reason.  For the decision here, we are going
21544             // to pick out a few specific states that we want to remain in when a client
21545             // is top (states that tend to be longer-term) and otherwise allow it to go
21546             // to the top state.
21547             switch (procState) {
21548                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21549                     // Something else is keeping it at this level, just leave it.
21550                     break;
21551                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21552                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21553                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21554                 case ActivityManager.PROCESS_STATE_SERVICE:
21555                     // These all are longer-term states, so pull them up to the top
21556                     // of the background states, but not all the way to the top state.
21557                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21558                     app.adjType = mayBeTopType;
21559                     app.adjSource = mayBeTopSource;
21560                     app.adjTarget = mayBeTopTarget;
21561                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21562                             + ": " + app + ", due to " + mayBeTopSource
21563                             + " adj=" + adj + " procState=" + procState);
21564                     break;
21565                 default:
21566                     // Otherwise, top is a better choice, so take it.
21567                     procState = ActivityManager.PROCESS_STATE_TOP;
21568                     app.adjType = mayBeTopType;
21569                     app.adjSource = mayBeTopSource;
21570                     app.adjTarget = mayBeTopTarget;
21571                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21572                             + ": " + app + ", due to " + mayBeTopSource
21573                             + " adj=" + adj + " procState=" + procState);
21574                     break;
21575             }
21576         }
21577
21578         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21579             if (app.hasClientActivities) {
21580                 // This is a cached process, but with client activities.  Mark it so.
21581                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21582                 app.adjType = "cch-client-act";
21583             } else if (app.treatLikeActivity) {
21584                 // This is a cached process, but somebody wants us to treat it like it has
21585                 // an activity, okay!
21586                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21587                 app.adjType = "cch-as-act";
21588             }
21589         }
21590
21591         if (adj == ProcessList.SERVICE_ADJ) {
21592             if (doingAll) {
21593                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21594                 mNewNumServiceProcs++;
21595                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21596                 if (!app.serviceb) {
21597                     // This service isn't far enough down on the LRU list to
21598                     // normally be a B service, but if we are low on RAM and it
21599                     // is large we want to force it down since we would prefer to
21600                     // keep launcher over it.
21601                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21602                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21603                         app.serviceHighRam = true;
21604                         app.serviceb = true;
21605                         //Slog.i(TAG, "ADJ " + app + " high ram!");
21606                     } else {
21607                         mNewNumAServiceProcs++;
21608                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
21609                     }
21610                 } else {
21611                     app.serviceHighRam = false;
21612                 }
21613             }
21614             if (app.serviceb) {
21615                 adj = ProcessList.SERVICE_B_ADJ;
21616             }
21617         }
21618
21619         app.curRawAdj = adj;
21620
21621         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21622         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21623         if (adj > app.maxAdj) {
21624             adj = app.maxAdj;
21625             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21626                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21627             }
21628         }
21629
21630         // Do final modification to adj.  Everything we do between here and applying
21631         // the final setAdj must be done in this function, because we will also use
21632         // it when computing the final cached adj later.  Note that we don't need to
21633         // worry about this for max adj above, since max adj will always be used to
21634         // keep it out of the cached vaues.
21635         app.curAdj = app.modifyRawOomAdj(adj);
21636         app.curSchedGroup = schedGroup;
21637         app.curProcState = procState;
21638         app.foregroundActivities = foregroundActivities;
21639
21640         return app.curRawAdj;
21641     }
21642
21643     /**
21644      * Record new PSS sample for a process.
21645      */
21646     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21647             long now) {
21648         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21649                 swapPss * 1024);
21650         proc.lastPssTime = now;
21651         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21652         if (DEBUG_PSS) Slog.d(TAG_PSS,
21653                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21654                 + " state=" + ProcessList.makeProcStateString(procState));
21655         if (proc.initialIdlePss == 0) {
21656             proc.initialIdlePss = pss;
21657         }
21658         proc.lastPss = pss;
21659         proc.lastSwapPss = swapPss;
21660         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21661             proc.lastCachedPss = pss;
21662             proc.lastCachedSwapPss = swapPss;
21663         }
21664
21665         final SparseArray<Pair<Long, String>> watchUids
21666                 = mMemWatchProcesses.getMap().get(proc.processName);
21667         Long check = null;
21668         if (watchUids != null) {
21669             Pair<Long, String> val = watchUids.get(proc.uid);
21670             if (val == null) {
21671                 val = watchUids.get(0);
21672             }
21673             if (val != null) {
21674                 check = val.first;
21675             }
21676         }
21677         if (check != null) {
21678             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21679                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21680                 if (!isDebuggable) {
21681                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21682                         isDebuggable = true;
21683                     }
21684                 }
21685                 if (isDebuggable) {
21686                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21687                     final ProcessRecord myProc = proc;
21688                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
21689                     mMemWatchDumpProcName = proc.processName;
21690                     mMemWatchDumpFile = heapdumpFile.toString();
21691                     mMemWatchDumpPid = proc.pid;
21692                     mMemWatchDumpUid = proc.uid;
21693                     BackgroundThread.getHandler().post(new Runnable() {
21694                         @Override
21695                         public void run() {
21696                             revokeUriPermission(ActivityThread.currentActivityThread()
21697                                             .getApplicationThread(),
21698                                     null, DumpHeapActivity.JAVA_URI,
21699                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
21700                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21701                                     UserHandle.myUserId());
21702                             ParcelFileDescriptor fd = null;
21703                             try {
21704                                 heapdumpFile.delete();
21705                                 fd = ParcelFileDescriptor.open(heapdumpFile,
21706                                         ParcelFileDescriptor.MODE_CREATE |
21707                                                 ParcelFileDescriptor.MODE_TRUNCATE |
21708                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
21709                                                 ParcelFileDescriptor.MODE_APPEND);
21710                                 IApplicationThread thread = myProc.thread;
21711                                 if (thread != null) {
21712                                     try {
21713                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
21714                                                 "Requesting dump heap from "
21715                                                 + myProc + " to " + heapdumpFile);
21716                                         thread.dumpHeap(/* managed= */ true,
21717                                                 /* mallocInfo= */ false, /* runGc= */ false,
21718                                                 heapdumpFile.toString(), fd);
21719                                     } catch (RemoteException e) {
21720                                     }
21721                                 }
21722                             } catch (FileNotFoundException e) {
21723                                 e.printStackTrace();
21724                             } finally {
21725                                 if (fd != null) {
21726                                     try {
21727                                         fd.close();
21728                                     } catch (IOException e) {
21729                                     }
21730                                 }
21731                             }
21732                         }
21733                     });
21734                 } else {
21735                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21736                             + ", but debugging not enabled");
21737                 }
21738             }
21739         }
21740     }
21741
21742     /**
21743      * Schedule PSS collection of a process.
21744      */
21745     void requestPssLocked(ProcessRecord proc, int procState) {
21746         if (mPendingPssProcesses.contains(proc)) {
21747             return;
21748         }
21749         if (mPendingPssProcesses.size() == 0) {
21750             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21751         }
21752         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21753         proc.pssProcState = procState;
21754         mPendingPssProcesses.add(proc);
21755     }
21756
21757     /**
21758      * Schedule PSS collection of all processes.
21759      */
21760     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21761         if (!always) {
21762             if (now < (mLastFullPssTime +
21763                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21764                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
21765                 return;
21766             }
21767         }
21768         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21769         mLastFullPssTime = now;
21770         mFullPssPending = true;
21771         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21772         mPendingPssProcesses.clear();
21773         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21774             ProcessRecord app = mLruProcesses.get(i);
21775             if (app.thread == null
21776                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21777                 continue;
21778             }
21779             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21780                 app.pssProcState = app.setProcState;
21781                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21782                         mTestPssMode, isSleepingLocked(), now);
21783                 mPendingPssProcesses.add(app);
21784             }
21785         }
21786         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21787     }
21788
21789     public void setTestPssMode(boolean enabled) {
21790         synchronized (this) {
21791             mTestPssMode = enabled;
21792             if (enabled) {
21793                 // Whenever we enable the mode, we want to take a snapshot all of current
21794                 // process mem use.
21795                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21796             }
21797         }
21798     }
21799
21800     /**
21801      * Ask a given process to GC right now.
21802      */
21803     final void performAppGcLocked(ProcessRecord app) {
21804         try {
21805             app.lastRequestedGc = SystemClock.uptimeMillis();
21806             if (app.thread != null) {
21807                 if (app.reportLowMemory) {
21808                     app.reportLowMemory = false;
21809                     app.thread.scheduleLowMemory();
21810                 } else {
21811                     app.thread.processInBackground();
21812                 }
21813             }
21814         } catch (Exception e) {
21815             // whatever.
21816         }
21817     }
21818
21819     /**
21820      * Returns true if things are idle enough to perform GCs.
21821      */
21822     private final boolean canGcNowLocked() {
21823         boolean processingBroadcasts = false;
21824         for (BroadcastQueue q : mBroadcastQueues) {
21825             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21826                 processingBroadcasts = true;
21827             }
21828         }
21829         return !processingBroadcasts
21830                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21831     }
21832
21833     /**
21834      * Perform GCs on all processes that are waiting for it, but only
21835      * if things are idle.
21836      */
21837     final void performAppGcsLocked() {
21838         final int N = mProcessesToGc.size();
21839         if (N <= 0) {
21840             return;
21841         }
21842         if (canGcNowLocked()) {
21843             while (mProcessesToGc.size() > 0) {
21844                 ProcessRecord proc = mProcessesToGc.remove(0);
21845                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21846                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21847                             <= SystemClock.uptimeMillis()) {
21848                         // To avoid spamming the system, we will GC processes one
21849                         // at a time, waiting a few seconds between each.
21850                         performAppGcLocked(proc);
21851                         scheduleAppGcsLocked();
21852                         return;
21853                     } else {
21854                         // It hasn't been long enough since we last GCed this
21855                         // process...  put it in the list to wait for its time.
21856                         addProcessToGcListLocked(proc);
21857                         break;
21858                     }
21859                 }
21860             }
21861
21862             scheduleAppGcsLocked();
21863         }
21864     }
21865
21866     /**
21867      * If all looks good, perform GCs on all processes waiting for them.
21868      */
21869     final void performAppGcsIfAppropriateLocked() {
21870         if (canGcNowLocked()) {
21871             performAppGcsLocked();
21872             return;
21873         }
21874         // Still not idle, wait some more.
21875         scheduleAppGcsLocked();
21876     }
21877
21878     /**
21879      * Schedule the execution of all pending app GCs.
21880      */
21881     final void scheduleAppGcsLocked() {
21882         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21883
21884         if (mProcessesToGc.size() > 0) {
21885             // Schedule a GC for the time to the next process.
21886             ProcessRecord proc = mProcessesToGc.get(0);
21887             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21888
21889             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21890             long now = SystemClock.uptimeMillis();
21891             if (when < (now+mConstants.GC_TIMEOUT)) {
21892                 when = now + mConstants.GC_TIMEOUT;
21893             }
21894             mHandler.sendMessageAtTime(msg, when);
21895         }
21896     }
21897
21898     /**
21899      * Add a process to the array of processes waiting to be GCed.  Keeps the
21900      * list in sorted order by the last GC time.  The process can't already be
21901      * on the list.
21902      */
21903     final void addProcessToGcListLocked(ProcessRecord proc) {
21904         boolean added = false;
21905         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21906             if (mProcessesToGc.get(i).lastRequestedGc <
21907                     proc.lastRequestedGc) {
21908                 added = true;
21909                 mProcessesToGc.add(i+1, proc);
21910                 break;
21911             }
21912         }
21913         if (!added) {
21914             mProcessesToGc.add(0, proc);
21915         }
21916     }
21917
21918     /**
21919      * Set up to ask a process to GC itself.  This will either do it
21920      * immediately, or put it on the list of processes to gc the next
21921      * time things are idle.
21922      */
21923     final void scheduleAppGcLocked(ProcessRecord app) {
21924         long now = SystemClock.uptimeMillis();
21925         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21926             return;
21927         }
21928         if (!mProcessesToGc.contains(app)) {
21929             addProcessToGcListLocked(app);
21930             scheduleAppGcsLocked();
21931         }
21932     }
21933
21934     final void checkExcessivePowerUsageLocked() {
21935         updateCpuStatsNow();
21936
21937         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21938         boolean doCpuKills = true;
21939         if (mLastPowerCheckUptime == 0) {
21940             doCpuKills = false;
21941         }
21942         final long curUptime = SystemClock.uptimeMillis();
21943         final long uptimeSince = curUptime - mLastPowerCheckUptime;
21944         mLastPowerCheckUptime = curUptime;
21945         int i = mLruProcesses.size();
21946         while (i > 0) {
21947             i--;
21948             ProcessRecord app = mLruProcesses.get(i);
21949             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21950                 if (app.lastCpuTime <= 0) {
21951                     continue;
21952                 }
21953                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21954                 if (DEBUG_POWER) {
21955                     StringBuilder sb = new StringBuilder(128);
21956                     sb.append("CPU for ");
21957                     app.toShortString(sb);
21958                     sb.append(": over ");
21959                     TimeUtils.formatDuration(uptimeSince, sb);
21960                     sb.append(" used ");
21961                     TimeUtils.formatDuration(cputimeUsed, sb);
21962                     sb.append(" (");
21963                     sb.append((cputimeUsed*100)/uptimeSince);
21964                     sb.append("%)");
21965                     Slog.i(TAG_POWER, sb.toString());
21966                 }
21967                 // If the process has used too much CPU over the last duration, the
21968                 // user probably doesn't want this, so kill!
21969                 if (doCpuKills && uptimeSince > 0) {
21970                     // What is the limit for this process?
21971                     int cpuLimit;
21972                     long checkDur = curUptime - app.whenUnimportant;
21973                     if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21974                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21975                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21976                             || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21977                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21978                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21979                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21980                     } else {
21981                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21982                     }
21983                     if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21984                         synchronized (stats) {
21985                             stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21986                                     uptimeSince, cputimeUsed);
21987                         }
21988                         app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
21989                                 + " dur=" + checkDur + " limit=" + cpuLimit, true);
21990                         app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21991                     }
21992                 }
21993                 app.lastCpuTime = app.curCpuTime;
21994             }
21995         }
21996     }
21997
21998     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21999             long nowElapsed) {
22000         boolean success = true;
22001
22002         if (app.curRawAdj != app.setRawAdj) {
22003             app.setRawAdj = app.curRawAdj;
22004         }
22005
22006         int changes = 0;
22007
22008         if (app.curAdj != app.setAdj) {
22009             ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22010             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22011                 String msg = "Set " + app.pid + " " + app.processName + " adj "
22012                         + app.curAdj + ": " + app.adjType;
22013                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22014             }
22015             app.setAdj = app.curAdj;
22016             app.verifiedAdj = ProcessList.INVALID_ADJ;
22017         }
22018
22019         if (app.setSchedGroup != app.curSchedGroup) {
22020             int oldSchedGroup = app.setSchedGroup;
22021             app.setSchedGroup = app.curSchedGroup;
22022             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22023                 String msg = "Setting sched group of " + app.processName
22024                         + " to " + app.curSchedGroup;
22025                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22026             }
22027             if (app.waitingToKill != null && app.curReceivers.isEmpty()
22028                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22029                 app.kill(app.waitingToKill, true);
22030                 success = false;
22031             } else {
22032                 int processGroup;
22033                 switch (app.curSchedGroup) {
22034                     case ProcessList.SCHED_GROUP_BACKGROUND:
22035                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22036                         break;
22037                     case ProcessList.SCHED_GROUP_TOP_APP:
22038                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22039                         processGroup = THREAD_GROUP_TOP_APP;
22040                         break;
22041                     default:
22042                         processGroup = THREAD_GROUP_DEFAULT;
22043                         break;
22044                 }
22045                 long oldId = Binder.clearCallingIdentity();
22046                 try {
22047                     setProcessGroup(app.pid, processGroup);
22048                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22049                         // do nothing if we already switched to RT
22050                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22051                             mVrController.onTopProcChangedLocked(app);
22052                             if (mUseFifoUiScheduling) {
22053                                 // Switch UI pipeline for app to SCHED_FIFO
22054                                 app.savedPriority = Process.getThreadPriority(app.pid);
22055                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22056                                 if (app.renderThreadTid != 0) {
22057                                     scheduleAsFifoPriority(app.renderThreadTid,
22058                                         /* suppressLogs */true);
22059                                     if (DEBUG_OOM_ADJ) {
22060                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
22061                                             app.renderThreadTid + ") to FIFO");
22062                                     }
22063                                 } else {
22064                                     if (DEBUG_OOM_ADJ) {
22065                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
22066                                     }
22067                                 }
22068                             } else {
22069                                 // Boost priority for top app UI and render threads
22070                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22071                                 if (app.renderThreadTid != 0) {
22072                                     try {
22073                                         setThreadPriority(app.renderThreadTid,
22074                                                 TOP_APP_PRIORITY_BOOST);
22075                                     } catch (IllegalArgumentException e) {
22076                                         // thread died, ignore
22077                                     }
22078                                 }
22079                             }
22080                         }
22081                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22082                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22083                         mVrController.onTopProcChangedLocked(app);
22084                         if (mUseFifoUiScheduling) {
22085                             try {
22086                                 // Reset UI pipeline to SCHED_OTHER
22087                                 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22088                                 setThreadPriority(app.pid, app.savedPriority);
22089                                 if (app.renderThreadTid != 0) {
22090                                     setThreadScheduler(app.renderThreadTid,
22091                                         SCHED_OTHER, 0);
22092                                     setThreadPriority(app.renderThreadTid, -4);
22093                                 }
22094                             } catch (IllegalArgumentException e) {
22095                                 Slog.w(TAG,
22096                                         "Failed to set scheduling policy, thread does not exist:\n"
22097                                                 + e);
22098                             } catch (SecurityException e) {
22099                                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22100                             }
22101                         } else {
22102                             // Reset priority for top app UI and render threads
22103                             setThreadPriority(app.pid, 0);
22104                             if (app.renderThreadTid != 0) {
22105                                 setThreadPriority(app.renderThreadTid, 0);
22106                             }
22107                         }
22108                     }
22109                 } catch (Exception e) {
22110                     if (false) {
22111                         Slog.w(TAG, "Failed setting process group of " + app.pid
22112                                 + " to " + app.curSchedGroup);
22113                         Slog.w(TAG, "at location", e);
22114                     }
22115                 } finally {
22116                     Binder.restoreCallingIdentity(oldId);
22117                 }
22118             }
22119         }
22120         if (app.repForegroundActivities != app.foregroundActivities) {
22121             app.repForegroundActivities = app.foregroundActivities;
22122             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22123         }
22124         if (app.repProcState != app.curProcState) {
22125             app.repProcState = app.curProcState;
22126             if (app.thread != null) {
22127                 try {
22128                     if (false) {
22129                         //RuntimeException h = new RuntimeException("here");
22130                         Slog.i(TAG, "Sending new process state " + app.repProcState
22131                                 + " to " + app /*, h*/);
22132                     }
22133                     app.thread.setProcessState(app.repProcState);
22134                 } catch (RemoteException e) {
22135                 }
22136             }
22137         }
22138         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22139                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22140             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22141                 // Experimental code to more aggressively collect pss while
22142                 // running test...  the problem is that this tends to collect
22143                 // the data right when a process is transitioning between process
22144                 // states, which well tend to give noisy data.
22145                 long start = SystemClock.uptimeMillis();
22146                 long pss = Debug.getPss(app.pid, mTmpLong, null);
22147                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22148                 mPendingPssProcesses.remove(app);
22149                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22150                         + " to " + app.curProcState + ": "
22151                         + (SystemClock.uptimeMillis()-start) + "ms");
22152             }
22153             app.lastStateTime = now;
22154             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22155                     mTestPssMode, isSleepingLocked(), now);
22156             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22157                     + ProcessList.makeProcStateString(app.setProcState) + " to "
22158                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22159                     + (app.nextPssTime-now) + ": " + app);
22160         } else {
22161             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22162                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22163                     mTestPssMode)))) {
22164                 requestPssLocked(app, app.setProcState);
22165                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22166                         mTestPssMode, isSleepingLocked(), now);
22167             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22168                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22169         }
22170         if (app.setProcState != app.curProcState) {
22171             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22172                 String msg = "Proc state change of " + app.processName
22173                         + " to " + app.curProcState;
22174                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22175             }
22176             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22177             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22178             if (setImportant && !curImportant) {
22179                 // This app is no longer something we consider important enough to allow to
22180                 // use arbitrary amounts of battery power.  Note
22181                 // its current CPU time to later know to kill it if
22182                 // it is not behaving well.
22183                 app.whenUnimportant = now;
22184                 app.lastCpuTime = 0;
22185             }
22186             // Inform UsageStats of important process state change
22187             // Must be called before updating setProcState
22188             maybeUpdateUsageStatsLocked(app, nowElapsed);
22189
22190             app.setProcState = app.curProcState;
22191             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22192                 app.notCachedSinceIdle = false;
22193             }
22194             if (!doingAll) {
22195                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22196             } else {
22197                 app.procStateChanged = true;
22198             }
22199         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22200                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22201             // For apps that sit around for a long time in the interactive state, we need
22202             // to report this at least once a day so they don't go idle.
22203             maybeUpdateUsageStatsLocked(app, nowElapsed);
22204         }
22205
22206         if (changes != 0) {
22207             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22208                     "Changes in " + app + ": " + changes);
22209             int i = mPendingProcessChanges.size()-1;
22210             ProcessChangeItem item = null;
22211             while (i >= 0) {
22212                 item = mPendingProcessChanges.get(i);
22213                 if (item.pid == app.pid) {
22214                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22215                             "Re-using existing item: " + item);
22216                     break;
22217                 }
22218                 i--;
22219             }
22220             if (i < 0) {
22221                 // No existing item in pending changes; need a new one.
22222                 final int NA = mAvailProcessChanges.size();
22223                 if (NA > 0) {
22224                     item = mAvailProcessChanges.remove(NA-1);
22225                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22226                             "Retrieving available item: " + item);
22227                 } else {
22228                     item = new ProcessChangeItem();
22229                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22230                             "Allocating new item: " + item);
22231                 }
22232                 item.changes = 0;
22233                 item.pid = app.pid;
22234                 item.uid = app.info.uid;
22235                 if (mPendingProcessChanges.size() == 0) {
22236                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22237                             "*** Enqueueing dispatch processes changed!");
22238                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22239                 }
22240                 mPendingProcessChanges.add(item);
22241             }
22242             item.changes |= changes;
22243             item.foregroundActivities = app.repForegroundActivities;
22244             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22245                     "Item " + Integer.toHexString(System.identityHashCode(item))
22246                     + " " + app.toShortString() + ": changes=" + item.changes
22247                     + " foreground=" + item.foregroundActivities
22248                     + " type=" + app.adjType + " source=" + app.adjSource
22249                     + " target=" + app.adjTarget);
22250         }
22251
22252         return success;
22253     }
22254
22255     private boolean isEphemeralLocked(int uid) {
22256         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22257         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22258             return false;
22259         }
22260         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22261                 packages[0]);
22262     }
22263
22264     @VisibleForTesting
22265     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22266         final UidRecord.ChangeItem pendingChange;
22267         if (uidRec == null || uidRec.pendingChange == null) {
22268             if (mPendingUidChanges.size() == 0) {
22269                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22270                         "*** Enqueueing dispatch uid changed!");
22271                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22272             }
22273             final int NA = mAvailUidChanges.size();
22274             if (NA > 0) {
22275                 pendingChange = mAvailUidChanges.remove(NA-1);
22276                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22277                         "Retrieving available item: " + pendingChange);
22278             } else {
22279                 pendingChange = new UidRecord.ChangeItem();
22280                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22281                         "Allocating new item: " + pendingChange);
22282             }
22283             if (uidRec != null) {
22284                 uidRec.pendingChange = pendingChange;
22285                 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22286                     // If this uid is going away, and we haven't yet reported it is gone,
22287                     // then do so now.
22288                     change |= UidRecord.CHANGE_IDLE;
22289                 }
22290             } else if (uid < 0) {
22291                 throw new IllegalArgumentException("No UidRecord or uid");
22292             }
22293             pendingChange.uidRecord = uidRec;
22294             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22295             mPendingUidChanges.add(pendingChange);
22296         } else {
22297             pendingChange = uidRec.pendingChange;
22298             // If there is no change in idle or active state, then keep whatever was pending.
22299             if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22300                 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22301                         | UidRecord.CHANGE_ACTIVE));
22302             }
22303             // If there is no change in cached or uncached state, then keep whatever was pending.
22304             if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22305                 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22306                         | UidRecord.CHANGE_UNCACHED));
22307             }
22308             // If this is a report of the UID being gone, then we shouldn't keep any previous
22309             // report of it being active or cached.  (That is, a gone uid is never active,
22310             // and never cached.)
22311             if ((change & UidRecord.CHANGE_GONE) != 0) {
22312                 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22313                 if (!uidRec.idle) {
22314                     // If this uid is going away, and we haven't yet reported it is gone,
22315                     // then do so now.
22316                     change |= UidRecord.CHANGE_IDLE;
22317                 }
22318             }
22319         }
22320         pendingChange.change = change;
22321         pendingChange.processState = uidRec != null
22322                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22323         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22324         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22325         if (uidRec != null) {
22326             uidRec.lastReportedChange = change;
22327             uidRec.updateLastDispatchedProcStateSeq(change);
22328         }
22329
22330         // Directly update the power manager, since we sit on top of it and it is critical
22331         // it be kept in sync (so wake locks will be held as soon as appropriate).
22332         if (mLocalPowerManager != null) {
22333             // TO DO: dispatch cached/uncached changes here, so we don't need to report
22334             // all proc state changes.
22335             if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22336                 mLocalPowerManager.uidActive(pendingChange.uid);
22337             }
22338             if ((change & UidRecord.CHANGE_IDLE) != 0) {
22339                 mLocalPowerManager.uidIdle(pendingChange.uid);
22340             }
22341             if ((change & UidRecord.CHANGE_GONE) != 0) {
22342                 mLocalPowerManager.uidGone(pendingChange.uid);
22343             } else {
22344                 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22345                         pendingChange.processState);
22346             }
22347         }
22348     }
22349
22350     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22351             String authority) {
22352         if (app == null) return;
22353         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22354             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22355             if (userState == null) return;
22356             final long now = SystemClock.elapsedRealtime();
22357             Long lastReported = userState.mProviderLastReportedFg.get(authority);
22358             if (lastReported == null || lastReported < now - 60 * 1000L) {
22359                 if (mSystemReady) {
22360                     // Cannot touch the user stats if not system ready
22361                     mUsageStatsService.reportContentProviderUsage(
22362                             authority, providerPkgName, app.userId);
22363                 }
22364                 userState.mProviderLastReportedFg.put(authority, now);
22365             }
22366         }
22367     }
22368
22369     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22370         if (DEBUG_USAGE_STATS) {
22371             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22372                     + "] state changes: old = " + app.setProcState + ", new = "
22373                     + app.curProcState);
22374         }
22375         if (mUsageStatsService == null) {
22376             return;
22377         }
22378         boolean isInteraction;
22379         // To avoid some abuse patterns, we are going to be careful about what we consider
22380         // to be an app interaction.  Being the top activity doesn't count while the display
22381         // is sleeping, nor do short foreground services.
22382         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22383             isInteraction = true;
22384             app.fgInteractionTime = 0;
22385         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22386             if (app.fgInteractionTime == 0) {
22387                 app.fgInteractionTime = nowElapsed;
22388                 isInteraction = false;
22389             } else {
22390                 isInteraction = nowElapsed > app.fgInteractionTime
22391                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22392             }
22393         } else {
22394             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22395             app.fgInteractionTime = 0;
22396         }
22397         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22398                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22399             app.interactionEventTime = nowElapsed;
22400             String[] packages = app.getPackageList();
22401             if (packages != null) {
22402                 for (int i = 0; i < packages.length; i++) {
22403                     mUsageStatsService.reportEvent(packages[i], app.userId,
22404                             UsageEvents.Event.SYSTEM_INTERACTION);
22405                 }
22406             }
22407         }
22408         app.reportedInteraction = isInteraction;
22409         if (!isInteraction) {
22410             app.interactionEventTime = 0;
22411         }
22412     }
22413
22414     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22415         if (proc.thread != null) {
22416             if (proc.baseProcessTracker != null) {
22417                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22418             }
22419         }
22420     }
22421
22422     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22423             ProcessRecord TOP_APP, boolean doingAll, long now) {
22424         if (app.thread == null) {
22425             return false;
22426         }
22427
22428         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22429
22430         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22431     }
22432
22433     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22434             boolean oomAdj) {
22435         if (isForeground != proc.foregroundServices) {
22436             proc.foregroundServices = isForeground;
22437             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22438                     proc.info.uid);
22439             if (isForeground) {
22440                 if (curProcs == null) {
22441                     curProcs = new ArrayList<ProcessRecord>();
22442                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22443                 }
22444                 if (!curProcs.contains(proc)) {
22445                     curProcs.add(proc);
22446                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22447                             proc.info.packageName, proc.info.uid);
22448                 }
22449             } else {
22450                 if (curProcs != null) {
22451                     if (curProcs.remove(proc)) {
22452                         mBatteryStatsService.noteEvent(
22453                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22454                                 proc.info.packageName, proc.info.uid);
22455                         if (curProcs.size() <= 0) {
22456                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22457                         }
22458                     }
22459                 }
22460             }
22461             if (oomAdj) {
22462                 updateOomAdjLocked();
22463             }
22464         }
22465     }
22466
22467     private final ActivityRecord resumedAppLocked() {
22468         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22469         String pkg;
22470         int uid;
22471         if (act != null) {
22472             pkg = act.packageName;
22473             uid = act.info.applicationInfo.uid;
22474         } else {
22475             pkg = null;
22476             uid = -1;
22477         }
22478         // Has the UID or resumed package name changed?
22479         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22480                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22481             if (mCurResumedPackage != null) {
22482                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22483                         mCurResumedPackage, mCurResumedUid);
22484             }
22485             mCurResumedPackage = pkg;
22486             mCurResumedUid = uid;
22487             if (mCurResumedPackage != null) {
22488                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22489                         mCurResumedPackage, mCurResumedUid);
22490             }
22491         }
22492         return act;
22493     }
22494
22495     /**
22496      * Update OomAdj for a specific process.
22497      * @param app The process to update
22498      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22499      *                  if necessary, or skip.
22500      * @return whether updateOomAdjLocked(app) was successful.
22501      */
22502     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22503         final ActivityRecord TOP_ACT = resumedAppLocked();
22504         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22505         final boolean wasCached = app.cached;
22506
22507         mAdjSeq++;
22508
22509         // This is the desired cached adjusment we want to tell it to use.
22510         // If our app is currently cached, we know it, and that is it.  Otherwise,
22511         // we don't know it yet, and it needs to now be cached we will then
22512         // need to do a complete oom adj.
22513         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22514                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22515         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22516                 SystemClock.uptimeMillis());
22517         if (oomAdjAll
22518                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22519             // Changed to/from cached state, so apps after it in the LRU
22520             // list may also be changed.
22521             updateOomAdjLocked();
22522         }
22523         return success;
22524     }
22525
22526     final void updateOomAdjLocked() {
22527         final ActivityRecord TOP_ACT = resumedAppLocked();
22528         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22529         final long now = SystemClock.uptimeMillis();
22530         final long nowElapsed = SystemClock.elapsedRealtime();
22531         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22532         final int N = mLruProcesses.size();
22533
22534         if (false) {
22535             RuntimeException e = new RuntimeException();
22536             e.fillInStackTrace();
22537             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22538         }
22539
22540         // Reset state in all uid records.
22541         for (int i=mActiveUids.size()-1; i>=0; i--) {
22542             final UidRecord uidRec = mActiveUids.valueAt(i);
22543             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22544                     "Starting update of " + uidRec);
22545             uidRec.reset();
22546         }
22547
22548         mStackSupervisor.rankTaskLayersIfNeeded();
22549
22550         mAdjSeq++;
22551         mNewNumServiceProcs = 0;
22552         mNewNumAServiceProcs = 0;
22553
22554         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22555         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22556
22557         // Let's determine how many processes we have running vs.
22558         // how many slots we have for background processes; we may want
22559         // to put multiple processes in a slot of there are enough of
22560         // them.
22561         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22562                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22563         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22564         if (numEmptyProcs > cachedProcessLimit) {
22565             // If there are more empty processes than our limit on cached
22566             // processes, then use the cached process limit for the factor.
22567             // This ensures that the really old empty processes get pushed
22568             // down to the bottom, so if we are running low on memory we will
22569             // have a better chance at keeping around more cached processes
22570             // instead of a gazillion empty processes.
22571             numEmptyProcs = cachedProcessLimit;
22572         }
22573         int emptyFactor = numEmptyProcs/numSlots;
22574         if (emptyFactor < 1) emptyFactor = 1;
22575         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22576         if (cachedFactor < 1) cachedFactor = 1;
22577         int stepCached = 0;
22578         int stepEmpty = 0;
22579         int numCached = 0;
22580         int numEmpty = 0;
22581         int numTrimming = 0;
22582
22583         mNumNonCachedProcs = 0;
22584         mNumCachedHiddenProcs = 0;
22585
22586         // First update the OOM adjustment for each of the
22587         // application processes based on their current state.
22588         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22589         int nextCachedAdj = curCachedAdj+1;
22590         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22591         int nextEmptyAdj = curEmptyAdj+2;
22592         for (int i=N-1; i>=0; i--) {
22593             ProcessRecord app = mLruProcesses.get(i);
22594             if (!app.killedByAm && app.thread != null) {
22595                 app.procStateChanged = false;
22596                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22597
22598                 // If we haven't yet assigned the final cached adj
22599                 // to the process, do that now.
22600                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22601                     switch (app.curProcState) {
22602                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22603                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22604                             // This process is a cached process holding activities...
22605                             // assign it the next cached value for that type, and then
22606                             // step that cached level.
22607                             app.curRawAdj = curCachedAdj;
22608                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22609                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22610                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22611                                     + ")");
22612                             if (curCachedAdj != nextCachedAdj) {
22613                                 stepCached++;
22614                                 if (stepCached >= cachedFactor) {
22615                                     stepCached = 0;
22616                                     curCachedAdj = nextCachedAdj;
22617                                     nextCachedAdj += 2;
22618                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22619                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22620                                     }
22621                                 }
22622                             }
22623                             break;
22624                         default:
22625                             // For everything else, assign next empty cached process
22626                             // level and bump that up.  Note that this means that
22627                             // long-running services that have dropped down to the
22628                             // cached level will be treated as empty (since their process
22629                             // state is still as a service), which is what we want.
22630                             app.curRawAdj = curEmptyAdj;
22631                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22632                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22633                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22634                                     + ")");
22635                             if (curEmptyAdj != nextEmptyAdj) {
22636                                 stepEmpty++;
22637                                 if (stepEmpty >= emptyFactor) {
22638                                     stepEmpty = 0;
22639                                     curEmptyAdj = nextEmptyAdj;
22640                                     nextEmptyAdj += 2;
22641                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22642                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22643                                     }
22644                                 }
22645                             }
22646                             break;
22647                     }
22648                 }
22649
22650                 applyOomAdjLocked(app, true, now, nowElapsed);
22651
22652                 // Count the number of process types.
22653                 switch (app.curProcState) {
22654                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22655                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22656                         mNumCachedHiddenProcs++;
22657                         numCached++;
22658                         if (numCached > cachedProcessLimit) {
22659                             app.kill("cached #" + numCached, true);
22660                         }
22661                         break;
22662                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22663                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22664                                 && app.lastActivityTime < oldTime) {
22665                             app.kill("empty for "
22666                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22667                                     / 1000) + "s", true);
22668                         } else {
22669                             numEmpty++;
22670                             if (numEmpty > emptyProcessLimit) {
22671                                 app.kill("empty #" + numEmpty, true);
22672                             }
22673                         }
22674                         break;
22675                     default:
22676                         mNumNonCachedProcs++;
22677                         break;
22678                 }
22679
22680                 if (app.isolated && app.services.size() <= 0) {
22681                     // If this is an isolated process, and there are no
22682                     // services running in it, then the process is no longer
22683                     // needed.  We agressively kill these because we can by
22684                     // definition not re-use the same process again, and it is
22685                     // good to avoid having whatever code was running in them
22686                     // left sitting around after no longer needed.
22687                     app.kill("isolated not needed", true);
22688                 } else {
22689                     // Keeping this process, update its uid.
22690                     final UidRecord uidRec = app.uidRecord;
22691                     if (uidRec != null) {
22692                         uidRec.ephemeral = app.info.isInstantApp();
22693                         if (uidRec.curProcState > app.curProcState) {
22694                             uidRec.curProcState = app.curProcState;
22695                         }
22696                         if (app.foregroundServices) {
22697                             uidRec.foregroundServices = true;
22698                         }
22699                     }
22700                 }
22701
22702                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22703                         && !app.killedByAm) {
22704                     numTrimming++;
22705                 }
22706             }
22707         }
22708
22709         incrementProcStateSeqAndNotifyAppsLocked();
22710
22711         mNumServiceProcs = mNewNumServiceProcs;
22712
22713         // Now determine the memory trimming level of background processes.
22714         // Unfortunately we need to start at the back of the list to do this
22715         // properly.  We only do this if the number of background apps we
22716         // are managing to keep around is less than half the maximum we desire;
22717         // if we are keeping a good number around, we'll let them use whatever
22718         // memory they want.
22719         final int numCachedAndEmpty = numCached + numEmpty;
22720         int memFactor;
22721         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22722                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22723             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22724                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22725             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22726                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22727             } else {
22728                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22729             }
22730         } else {
22731             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22732         }
22733         // We always allow the memory level to go up (better).  We only allow it to go
22734         // down if we are in a state where that is allowed, *and* the total number of processes
22735         // has gone down since last time.
22736         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22737                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22738                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22739         if (memFactor > mLastMemoryLevel) {
22740             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22741                 memFactor = mLastMemoryLevel;
22742                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22743             }
22744         }
22745         if (memFactor != mLastMemoryLevel) {
22746             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22747         }
22748         mLastMemoryLevel = memFactor;
22749         mLastNumProcesses = mLruProcesses.size();
22750         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22751         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22752         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22753             if (mLowRamStartTime == 0) {
22754                 mLowRamStartTime = now;
22755             }
22756             int step = 0;
22757             int fgTrimLevel;
22758             switch (memFactor) {
22759                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22760                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22761                     break;
22762                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22763                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22764                     break;
22765                 default:
22766                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22767                     break;
22768             }
22769             int factor = numTrimming/3;
22770             int minFactor = 2;
22771             if (mHomeProcess != null) minFactor++;
22772             if (mPreviousProcess != null) minFactor++;
22773             if (factor < minFactor) factor = minFactor;
22774             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22775             for (int i=N-1; i>=0; i--) {
22776                 ProcessRecord app = mLruProcesses.get(i);
22777                 if (allChanged || app.procStateChanged) {
22778                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22779                     app.procStateChanged = false;
22780                 }
22781                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22782                         && !app.killedByAm) {
22783                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
22784                         try {
22785                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22786                                     "Trimming memory of " + app.processName + " to " + curLevel);
22787                             app.thread.scheduleTrimMemory(curLevel);
22788                         } catch (RemoteException e) {
22789                         }
22790                         if (false) {
22791                             // For now we won't do this; our memory trimming seems
22792                             // to be good enough at this point that destroying
22793                             // activities causes more harm than good.
22794                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22795                                     && app != mHomeProcess && app != mPreviousProcess) {
22796                                 // Need to do this on its own message because the stack may not
22797                                 // be in a consistent state at this point.
22798                                 // For these apps we will also finish their activities
22799                                 // to help them free memory.
22800                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22801                             }
22802                         }
22803                     }
22804                     app.trimMemoryLevel = curLevel;
22805                     step++;
22806                     if (step >= factor) {
22807                         step = 0;
22808                         switch (curLevel) {
22809                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22810                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22811                                 break;
22812                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22813                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22814                                 break;
22815                         }
22816                     }
22817                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22818                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22819                             && app.thread != null) {
22820                         try {
22821                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22822                                     "Trimming memory of heavy-weight " + app.processName
22823                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22824                             app.thread.scheduleTrimMemory(
22825                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22826                         } catch (RemoteException e) {
22827                         }
22828                     }
22829                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22830                 } else {
22831                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22832                             || app.systemNoUi) && app.pendingUiClean) {
22833                         // If this application is now in the background and it
22834                         // had done UI, then give it the special trim level to
22835                         // have it free UI resources.
22836                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22837                         if (app.trimMemoryLevel < level && app.thread != null) {
22838                             try {
22839                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22840                                         "Trimming memory of bg-ui " + app.processName
22841                                         + " to " + level);
22842                                 app.thread.scheduleTrimMemory(level);
22843                             } catch (RemoteException e) {
22844                             }
22845                         }
22846                         app.pendingUiClean = false;
22847                     }
22848                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22849                         try {
22850                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22851                                     "Trimming memory of fg " + app.processName
22852                                     + " to " + fgTrimLevel);
22853                             app.thread.scheduleTrimMemory(fgTrimLevel);
22854                         } catch (RemoteException e) {
22855                         }
22856                     }
22857                     app.trimMemoryLevel = fgTrimLevel;
22858                 }
22859             }
22860         } else {
22861             if (mLowRamStartTime != 0) {
22862                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22863                 mLowRamStartTime = 0;
22864             }
22865             for (int i=N-1; i>=0; i--) {
22866                 ProcessRecord app = mLruProcesses.get(i);
22867                 if (allChanged || app.procStateChanged) {
22868                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22869                     app.procStateChanged = false;
22870                 }
22871                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22872                         || app.systemNoUi) && app.pendingUiClean) {
22873                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22874                             && app.thread != null) {
22875                         try {
22876                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22877                                     "Trimming memory of ui hidden " + app.processName
22878                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22879                             app.thread.scheduleTrimMemory(
22880                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22881                         } catch (RemoteException e) {
22882                         }
22883                     }
22884                     app.pendingUiClean = false;
22885                 }
22886                 app.trimMemoryLevel = 0;
22887             }
22888         }
22889
22890         if (mAlwaysFinishActivities) {
22891             // Need to do this on its own message because the stack may not
22892             // be in a consistent state at this point.
22893             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22894         }
22895
22896         if (allChanged) {
22897             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22898         }
22899
22900         ArrayList<UidRecord> becameIdle = null;
22901
22902         // Update from any uid changes.
22903         if (mLocalPowerManager != null) {
22904             mLocalPowerManager.startUidChanges();
22905         }
22906         for (int i=mActiveUids.size()-1; i>=0; i--) {
22907             final UidRecord uidRec = mActiveUids.valueAt(i);
22908             int uidChange = UidRecord.CHANGE_PROCSTATE;
22909             if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22910                     && (uidRec.setProcState != uidRec.curProcState
22911                            || uidRec.setWhitelist != uidRec.curWhitelist)) {
22912                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22913                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22914                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22915                         + " to " + uidRec.curWhitelist);
22916                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22917                         && !uidRec.curWhitelist) {
22918                     // UID is now in the background (and not on the temp whitelist).  Was it
22919                     // previously in the foreground (or on the temp whitelist)?
22920                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22921                             || uidRec.setWhitelist) {
22922                         uidRec.lastBackgroundTime = nowElapsed;
22923                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22924                             // Note: the background settle time is in elapsed realtime, while
22925                             // the handler time base is uptime.  All this means is that we may
22926                             // stop background uids later than we had intended, but that only
22927                             // happens because the device was sleeping so we are okay anyway.
22928                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22929                                     mConstants.BACKGROUND_SETTLE_TIME);
22930                         }
22931                     }
22932                     if (uidRec.idle && !uidRec.setIdle) {
22933                         uidChange = UidRecord.CHANGE_IDLE;
22934                         if (becameIdle == null) {
22935                             becameIdle = new ArrayList<>();
22936                         }
22937                         becameIdle.add(uidRec);
22938                     }
22939                 } else {
22940                     if (uidRec.idle) {
22941                         uidChange = UidRecord.CHANGE_ACTIVE;
22942                         EventLogTags.writeAmUidActive(uidRec.uid);
22943                         uidRec.idle = false;
22944                     }
22945                     uidRec.lastBackgroundTime = 0;
22946                 }
22947                 final boolean wasCached = uidRec.setProcState
22948                         > ActivityManager.PROCESS_STATE_RECEIVER;
22949                 final boolean isCached = uidRec.curProcState
22950                         > ActivityManager.PROCESS_STATE_RECEIVER;
22951                 if (wasCached != isCached ||
22952                         uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22953                     uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22954                 }
22955                 uidRec.setProcState = uidRec.curProcState;
22956                 uidRec.setWhitelist = uidRec.curWhitelist;
22957                 uidRec.setIdle = uidRec.idle;
22958                 enqueueUidChangeLocked(uidRec, -1, uidChange);
22959                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22960                 if (uidRec.foregroundServices) {
22961                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
22962                 }
22963             }
22964         }
22965         if (mLocalPowerManager != null) {
22966             mLocalPowerManager.finishUidChanges();
22967         }
22968
22969         if (becameIdle != null) {
22970             // If we have any new uids that became idle this time, we need to make sure
22971             // they aren't left with running services.
22972             for (int i = becameIdle.size() - 1; i >= 0; i--) {
22973                 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22974             }
22975         }
22976
22977         if (mProcessStats.shouldWriteNowLocked(now)) {
22978             mHandler.post(new Runnable() {
22979                 @Override public void run() {
22980                     synchronized (ActivityManagerService.this) {
22981                         mProcessStats.writeStateAsyncLocked();
22982                     }
22983                 }
22984             });
22985         }
22986
22987         if (DEBUG_OOM_ADJ) {
22988             final long duration = SystemClock.uptimeMillis() - now;
22989             if (false) {
22990                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22991                         new RuntimeException("here").fillInStackTrace());
22992             } else {
22993                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22994             }
22995         }
22996     }
22997
22998     @Override
22999     public void makePackageIdle(String packageName, int userId) {
23000         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23001                 != PackageManager.PERMISSION_GRANTED) {
23002             String msg = "Permission Denial: makePackageIdle() from pid="
23003                     + Binder.getCallingPid()
23004                     + ", uid=" + Binder.getCallingUid()
23005                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23006             Slog.w(TAG, msg);
23007             throw new SecurityException(msg);
23008         }
23009         final int callingPid = Binder.getCallingPid();
23010         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23011                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23012         long callingId = Binder.clearCallingIdentity();
23013         synchronized(this) {
23014             try {
23015                 IPackageManager pm = AppGlobals.getPackageManager();
23016                 int pkgUid = -1;
23017                 try {
23018                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23019                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23020                 } catch (RemoteException e) {
23021                 }
23022                 if (pkgUid == -1) {
23023                     throw new IllegalArgumentException("Unknown package name " + packageName);
23024                 }
23025
23026                 if (mLocalPowerManager != null) {
23027                     mLocalPowerManager.startUidChanges();
23028                 }
23029                 final int appId = UserHandle.getAppId(pkgUid);
23030                 final int N = mActiveUids.size();
23031                 for (int i=N-1; i>=0; i--) {
23032                     final UidRecord uidRec = mActiveUids.valueAt(i);
23033                     final long bgTime = uidRec.lastBackgroundTime;
23034                     if (bgTime > 0 && !uidRec.idle) {
23035                         if (UserHandle.getAppId(uidRec.uid) == appId) {
23036                             if (userId == UserHandle.USER_ALL ||
23037                                     userId == UserHandle.getUserId(uidRec.uid)) {
23038                                 EventLogTags.writeAmUidIdle(uidRec.uid);
23039                                 uidRec.idle = true;
23040                                 uidRec.setIdle = true;
23041                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23042                                         + " from package " + packageName + " user " + userId);
23043                                 doStopUidLocked(uidRec.uid, uidRec);
23044                             }
23045                         }
23046                     }
23047                 }
23048             } finally {
23049                 if (mLocalPowerManager != null) {
23050                     mLocalPowerManager.finishUidChanges();
23051                 }
23052                 Binder.restoreCallingIdentity(callingId);
23053             }
23054         }
23055     }
23056
23057     final void idleUids() {
23058         synchronized (this) {
23059             final int N = mActiveUids.size();
23060             if (N <= 0) {
23061                 return;
23062             }
23063             final long nowElapsed = SystemClock.elapsedRealtime();
23064             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23065             long nextTime = 0;
23066             if (mLocalPowerManager != null) {
23067                 mLocalPowerManager.startUidChanges();
23068             }
23069             for (int i=N-1; i>=0; i--) {
23070                 final UidRecord uidRec = mActiveUids.valueAt(i);
23071                 final long bgTime = uidRec.lastBackgroundTime;
23072                 if (bgTime > 0 && !uidRec.idle) {
23073                     if (bgTime <= maxBgTime) {
23074                         EventLogTags.writeAmUidIdle(uidRec.uid);
23075                         uidRec.idle = true;
23076                         uidRec.setIdle = true;
23077                         doStopUidLocked(uidRec.uid, uidRec);
23078                     } else {
23079                         if (nextTime == 0 || nextTime > bgTime) {
23080                             nextTime = bgTime;
23081                         }
23082                     }
23083                 }
23084             }
23085             if (mLocalPowerManager != null) {
23086                 mLocalPowerManager.finishUidChanges();
23087             }
23088             if (nextTime > 0) {
23089                 mHandler.removeMessages(IDLE_UIDS_MSG);
23090                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23091                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23092             }
23093         }
23094     }
23095
23096     /**
23097      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23098      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23099      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23100      */
23101     @VisibleForTesting
23102     @GuardedBy("this")
23103     void incrementProcStateSeqAndNotifyAppsLocked() {
23104         if (mWaitForNetworkTimeoutMs <= 0) {
23105             return;
23106         }
23107         // Used for identifying which uids need to block for network.
23108         ArrayList<Integer> blockingUids = null;
23109         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23110             final UidRecord uidRec = mActiveUids.valueAt(i);
23111             // If the network is not restricted for uid, then nothing to do here.
23112             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23113                 continue;
23114             }
23115             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23116                 continue;
23117             }
23118             // If process state is not changed, then there's nothing to do.
23119             if (uidRec.setProcState == uidRec.curProcState) {
23120                 continue;
23121             }
23122             final int blockState = getBlockStateForUid(uidRec);
23123             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23124             // there's nothing the app needs to do in this scenario.
23125             if (blockState == NETWORK_STATE_NO_CHANGE) {
23126                 continue;
23127             }
23128             synchronized (uidRec.networkStateLock) {
23129                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23130                 if (blockState == NETWORK_STATE_BLOCK) {
23131                     if (blockingUids == null) {
23132                         blockingUids = new ArrayList<>();
23133                     }
23134                     blockingUids.add(uidRec.uid);
23135                 } else {
23136                     if (DEBUG_NETWORK) {
23137                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23138                                 + " threads for uid: " + uidRec);
23139                     }
23140                     if (uidRec.waitingForNetwork) {
23141                         uidRec.networkStateLock.notifyAll();
23142                     }
23143                 }
23144             }
23145         }
23146
23147         // There are no uids that need to block, so nothing more to do.
23148         if (blockingUids == null) {
23149             return;
23150         }
23151
23152         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23153             final ProcessRecord app = mLruProcesses.get(i);
23154             if (!blockingUids.contains(app.uid)) {
23155                 continue;
23156             }
23157             if (!app.killedByAm && app.thread != null) {
23158                 final UidRecord uidRec = mActiveUids.get(app.uid);
23159                 try {
23160                     if (DEBUG_NETWORK) {
23161                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23162                                 + uidRec);
23163                     }
23164                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23165                 } catch (RemoteException ignored) {
23166                 }
23167             }
23168         }
23169     }
23170
23171     /**
23172      * Checks if the uid is coming from background to foreground or vice versa and returns
23173      * appropriate block state based on this.
23174      *
23175      * @return blockState based on whether the uid is coming from background to foreground or
23176      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23177      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23178      *         {@link #NETWORK_STATE_NO_CHANGE}.
23179      */
23180     @VisibleForTesting
23181     int getBlockStateForUid(UidRecord uidRec) {
23182         // Denotes whether uid's process state is currently allowed network access.
23183         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23184                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23185         // Denotes whether uid's process state was previously allowed network access.
23186         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23187                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23188
23189         // When the uid is coming to foreground, AMS should inform the app thread that it should
23190         // block for the network rules to get updated before launching an activity.
23191         if (!wasAllowed && isAllowed) {
23192             return NETWORK_STATE_BLOCK;
23193         }
23194         // When the uid is going to background, AMS should inform the app thread that if an
23195         // activity launch is blocked for the network rules to get updated, it should be unblocked.
23196         if (wasAllowed && !isAllowed) {
23197             return NETWORK_STATE_UNBLOCK;
23198         }
23199         return NETWORK_STATE_NO_CHANGE;
23200     }
23201
23202     final void runInBackgroundDisabled(int uid) {
23203         synchronized (this) {
23204             UidRecord uidRec = mActiveUids.get(uid);
23205             if (uidRec != null) {
23206                 // This uid is actually running...  should it be considered background now?
23207                 if (uidRec.idle) {
23208                     doStopUidLocked(uidRec.uid, uidRec);
23209                 }
23210             } else {
23211                 // This uid isn't actually running...  still send a report about it being "stopped".
23212                 doStopUidLocked(uid, null);
23213             }
23214         }
23215     }
23216
23217     final void doStopUidLocked(int uid, final UidRecord uidRec) {
23218         mServices.stopInBackgroundLocked(uid);
23219         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23220     }
23221
23222     /**
23223      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23224      */
23225     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23226             long duration, String tag) {
23227         if (DEBUG_WHITELISTS) {
23228             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23229                     + targetUid + ", " + duration + ")");
23230         }
23231
23232         synchronized (mPidsSelfLocked) {
23233             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23234             if (pr == null) {
23235                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23236                         + callerPid);
23237                 return;
23238             }
23239             if (!pr.whitelistManager) {
23240                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23241                         != PackageManager.PERMISSION_GRANTED) {
23242                     if (DEBUG_WHITELISTS) {
23243                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23244                                 + ": pid " + callerPid + " is not allowed");
23245                     }
23246                     return;
23247                 }
23248             }
23249         }
23250
23251         tempWhitelistUidLocked(targetUid, duration, tag);
23252     }
23253
23254     /**
23255      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23256      */
23257     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23258         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23259         setUidTempWhitelistStateLocked(targetUid, true);
23260         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23261     }
23262
23263     void pushTempWhitelist() {
23264         final int N;
23265         final PendingTempWhitelist[] list;
23266
23267         // First copy out the pending changes...  we need to leave them in the map for now,
23268         // in case someone needs to check what is coming up while we don't have the lock held.
23269         synchronized(this) {
23270             N = mPendingTempWhitelist.size();
23271             list = new PendingTempWhitelist[N];
23272             for (int i = 0; i < N; i++) {
23273                 list[i] = mPendingTempWhitelist.valueAt(i);
23274             }
23275         }
23276
23277         // Now safely dispatch changes to device idle controller.
23278         for (int i = 0; i < N; i++) {
23279             PendingTempWhitelist ptw = list[i];
23280             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23281                     ptw.duration, true, ptw.tag);
23282         }
23283
23284         // And now we can safely remove them from the map.
23285         synchronized(this) {
23286             for (int i = 0; i < N; i++) {
23287                 PendingTempWhitelist ptw = list[i];
23288                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23289                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23290                     mPendingTempWhitelist.removeAt(index);
23291                 }
23292             }
23293         }
23294     }
23295
23296     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23297         boolean changed = false;
23298         for (int i=mActiveUids.size()-1; i>=0; i--) {
23299             final UidRecord uidRec = mActiveUids.valueAt(i);
23300             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23301                 uidRec.curWhitelist = onWhitelist;
23302                 changed = true;
23303             }
23304         }
23305         if (changed) {
23306             updateOomAdjLocked();
23307         }
23308     }
23309
23310     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23311         boolean changed = false;
23312         final UidRecord uidRec = mActiveUids.get(uid);
23313         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23314             uidRec.curWhitelist = onWhitelist;
23315             updateOomAdjLocked();
23316         }
23317     }
23318
23319     final void trimApplications() {
23320         synchronized (this) {
23321             int i;
23322
23323             // First remove any unused application processes whose package
23324             // has been removed.
23325             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23326                 final ProcessRecord app = mRemovedProcesses.get(i);
23327                 if (app.activities.size() == 0
23328                         && app.curReceivers.isEmpty() && app.services.size() == 0) {
23329                     Slog.i(
23330                         TAG, "Exiting empty application process "
23331                         + app.toShortString() + " ("
23332                         + (app.thread != null ? app.thread.asBinder() : null)
23333                         + ")\n");
23334                     if (app.pid > 0 && app.pid != MY_PID) {
23335                         app.kill("empty", false);
23336                     } else {
23337                         try {
23338                             app.thread.scheduleExit();
23339                         } catch (Exception e) {
23340                             // Ignore exceptions.
23341                         }
23342                     }
23343                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23344                     mRemovedProcesses.remove(i);
23345
23346                     if (app.persistent) {
23347                         addAppLocked(app.info, null, false, null /* ABI override */);
23348                     }
23349                 }
23350             }
23351
23352             // Now update the oom adj for all processes.
23353             updateOomAdjLocked();
23354         }
23355     }
23356
23357     /** This method sends the specified signal to each of the persistent apps */
23358     public void signalPersistentProcesses(int sig) throws RemoteException {
23359         if (sig != SIGNAL_USR1) {
23360             throw new SecurityException("Only SIGNAL_USR1 is allowed");
23361         }
23362
23363         synchronized (this) {
23364             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23365                     != PackageManager.PERMISSION_GRANTED) {
23366                 throw new SecurityException("Requires permission "
23367                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23368             }
23369
23370             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23371                 ProcessRecord r = mLruProcesses.get(i);
23372                 if (r.thread != null && r.persistent) {
23373                     sendSignal(r.pid, sig);
23374                 }
23375             }
23376         }
23377     }
23378
23379     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23380         if (proc == null || proc == mProfileProc) {
23381             proc = mProfileProc;
23382             profileType = mProfileType;
23383             clearProfilerLocked();
23384         }
23385         if (proc == null) {
23386             return;
23387         }
23388         try {
23389             proc.thread.profilerControl(false, null, profileType);
23390         } catch (RemoteException e) {
23391             throw new IllegalStateException("Process disappeared");
23392         }
23393     }
23394
23395     private void clearProfilerLocked() {
23396         if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23397             try {
23398                 mProfilerInfo.profileFd.close();
23399             } catch (IOException e) {
23400             }
23401         }
23402         mProfileApp = null;
23403         mProfileProc = null;
23404         mProfilerInfo = null;
23405     }
23406
23407     public boolean profileControl(String process, int userId, boolean start,
23408             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23409
23410         try {
23411             synchronized (this) {
23412                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23413                 // its own permission.
23414                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23415                         != PackageManager.PERMISSION_GRANTED) {
23416                     throw new SecurityException("Requires permission "
23417                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23418                 }
23419
23420                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23421                     throw new IllegalArgumentException("null profile info or fd");
23422                 }
23423
23424                 ProcessRecord proc = null;
23425                 if (process != null) {
23426                     proc = findProcessLocked(process, userId, "profileControl");
23427                 }
23428
23429                 if (start && (proc == null || proc.thread == null)) {
23430                     throw new IllegalArgumentException("Unknown process: " + process);
23431                 }
23432
23433                 if (start) {
23434                     stopProfilerLocked(null, 0);
23435                     setProfileApp(proc.info, proc.processName, profilerInfo);
23436                     mProfileProc = proc;
23437                     mProfileType = profileType;
23438                     ParcelFileDescriptor fd = profilerInfo.profileFd;
23439                     try {
23440                         fd = fd.dup();
23441                     } catch (IOException e) {
23442                         fd = null;
23443                     }
23444                     profilerInfo.profileFd = fd;
23445                     proc.thread.profilerControl(start, profilerInfo, profileType);
23446                     fd = null;
23447                     try {
23448                         mProfilerInfo.profileFd.close();
23449                     } catch (IOException e) {
23450                     }
23451                     mProfilerInfo.profileFd = null;
23452                 } else {
23453                     stopProfilerLocked(proc, profileType);
23454                     if (profilerInfo != null && profilerInfo.profileFd != null) {
23455                         try {
23456                             profilerInfo.profileFd.close();
23457                         } catch (IOException e) {
23458                         }
23459                     }
23460                 }
23461
23462                 return true;
23463             }
23464         } catch (RemoteException e) {
23465             throw new IllegalStateException("Process disappeared");
23466         } finally {
23467             if (profilerInfo != null && profilerInfo.profileFd != null) {
23468                 try {
23469                     profilerInfo.profileFd.close();
23470                 } catch (IOException e) {
23471                 }
23472             }
23473         }
23474     }
23475
23476     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23477         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23478                 userId, true, ALLOW_FULL_ONLY, callName, null);
23479         ProcessRecord proc = null;
23480         try {
23481             int pid = Integer.parseInt(process);
23482             synchronized (mPidsSelfLocked) {
23483                 proc = mPidsSelfLocked.get(pid);
23484             }
23485         } catch (NumberFormatException e) {
23486         }
23487
23488         if (proc == null) {
23489             ArrayMap<String, SparseArray<ProcessRecord>> all
23490                     = mProcessNames.getMap();
23491             SparseArray<ProcessRecord> procs = all.get(process);
23492             if (procs != null && procs.size() > 0) {
23493                 proc = procs.valueAt(0);
23494                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23495                     for (int i=1; i<procs.size(); i++) {
23496                         ProcessRecord thisProc = procs.valueAt(i);
23497                         if (thisProc.userId == userId) {
23498                             proc = thisProc;
23499                             break;
23500                         }
23501                     }
23502                 }
23503             }
23504         }
23505
23506         return proc;
23507     }
23508
23509     public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23510             boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23511
23512         try {
23513             synchronized (this) {
23514                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23515                 // its own permission (same as profileControl).
23516                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23517                         != PackageManager.PERMISSION_GRANTED) {
23518                     throw new SecurityException("Requires permission "
23519                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23520                 }
23521
23522                 if (fd == null) {
23523                     throw new IllegalArgumentException("null fd");
23524                 }
23525
23526                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23527                 if (proc == null || proc.thread == null) {
23528                     throw new IllegalArgumentException("Unknown process: " + process);
23529                 }
23530
23531                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23532                 if (!isDebuggable) {
23533                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23534                         throw new SecurityException("Process not debuggable: " + proc);
23535                     }
23536                 }
23537
23538                 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23539                 fd = null;
23540                 return true;
23541             }
23542         } catch (RemoteException e) {
23543             throw new IllegalStateException("Process disappeared");
23544         } finally {
23545             if (fd != null) {
23546                 try {
23547                     fd.close();
23548                 } catch (IOException e) {
23549                 }
23550             }
23551         }
23552     }
23553
23554     @Override
23555     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23556             String reportPackage) {
23557         if (processName != null) {
23558             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23559                     "setDumpHeapDebugLimit()");
23560         } else {
23561             synchronized (mPidsSelfLocked) {
23562                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23563                 if (proc == null) {
23564                     throw new SecurityException("No process found for calling pid "
23565                             + Binder.getCallingPid());
23566                 }
23567                 if (!Build.IS_DEBUGGABLE
23568                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23569                     throw new SecurityException("Not running a debuggable build");
23570                 }
23571                 processName = proc.processName;
23572                 uid = proc.uid;
23573                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23574                     throw new SecurityException("Package " + reportPackage + " is not running in "
23575                             + proc);
23576                 }
23577             }
23578         }
23579         synchronized (this) {
23580             if (maxMemSize > 0) {
23581                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23582             } else {
23583                 if (uid != 0) {
23584                     mMemWatchProcesses.remove(processName, uid);
23585                 } else {
23586                     mMemWatchProcesses.getMap().remove(processName);
23587                 }
23588             }
23589         }
23590     }
23591
23592     @Override
23593     public void dumpHeapFinished(String path) {
23594         synchronized (this) {
23595             if (Binder.getCallingPid() != mMemWatchDumpPid) {
23596                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23597                         + " does not match last pid " + mMemWatchDumpPid);
23598                 return;
23599             }
23600             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23601                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23602                         + " does not match last path " + mMemWatchDumpFile);
23603                 return;
23604             }
23605             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23606             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23607
23608             // Forced gc to clean up the remnant hprof fd.
23609             Runtime.getRuntime().gc();
23610         }
23611     }
23612
23613     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23614     public void monitor() {
23615         synchronized (this) { }
23616     }
23617
23618     void onCoreSettingsChange(Bundle settings) {
23619         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23620             ProcessRecord processRecord = mLruProcesses.get(i);
23621             try {
23622                 if (processRecord.thread != null) {
23623                     processRecord.thread.setCoreSettings(settings);
23624                 }
23625             } catch (RemoteException re) {
23626                 /* ignore */
23627             }
23628         }
23629     }
23630
23631     // Multi-user methods
23632
23633     /**
23634      * Start user, if its not already running, but don't bring it to foreground.
23635      */
23636     @Override
23637     public boolean startUserInBackground(final int userId) {
23638         return mUserController.startUser(userId, /* foreground */ false);
23639     }
23640
23641     @Override
23642     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23643         return mUserController.unlockUser(userId, token, secret, listener);
23644     }
23645
23646     @Override
23647     public boolean switchUser(final int targetUserId) {
23648         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23649         int currentUserId;
23650         UserInfo targetUserInfo;
23651         synchronized (this) {
23652             currentUserId = mUserController.getCurrentUserIdLocked();
23653             targetUserInfo = mUserController.getUserInfo(targetUserId);
23654             if (targetUserId == currentUserId) {
23655                 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23656                 return true;
23657             }
23658             if (targetUserInfo == null) {
23659                 Slog.w(TAG, "No user info for user #" + targetUserId);
23660                 return false;
23661             }
23662             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23663                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23664                         + " when device is in demo mode");
23665                 return false;
23666             }
23667             if (!targetUserInfo.supportsSwitchTo()) {
23668                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23669                 return false;
23670             }
23671             if (targetUserInfo.isManagedProfile()) {
23672                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23673                 return false;
23674             }
23675             mUserController.setTargetUserIdLocked(targetUserId);
23676         }
23677         if (mUserController.mUserSwitchUiEnabled) {
23678             UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23679             Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23680             mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23681             mUiHandler.sendMessage(mHandler.obtainMessage(
23682                     START_USER_SWITCH_UI_MSG, userNames));
23683         } else {
23684             mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23685             mHandler.sendMessage(mHandler.obtainMessage(
23686                     START_USER_SWITCH_FG_MSG, targetUserId, 0));
23687         }
23688         return true;
23689     }
23690
23691     void scheduleStartProfilesLocked() {
23692         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23693             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23694                     DateUtils.SECOND_IN_MILLIS);
23695         }
23696     }
23697
23698     @Override
23699     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23700         return mUserController.stopUser(userId, force, callback);
23701     }
23702
23703     @Override
23704     public UserInfo getCurrentUser() {
23705         return mUserController.getCurrentUser();
23706     }
23707
23708     String getStartedUserState(int userId) {
23709         synchronized (this) {
23710             final UserState userState = mUserController.getStartedUserStateLocked(userId);
23711             return UserState.stateToString(userState.state);
23712         }
23713     }
23714
23715     @Override
23716     public boolean isUserRunning(int userId, int flags) {
23717         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23718                 && checkCallingPermission(INTERACT_ACROSS_USERS)
23719                     != PackageManager.PERMISSION_GRANTED) {
23720             String msg = "Permission Denial: isUserRunning() from pid="
23721                     + Binder.getCallingPid()
23722                     + ", uid=" + Binder.getCallingUid()
23723                     + " requires " + INTERACT_ACROSS_USERS;
23724             Slog.w(TAG, msg);
23725             throw new SecurityException(msg);
23726         }
23727         synchronized (this) {
23728             return mUserController.isUserRunningLocked(userId, flags);
23729         }
23730     }
23731
23732     @Override
23733     public int[] getRunningUserIds() {
23734         if (checkCallingPermission(INTERACT_ACROSS_USERS)
23735                 != PackageManager.PERMISSION_GRANTED) {
23736             String msg = "Permission Denial: isUserRunning() from pid="
23737                     + Binder.getCallingPid()
23738                     + ", uid=" + Binder.getCallingUid()
23739                     + " requires " + INTERACT_ACROSS_USERS;
23740             Slog.w(TAG, msg);
23741             throw new SecurityException(msg);
23742         }
23743         synchronized (this) {
23744             return mUserController.getStartedUserArrayLocked();
23745         }
23746     }
23747
23748     @Override
23749     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23750         mUserController.registerUserSwitchObserver(observer, name);
23751     }
23752
23753     @Override
23754     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23755         mUserController.unregisterUserSwitchObserver(observer);
23756     }
23757
23758     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23759         if (info == null) return null;
23760         ApplicationInfo newInfo = new ApplicationInfo(info);
23761         newInfo.initForUser(userId);
23762         return newInfo;
23763     }
23764
23765     public boolean isUserStopped(int userId) {
23766         synchronized (this) {
23767             return mUserController.getStartedUserStateLocked(userId) == null;
23768         }
23769     }
23770
23771     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23772         if (aInfo == null
23773                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23774             return aInfo;
23775         }
23776
23777         ActivityInfo info = new ActivityInfo(aInfo);
23778         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23779         return info;
23780     }
23781
23782     private boolean processSanityChecksLocked(ProcessRecord process) {
23783         if (process == null || process.thread == null) {
23784             return false;
23785         }
23786
23787         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23788         if (!isDebuggable) {
23789             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23790                 return false;
23791             }
23792         }
23793
23794         return true;
23795     }
23796
23797     public boolean startBinderTracking() throws RemoteException {
23798         synchronized (this) {
23799             mBinderTransactionTrackingEnabled = true;
23800             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23801             // permission (same as profileControl).
23802             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23803                     != PackageManager.PERMISSION_GRANTED) {
23804                 throw new SecurityException("Requires permission "
23805                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23806             }
23807
23808             for (int i = 0; i < mLruProcesses.size(); i++) {
23809                 ProcessRecord process = mLruProcesses.get(i);
23810                 if (!processSanityChecksLocked(process)) {
23811                     continue;
23812                 }
23813                 try {
23814                     process.thread.startBinderTracking();
23815                 } catch (RemoteException e) {
23816                     Log.v(TAG, "Process disappared");
23817                 }
23818             }
23819             return true;
23820         }
23821     }
23822
23823     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23824         try {
23825             synchronized (this) {
23826                 mBinderTransactionTrackingEnabled = false;
23827                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23828                 // permission (same as profileControl).
23829                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23830                         != PackageManager.PERMISSION_GRANTED) {
23831                     throw new SecurityException("Requires permission "
23832                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23833                 }
23834
23835                 if (fd == null) {
23836                     throw new IllegalArgumentException("null fd");
23837                 }
23838
23839                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23840                 pw.println("Binder transaction traces for all processes.\n");
23841                 for (ProcessRecord process : mLruProcesses) {
23842                     if (!processSanityChecksLocked(process)) {
23843                         continue;
23844                     }
23845
23846                     pw.println("Traces for process: " + process.processName);
23847                     pw.flush();
23848                     try {
23849                         TransferPipe tp = new TransferPipe();
23850                         try {
23851                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23852                             tp.go(fd.getFileDescriptor());
23853                         } finally {
23854                             tp.kill();
23855                         }
23856                     } catch (IOException e) {
23857                         pw.println("Failure while dumping IPC traces from " + process +
23858                                 ".  Exception: " + e);
23859                         pw.flush();
23860                     } catch (RemoteException e) {
23861                         pw.println("Got a RemoteException while dumping IPC traces from " +
23862                                 process + ".  Exception: " + e);
23863                         pw.flush();
23864                     }
23865                 }
23866                 fd = null;
23867                 return true;
23868             }
23869         } finally {
23870             if (fd != null) {
23871                 try {
23872                     fd.close();
23873                 } catch (IOException e) {
23874                 }
23875             }
23876         }
23877     }
23878
23879     @VisibleForTesting
23880     final class LocalService extends ActivityManagerInternal {
23881         @Override
23882         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23883                 int targetUserId) {
23884             synchronized (ActivityManagerService.this) {
23885                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23886                         targetPkg, intent, null, targetUserId);
23887             }
23888         }
23889
23890         @Override
23891         public String checkContentProviderAccess(String authority, int userId) {
23892             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23893         }
23894
23895         @Override
23896         public void onWakefulnessChanged(int wakefulness) {
23897             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23898         }
23899
23900         @Override
23901         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23902                 String processName, String abiOverride, int uid, Runnable crashHandler) {
23903             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23904                     processName, abiOverride, uid, crashHandler);
23905         }
23906
23907         @Override
23908         public SleepToken acquireSleepToken(String tag, int displayId) {
23909             Preconditions.checkNotNull(tag);
23910             return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23911         }
23912
23913         @Override
23914         public ComponentName getHomeActivityForUser(int userId) {
23915             synchronized (ActivityManagerService.this) {
23916                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23917                 return homeActivity == null ? null : homeActivity.realActivity;
23918             }
23919         }
23920
23921         @Override
23922         public void onUserRemoved(int userId) {
23923             synchronized (ActivityManagerService.this) {
23924                 ActivityManagerService.this.onUserStoppedLocked(userId);
23925             }
23926             mBatteryStatsService.onUserRemoved(userId);
23927         }
23928
23929         @Override
23930         public void onLocalVoiceInteractionStarted(IBinder activity,
23931                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23932             synchronized (ActivityManagerService.this) {
23933                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23934                         voiceSession, voiceInteractor);
23935             }
23936         }
23937
23938         @Override
23939         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23940             synchronized (ActivityManagerService.this) {
23941                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23942                         reasons, timestamp);
23943             }
23944         }
23945
23946         @Override
23947         public void notifyAppTransitionFinished() {
23948             synchronized (ActivityManagerService.this) {
23949                 mStackSupervisor.notifyAppTransitionDone();
23950             }
23951         }
23952
23953         @Override
23954         public void notifyAppTransitionCancelled() {
23955             synchronized (ActivityManagerService.this) {
23956                 mStackSupervisor.notifyAppTransitionDone();
23957             }
23958         }
23959
23960         @Override
23961         public List<IBinder> getTopVisibleActivities() {
23962             synchronized (ActivityManagerService.this) {
23963                 return mStackSupervisor.getTopVisibleActivities();
23964             }
23965         }
23966
23967         @Override
23968         public void notifyDockedStackMinimizedChanged(boolean minimized) {
23969             synchronized (ActivityManagerService.this) {
23970                 mStackSupervisor.setDockedStackMinimized(minimized);
23971             }
23972         }
23973
23974         @Override
23975         public void killForegroundAppsForUser(int userHandle) {
23976             synchronized (ActivityManagerService.this) {
23977                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23978                 final int NP = mProcessNames.getMap().size();
23979                 for (int ip = 0; ip < NP; ip++) {
23980                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23981                     final int NA = apps.size();
23982                     for (int ia = 0; ia < NA; ia++) {
23983                         final ProcessRecord app = apps.valueAt(ia);
23984                         if (app.persistent) {
23985                             // We don't kill persistent processes.
23986                             continue;
23987                         }
23988                         if (app.removed) {
23989                             procs.add(app);
23990                         } else if (app.userId == userHandle && app.foregroundActivities) {
23991                             app.removed = true;
23992                             procs.add(app);
23993                         }
23994                     }
23995                 }
23996
23997                 final int N = procs.size();
23998                 for (int i = 0; i < N; i++) {
23999                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
24000                 }
24001             }
24002         }
24003
24004         @Override
24005         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24006                 long duration) {
24007             if (!(target instanceof PendingIntentRecord)) {
24008                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24009                 return;
24010             }
24011             synchronized (ActivityManagerService.this) {
24012                 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24013             }
24014         }
24015
24016         @Override
24017         public void setDeviceIdleWhitelist(int[] appids) {
24018             synchronized (ActivityManagerService.this) {
24019                 mDeviceIdleWhitelist = appids;
24020             }
24021         }
24022
24023         @Override
24024         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24025             synchronized (ActivityManagerService.this) {
24026                 mDeviceIdleTempWhitelist = appids;
24027                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24028             }
24029         }
24030
24031         @Override
24032         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24033                 int userId) {
24034             Preconditions.checkNotNull(values, "Configuration must not be null");
24035             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24036             synchronized (ActivityManagerService.this) {
24037                 updateConfigurationLocked(values, null, false, true, userId,
24038                         false /* deferResume */);
24039             }
24040         }
24041
24042         @Override
24043         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24044                 Bundle bOptions) {
24045             Preconditions.checkNotNull(intents, "intents");
24046             final String[] resolvedTypes = new String[intents.length];
24047             for (int i = 0; i < intents.length; i++) {
24048                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24049             }
24050
24051             // UID of the package on user userId.
24052             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24053             // packageUid may not be initialized.
24054             int packageUid = 0;
24055             try {
24056                 packageUid = AppGlobals.getPackageManager().getPackageUid(
24057                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24058             } catch (RemoteException e) {
24059                 // Shouldn't happen.
24060             }
24061
24062             synchronized (ActivityManagerService.this) {
24063                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24064                         /*resultTo*/ null, bOptions, userId);
24065             }
24066         }
24067
24068         @Override
24069         public int getUidProcessState(int uid) {
24070             return getUidState(uid);
24071         }
24072
24073         @Override
24074         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24075             synchronized (ActivityManagerService.this) {
24076
24077                 // We might change the visibilities here, so prepare an empty app transition which
24078                 // might be overridden later if we actually change visibilities.
24079                 final boolean wasTransitionSet =
24080                         mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24081                 if (!wasTransitionSet) {
24082                     mWindowManager.prepareAppTransition(TRANSIT_NONE,
24083                             false /* alwaysKeepCurrent */);
24084                 }
24085                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24086
24087                 // If there was a transition set already we don't want to interfere with it as we
24088                 // might be starting it too early.
24089                 if (!wasTransitionSet) {
24090                     mWindowManager.executeAppTransition();
24091                 }
24092             }
24093             if (callback != null) {
24094                 callback.run();
24095             }
24096         }
24097
24098         @Override
24099         public boolean isSystemReady() {
24100             // no need to synchronize(this) just to read & return the value
24101             return mSystemReady;
24102         }
24103
24104         @Override
24105         public void notifyKeyguardTrustedChanged() {
24106             synchronized (ActivityManagerService.this) {
24107                 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24108                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24109                 }
24110             }
24111         }
24112
24113         /**
24114          * Sets if the given pid has an overlay UI or not.
24115          *
24116          * @param pid The pid we are setting overlay UI for.
24117          * @param hasOverlayUi True if the process has overlay UI.
24118          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24119          */
24120         @Override
24121         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24122             synchronized (ActivityManagerService.this) {
24123                 final ProcessRecord pr;
24124                 synchronized (mPidsSelfLocked) {
24125                     pr = mPidsSelfLocked.get(pid);
24126                     if (pr == null) {
24127                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24128                         return;
24129                     }
24130                 }
24131                 if (pr.hasOverlayUi == hasOverlayUi) {
24132                     return;
24133                 }
24134                 pr.hasOverlayUi = hasOverlayUi;
24135                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24136                 updateOomAdjLocked(pr, true);
24137             }
24138         }
24139
24140         /**
24141          * Called after the network policy rules are updated by
24142          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24143          * and {@param procStateSeq}.
24144          */
24145         @Override
24146         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24147             if (DEBUG_NETWORK) {
24148                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24149                         + uid + " seq: " + procStateSeq);
24150             }
24151             UidRecord record;
24152             synchronized (ActivityManagerService.this) {
24153                 record = mActiveUids.get(uid);
24154                 if (record == null) {
24155                     if (DEBUG_NETWORK) {
24156                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24157                                 + " procStateSeq: " + procStateSeq);
24158                     }
24159                     return;
24160                 }
24161             }
24162             synchronized (record.networkStateLock) {
24163                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24164                     if (DEBUG_NETWORK) {
24165                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24166                                 + " been handled for uid: " + uid);
24167                     }
24168                     return;
24169                 }
24170                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24171                 if (record.curProcStateSeq > procStateSeq) {
24172                     if (DEBUG_NETWORK) {
24173                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24174                                 + ", curProcstateSeq: " + record.curProcStateSeq
24175                                 + ", procStateSeq: " + procStateSeq);
24176                     }
24177                     return;
24178                 }
24179                 if (record.waitingForNetwork) {
24180                     if (DEBUG_NETWORK) {
24181                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24182                                 + ", procStateSeq: " + procStateSeq);
24183                     }
24184                     record.networkStateLock.notifyAll();
24185                 }
24186             }
24187         }
24188
24189         /**
24190          * Called after virtual display Id is updated by
24191          * {@link com.android.server.vr.Vr2dDisplay} with a specific
24192          * {@param vrVr2dDisplayId}.
24193          */
24194         @Override
24195         public void setVr2dDisplayId(int vr2dDisplayId) {
24196             if (DEBUG_STACK) {
24197                 Slog.d(TAG, "setVr2dDisplayId called for: " +
24198                         vr2dDisplayId);
24199             }
24200             synchronized (ActivityManagerService.this) {
24201                 mVr2dDisplayId = vr2dDisplayId;
24202             }
24203         }
24204
24205         @Override
24206         public void saveANRState(String reason) {
24207             synchronized (ActivityManagerService.this) {
24208                 final StringWriter sw = new StringWriter();
24209                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24210                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24211                 if (reason != null) {
24212                     pw.println("  Reason: " + reason);
24213                 }
24214                 pw.println();
24215                 mActivityStarter.dump(pw, "  ", null);
24216                 pw.println();
24217                 pw.println("-------------------------------------------------------------------------------");
24218                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24219                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24220                         "" /* header */);
24221                 pw.println();
24222                 pw.close();
24223
24224                 mLastANRState = sw.toString();
24225             }
24226         }
24227
24228         @Override
24229         public void clearSavedANRState() {
24230             synchronized (ActivityManagerService.this) {
24231                 mLastANRState = null;
24232             }
24233         }
24234
24235         @Override
24236         public void setFocusedActivity(IBinder token) {
24237             synchronized (ActivityManagerService.this) {
24238                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24239                 if (r == null) {
24240                     throw new IllegalArgumentException(
24241                             "setFocusedActivity: No activity record matching token=" + token);
24242                 }
24243                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24244                         r, "setFocusedActivity")) {
24245                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
24246                 }
24247             }
24248         }
24249
24250         @Override
24251         public void registerScreenObserver(ScreenObserver observer) {
24252             mScreenObservers.add(observer);
24253         }
24254     }
24255
24256     /**
24257      * Called by app main thread to wait for the network policy rules to get updated.
24258      *
24259      * @param procStateSeq The sequence number indicating the process state change that the main
24260      *                     thread is interested in.
24261      */
24262     @Override
24263     public void waitForNetworkStateUpdate(long procStateSeq) {
24264         final int callingUid = Binder.getCallingUid();
24265         if (DEBUG_NETWORK) {
24266             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24267         }
24268         UidRecord record;
24269         synchronized (this) {
24270             record = mActiveUids.get(callingUid);
24271             if (record == null) {
24272                 return;
24273             }
24274         }
24275         synchronized (record.networkStateLock) {
24276             if (record.lastDispatchedProcStateSeq < procStateSeq) {
24277                 if (DEBUG_NETWORK) {
24278                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24279                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24280                             + " lastProcStateSeqDispatchedToObservers: "
24281                             + record.lastDispatchedProcStateSeq);
24282                 }
24283                 return;
24284             }
24285             if (record.curProcStateSeq > procStateSeq) {
24286                 if (DEBUG_NETWORK) {
24287                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24288                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24289                             + ", procStateSeq: " + procStateSeq);
24290                 }
24291                 return;
24292             }
24293             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24294                 if (DEBUG_NETWORK) {
24295                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24296                             + procStateSeq + ", so no need to wait. Uid: "
24297                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24298                             + record.lastNetworkUpdatedProcStateSeq);
24299                 }
24300                 return;
24301             }
24302             try {
24303                 if (DEBUG_NETWORK) {
24304                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24305                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24306                 }
24307                 final long startTime = SystemClock.uptimeMillis();
24308                 record.waitingForNetwork = true;
24309                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24310                 record.waitingForNetwork = false;
24311                 final long totalTime = SystemClock.uptimeMillis() - startTime;
24312                 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24313                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24314                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24315                             + procStateSeq + " UidRec: " + record
24316                             + " validateUidRec: " + mValidateUids.get(callingUid));
24317                 }
24318             } catch (InterruptedException e) {
24319                 Thread.currentThread().interrupt();
24320             }
24321         }
24322     }
24323
24324     public void waitForBroadcastIdle(PrintWriter pw) {
24325         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24326         while (true) {
24327             boolean idle = true;
24328             synchronized (this) {
24329                 for (BroadcastQueue queue : mBroadcastQueues) {
24330                     if (!queue.isIdle()) {
24331                         final String msg = "Waiting for queue " + queue + " to become idle...";
24332                         pw.println(msg);
24333                         pw.flush();
24334                         Slog.v(TAG, msg);
24335                         idle = false;
24336                     }
24337                 }
24338             }
24339
24340             if (idle) {
24341                 final String msg = "All broadcast queues are idle!";
24342                 pw.println(msg);
24343                 pw.flush();
24344                 Slog.v(TAG, msg);
24345                 return;
24346             } else {
24347                 SystemClock.sleep(1000);
24348             }
24349         }
24350     }
24351
24352     /**
24353      * Return the user id of the last resumed activity.
24354      */
24355     @Override
24356     public @UserIdInt int getLastResumedActivityUserId() {
24357         enforceCallingPermission(
24358                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24359         synchronized (this) {
24360             if (mLastResumedActivity == null) {
24361                 return mUserController.getCurrentUserIdLocked();
24362             }
24363             return mLastResumedActivity.userId;
24364         }
24365     }
24366
24367     /**
24368      * An implementation of IAppTask, that allows an app to manage its own tasks via
24369      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24370      * only the process that calls getAppTasks() can call the AppTask methods.
24371      */
24372     class AppTaskImpl extends IAppTask.Stub {
24373         private int mTaskId;
24374         private int mCallingUid;
24375
24376         public AppTaskImpl(int taskId, int callingUid) {
24377             mTaskId = taskId;
24378             mCallingUid = callingUid;
24379         }
24380
24381         private void checkCaller() {
24382             if (mCallingUid != Binder.getCallingUid()) {
24383                 throw new SecurityException("Caller " + mCallingUid
24384                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24385             }
24386         }
24387
24388         @Override
24389         public void finishAndRemoveTask() {
24390             checkCaller();
24391
24392             synchronized (ActivityManagerService.this) {
24393                 long origId = Binder.clearCallingIdentity();
24394                 try {
24395                     // We remove the task from recents to preserve backwards
24396                     if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24397                             REMOVE_FROM_RECENTS)) {
24398                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24399                     }
24400                 } finally {
24401                     Binder.restoreCallingIdentity(origId);
24402                 }
24403             }
24404         }
24405
24406         @Override
24407         public ActivityManager.RecentTaskInfo getTaskInfo() {
24408             checkCaller();
24409
24410             synchronized (ActivityManagerService.this) {
24411                 long origId = Binder.clearCallingIdentity();
24412                 try {
24413                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24414                     if (tr == null) {
24415                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24416                     }
24417                     return createRecentTaskInfoFromTaskRecord(tr);
24418                 } finally {
24419                     Binder.restoreCallingIdentity(origId);
24420                 }
24421             }
24422         }
24423
24424         @Override
24425         public void moveToFront() {
24426             checkCaller();
24427             // Will bring task to front if it already has a root activity.
24428             final long origId = Binder.clearCallingIdentity();
24429             try {
24430                 synchronized (this) {
24431                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24432                 }
24433             } finally {
24434                 Binder.restoreCallingIdentity(origId);
24435             }
24436         }
24437
24438         @Override
24439         public int startActivity(IBinder whoThread, String callingPackage,
24440                 Intent intent, String resolvedType, Bundle bOptions) {
24441             checkCaller();
24442
24443             int callingUser = UserHandle.getCallingUserId();
24444             TaskRecord tr;
24445             IApplicationThread appThread;
24446             synchronized (ActivityManagerService.this) {
24447                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24448                 if (tr == null) {
24449                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24450                 }
24451                 appThread = IApplicationThread.Stub.asInterface(whoThread);
24452                 if (appThread == null) {
24453                     throw new IllegalArgumentException("Bad app thread " + appThread);
24454                 }
24455             }
24456             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24457                     resolvedType, null, null, null, null, 0, 0, null, null,
24458                     null, bOptions, false, callingUser, tr, "AppTaskImpl");
24459         }
24460
24461         @Override
24462         public void setExcludeFromRecents(boolean exclude) {
24463             checkCaller();
24464
24465             synchronized (ActivityManagerService.this) {
24466                 long origId = Binder.clearCallingIdentity();
24467                 try {
24468                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24469                     if (tr == null) {
24470                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24471                     }
24472                     Intent intent = tr.getBaseIntent();
24473                     if (exclude) {
24474                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24475                     } else {
24476                         intent.setFlags(intent.getFlags()
24477                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24478                     }
24479                 } finally {
24480                     Binder.restoreCallingIdentity(origId);
24481                 }
24482             }
24483         }
24484     }
24485
24486     /**
24487      * Kill processes for the user with id userId and that depend on the package named packageName
24488      */
24489     @Override
24490     public void killPackageDependents(String packageName, int userId) {
24491         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24492         if (packageName == null) {
24493             throw new NullPointerException(
24494                     "Cannot kill the dependents of a package without its name.");
24495         }
24496
24497         long callingId = Binder.clearCallingIdentity();
24498         IPackageManager pm = AppGlobals.getPackageManager();
24499         int pkgUid = -1;
24500         try {
24501             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24502         } catch (RemoteException e) {
24503         }
24504         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24505             throw new IllegalArgumentException(
24506                     "Cannot kill dependents of non-existing package " + packageName);
24507         }
24508         try {
24509             synchronized(this) {
24510                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24511                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24512                         "dep: " + packageName);
24513             }
24514         } finally {
24515             Binder.restoreCallingIdentity(callingId);
24516         }
24517     }
24518
24519     @Override
24520     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24521             throws RemoteException {
24522         final long callingId = Binder.clearCallingIdentity();
24523         try {
24524             mKeyguardController.dismissKeyguard(token, callback);
24525         } finally {
24526             Binder.restoreCallingIdentity(callingId);
24527         }
24528     }
24529
24530     @Override
24531     public int restartUserInBackground(final int userId) {
24532         return mUserController.restartUser(userId, /* foreground */ false);
24533     }
24534
24535     @Override
24536     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24537         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24538                 "scheduleApplicationInfoChanged()");
24539
24540         synchronized (this) {
24541             final long origId = Binder.clearCallingIdentity();
24542             try {
24543                 updateApplicationInfoLocked(packageNames, userId);
24544             } finally {
24545                 Binder.restoreCallingIdentity(origId);
24546             }
24547         }
24548     }
24549
24550     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24551         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24552         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24553             final ProcessRecord app = mLruProcesses.get(i);
24554             if (app.thread == null) {
24555                 continue;
24556             }
24557
24558             if (userId != UserHandle.USER_ALL && app.userId != userId) {
24559                 continue;
24560             }
24561
24562             final int packageCount = app.pkgList.size();
24563             for (int j = 0; j < packageCount; j++) {
24564                 final String packageName = app.pkgList.keyAt(j);
24565                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24566                     try {
24567                         final ApplicationInfo ai = AppGlobals.getPackageManager()
24568                                 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24569                         if (ai != null) {
24570                             app.thread.scheduleApplicationInfoChanged(ai);
24571                         }
24572                     } catch (RemoteException e) {
24573                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24574                                     packageName, app));
24575                     }
24576                 }
24577             }
24578         }
24579     }
24580
24581     /**
24582      * Attach an agent to the specified process (proces name or PID)
24583      */
24584     public void attachAgent(String process, String path) {
24585         try {
24586             synchronized (this) {
24587                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24588                 if (proc == null || proc.thread == null) {
24589                     throw new IllegalArgumentException("Unknown process: " + process);
24590                 }
24591
24592                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24593                 if (!isDebuggable) {
24594                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24595                         throw new SecurityException("Process not debuggable: " + proc);
24596                     }
24597                 }
24598
24599                 proc.thread.attachAgent(path);
24600             }
24601         } catch (RemoteException e) {
24602             throw new IllegalStateException("Process disappeared");
24603         }
24604     }
24605
24606     @VisibleForTesting
24607     public static class Injector {
24608         private NetworkManagementInternal mNmi;
24609
24610         public Context getContext() {
24611             return null;
24612         }
24613
24614         public AppOpsService getAppOpsService(File file, Handler handler) {
24615             return new AppOpsService(file, handler);
24616         }
24617
24618         public Handler getUiHandler(ActivityManagerService service) {
24619             return service.new UiHandler();
24620         }
24621
24622         public boolean isNetworkRestrictedForUid(int uid) {
24623             if (ensureHasNetworkManagementInternal()) {
24624                 return mNmi.isNetworkRestrictedForUid(uid);
24625             }
24626             return false;
24627         }
24628
24629         private boolean ensureHasNetworkManagementInternal() {
24630             if (mNmi == null) {
24631                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24632             }
24633             return mNmi != null;
24634         }
24635     }
24636
24637     @Override
24638     public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24639             throws RemoteException {
24640         synchronized (this) {
24641             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24642             if (r == null) {
24643                 return;
24644             }
24645             final long origId = Binder.clearCallingIdentity();
24646             try {
24647                 r.setShowWhenLocked(showWhenLocked);
24648             } finally {
24649                 Binder.restoreCallingIdentity(origId);
24650             }
24651         }
24652     }
24653
24654     @Override
24655     public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24656         synchronized (this) {
24657             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24658             if (r == null) {
24659                 return;
24660             }
24661             final long origId = Binder.clearCallingIdentity();
24662             try {
24663                 r.setTurnScreenOn(turnScreenOn);
24664             } finally {
24665                 Binder.restoreCallingIdentity(origId);
24666             }
24667         }
24668     }
24669 }