ActivityManagerService.java revision 18d501ac172bc78867f6d9031560dfe5ab31b541
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
17package com.android.server.am;
18
19import static android.Manifest.permission.CHANGE_CONFIGURATION;
20import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
24import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25import static android.Manifest.permission.READ_FRAME_BUFFER;
26import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
28import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
29import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
30import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
31import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
32import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
33import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
34import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
35import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
36import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
37import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
38import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
39import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
40import static android.content.pm.PackageManager.GET_PROVIDERS;
41import static android.content.pm.PackageManager.MATCH_ANY_USER;
42import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
43import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
44import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
45import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
46import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
47import static android.content.pm.PackageManager.PERMISSION_GRANTED;
48import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
49import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
50import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
51import static android.os.Build.VERSION_CODES.N;
52import static android.os.Process.BLUETOOTH_UID;
53import static android.os.Process.FIRST_APPLICATION_UID;
54import static android.os.Process.FIRST_ISOLATED_UID;
55import static android.os.Process.LAST_ISOLATED_UID;
56import static android.os.Process.NFC_UID;
57import static android.os.Process.PHONE_UID;
58import static android.os.Process.PROC_CHAR;
59import static android.os.Process.PROC_OUT_LONG;
60import static android.os.Process.PROC_PARENS;
61import static android.os.Process.PROC_SPACE_TERM;
62import static android.os.Process.ProcessStartResult;
63import static android.os.Process.ROOT_UID;
64import static android.os.Process.SCHED_FIFO;
65import static android.os.Process.SCHED_OTHER;
66import static android.os.Process.SCHED_RESET_ON_FORK;
67import static android.os.Process.SHELL_UID;
68import static android.os.Process.SIGNAL_QUIT;
69import static android.os.Process.SIGNAL_USR1;
70import static android.os.Process.SYSTEM_UID;
71import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
72import static android.os.Process.THREAD_GROUP_DEFAULT;
73import static android.os.Process.THREAD_GROUP_TOP_APP;
74import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
75import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
76import static android.os.Process.getFreeMemory;
77import static android.os.Process.getTotalMemory;
78import static android.os.Process.isThreadInProcess;
79import static android.os.Process.killProcess;
80import static android.os.Process.killProcessQuiet;
81import static android.os.Process.myPid;
82import static android.os.Process.myUid;
83import static android.os.Process.readProcFile;
84import static android.os.Process.removeAllProcessGroups;
85import static android.os.Process.sendSignal;
86import static android.os.Process.setProcessGroup;
87import static android.os.Process.setThreadPriority;
88import static android.os.Process.setThreadScheduler;
89import static android.os.Process.startWebView;
90import static android.os.Process.zygoteProcess;
91import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
92import static android.provider.Settings.Global.DEBUG_APP;
93import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
94import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
95import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
96import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
97import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
98import static android.provider.Settings.System.FONT_SCALE;
99import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
100import static android.text.format.DateUtils.DAY_IN_MILLIS;
101import static android.view.Display.DEFAULT_DISPLAY;
102import static android.view.Display.INVALID_DISPLAY;
103import static com.android.internal.util.XmlUtils.readBooleanAttribute;
104import static com.android.internal.util.XmlUtils.readIntAttribute;
105import static com.android.internal.util.XmlUtils.readLongAttribute;
106import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
107import static com.android.internal.util.XmlUtils.writeIntAttribute;
108import static com.android.internal.util.XmlUtils.writeLongAttribute;
109import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
110import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
111import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
112import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
113import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
114import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
115import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
116import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
117import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
118import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
119import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
120import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
121import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
122import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
123import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
124import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
125import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
126import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
127import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
141import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
152import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
153import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
154import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
155import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
156import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
157import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
158import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
159import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
160import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
161import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
162import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
163import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
164import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
165import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
166import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
167import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
168import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
169import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
170import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
171import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
172import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
173import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
174import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
175import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
176import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
177import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
178import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
179import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
180import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
181import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
182import static com.android.server.wm.AppTransition.TRANSIT_NONE;
183import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
184import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
185import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
186import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
187import static org.xmlpull.v1.XmlPullParser.START_TAG;
188
189import android.Manifest;
190import android.Manifest.permission;
191import android.annotation.NonNull;
192import android.annotation.Nullable;
193import android.annotation.UserIdInt;
194import android.app.Activity;
195import android.app.ActivityManager;
196import android.app.ActivityManager.RunningTaskInfo;
197import android.app.ActivityManager.StackId;
198import android.app.ActivityManager.StackInfo;
199import android.app.ActivityManager.TaskSnapshot;
200import android.app.ActivityManagerInternal;
201import android.app.ActivityManagerInternal.SleepToken;
202import android.app.ActivityOptions;
203import android.app.ActivityThread;
204import android.app.AlertDialog;
205import android.app.AppGlobals;
206import android.app.AppOpsManager;
207import android.app.ApplicationErrorReport;
208import android.app.ApplicationThreadConstants;
209import android.app.BroadcastOptions;
210import android.app.ContentProviderHolder;
211import android.app.Dialog;
212import android.app.IActivityController;
213import android.app.IActivityManager;
214import android.app.IAppTask;
215import android.app.IApplicationThread;
216import android.app.IInstrumentationWatcher;
217import android.app.INotificationManager;
218import android.app.IProcessObserver;
219import android.app.IServiceConnection;
220import android.app.IStopUserCallback;
221import android.app.ITaskStackListener;
222import android.app.IUiAutomationConnection;
223import android.app.IUidObserver;
224import android.app.IUserSwitchObserver;
225import android.app.Instrumentation;
226import android.app.Notification;
227import android.app.NotificationManager;
228import android.app.PendingIntent;
229import android.app.PictureInPictureParams;
230import android.app.ProfilerInfo;
231import android.app.RemoteAction;
232import android.app.WaitResult;
233import android.app.admin.DevicePolicyManager;
234import android.app.assist.AssistContent;
235import android.app.assist.AssistStructure;
236import android.app.backup.IBackupManager;
237import android.app.usage.UsageEvents;
238import android.app.usage.UsageStatsManagerInternal;
239import android.appwidget.AppWidgetManager;
240import android.content.ActivityNotFoundException;
241import android.content.BroadcastReceiver;
242import android.content.ClipData;
243import android.content.ComponentCallbacks2;
244import android.content.ComponentName;
245import android.content.ContentProvider;
246import android.content.ContentResolver;
247import android.content.Context;
248import android.content.DialogInterface;
249import android.content.IContentProvider;
250import android.content.IIntentReceiver;
251import android.content.IIntentSender;
252import android.content.Intent;
253import android.content.IntentFilter;
254import android.content.pm.ActivityInfo;
255import android.content.pm.ApplicationInfo;
256import android.content.pm.ConfigurationInfo;
257import android.content.pm.IPackageDataObserver;
258import android.content.pm.IPackageManager;
259import android.content.pm.InstrumentationInfo;
260import android.content.pm.PackageInfo;
261import android.content.pm.PackageManager;
262import android.content.pm.PackageManager.NameNotFoundException;
263import android.content.pm.PackageManagerInternal;
264import android.content.pm.ParceledListSlice;
265import android.content.pm.PathPermission;
266import android.content.pm.PermissionInfo;
267import android.content.pm.ProviderInfo;
268import android.content.pm.ResolveInfo;
269import android.content.pm.SELinuxUtil;
270import android.content.pm.ServiceInfo;
271import android.content.pm.UserInfo;
272import android.content.res.CompatibilityInfo;
273import android.content.res.Configuration;
274import android.content.res.Resources;
275import android.database.ContentObserver;
276import android.graphics.Bitmap;
277import android.graphics.Point;
278import android.graphics.Rect;
279import android.location.LocationManager;
280import android.media.audiofx.AudioEffect;
281import android.metrics.LogMaker;
282import android.net.Proxy;
283import android.net.ProxyInfo;
284import android.net.Uri;
285import android.os.BatteryStats;
286import android.os.Binder;
287import android.os.Build;
288import android.os.Bundle;
289import android.os.Debug;
290import android.os.DropBoxManager;
291import android.os.Environment;
292import android.os.FactoryTest;
293import android.os.FileObserver;
294import android.os.FileUtils;
295import android.os.Handler;
296import android.os.IBinder;
297import android.os.IDeviceIdentifiersPolicyService;
298import android.os.IPermissionController;
299import android.os.IProcessInfoService;
300import android.os.IProgressListener;
301import android.os.LocaleList;
302import android.os.Looper;
303import android.os.Message;
304import android.os.Parcel;
305import android.os.ParcelFileDescriptor;
306import android.os.PersistableBundle;
307import android.os.PowerManager;
308import android.os.PowerManagerInternal;
309import android.os.Process;
310import android.os.RemoteCallbackList;
311import android.os.RemoteException;
312import android.os.ResultReceiver;
313import android.os.ServiceManager;
314import android.os.ShellCallback;
315import android.os.StrictMode;
316import android.os.SystemClock;
317import android.os.SystemProperties;
318import android.os.Trace;
319import android.os.TransactionTooLargeException;
320import android.os.UpdateLock;
321import android.os.UserHandle;
322import android.os.UserManager;
323import android.os.WorkSource;
324import android.os.storage.IStorageManager;
325import android.os.storage.StorageManager;
326import android.os.storage.StorageManagerInternal;
327import android.provider.Downloads;
328import android.provider.Settings;
329import android.service.voice.IVoiceInteractionSession;
330import android.service.voice.VoiceInteractionManagerInternal;
331import android.service.voice.VoiceInteractionSession;
332import android.telecom.TelecomManager;
333import android.text.TextUtils;
334import android.text.format.DateUtils;
335import android.text.format.Time;
336import android.text.style.SuggestionSpan;
337import android.util.ArrayMap;
338import android.util.ArraySet;
339import android.util.AtomicFile;
340import android.util.TimingsTraceLog;
341import android.util.DebugUtils;
342import android.util.DisplayMetrics;
343import android.util.EventLog;
344import android.util.Log;
345import android.util.Pair;
346import android.util.PrintWriterPrinter;
347import android.util.Slog;
348import android.util.SparseArray;
349import android.util.SparseIntArray;
350import android.util.TimeUtils;
351import android.util.Xml;
352import android.view.Gravity;
353import android.view.LayoutInflater;
354import android.view.View;
355import android.view.WindowManager;
356
357import com.android.internal.R;
358import com.android.internal.annotations.GuardedBy;
359import com.android.internal.annotations.VisibleForTesting;
360import com.android.internal.app.AssistUtils;
361import com.android.internal.app.DumpHeapActivity;
362import com.android.internal.app.IAppOpsCallback;
363import com.android.internal.app.IAppOpsService;
364import com.android.internal.app.IVoiceInteractor;
365import com.android.internal.app.ProcessMap;
366import com.android.internal.app.SystemUserHomeActivity;
367import com.android.internal.app.procstats.ProcessStats;
368import com.android.internal.logging.MetricsLogger;
369import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
370import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
371import com.android.internal.notification.SystemNotificationChannels;
372import com.android.internal.os.BackgroundThread;
373import com.android.internal.os.BatteryStatsImpl;
374import com.android.internal.os.IResultReceiver;
375import com.android.internal.os.ProcessCpuTracker;
376import com.android.internal.os.TransferPipe;
377import com.android.internal.os.Zygote;
378import com.android.internal.policy.IKeyguardDismissCallback;
379import com.android.internal.telephony.TelephonyIntents;
380import com.android.internal.util.ArrayUtils;
381import com.android.internal.util.DumpUtils;
382import com.android.internal.util.FastPrintWriter;
383import com.android.internal.util.FastXmlSerializer;
384import com.android.internal.util.MemInfoReader;
385import com.android.internal.util.Preconditions;
386import com.android.server.AppOpsService;
387import com.android.server.AttributeCache;
388import com.android.server.DeviceIdleController;
389import com.android.server.IntentResolver;
390import com.android.server.LocalServices;
391import com.android.server.LockGuard;
392import com.android.server.NetworkManagementInternal;
393import com.android.server.RescueParty;
394import com.android.server.ServiceThread;
395import com.android.server.SystemConfig;
396import com.android.server.SystemService;
397import com.android.server.SystemServiceManager;
398import com.android.server.ThreadPriorityBooster;
399import com.android.server.Watchdog;
400import com.android.server.am.ActivityStack.ActivityState;
401import com.android.server.firewall.IntentFirewall;
402import com.android.server.job.JobSchedulerInternal;
403import com.android.server.pm.Installer;
404import com.android.server.pm.Installer.InstallerException;
405import com.android.server.vr.VrManagerInternal;
406import com.android.server.wm.PinnedStackWindowController;
407import com.android.server.wm.WindowManagerService;
408import com.google.android.collect.Lists;
409import com.google.android.collect.Maps;
410
411import org.xmlpull.v1.XmlPullParser;
412import org.xmlpull.v1.XmlPullParserException;
413import org.xmlpull.v1.XmlSerializer;
414
415import java.io.File;
416import java.io.FileDescriptor;
417import java.io.FileInputStream;
418import java.io.FileNotFoundException;
419import java.io.FileOutputStream;
420import java.io.IOException;
421import java.io.InputStreamReader;
422import java.io.PrintWriter;
423import java.io.StringWriter;
424import java.io.UnsupportedEncodingException;
425import java.lang.ref.WeakReference;
426import java.nio.charset.StandardCharsets;
427import java.text.DateFormat;
428import java.text.SimpleDateFormat;
429import java.util.ArrayList;
430import java.util.Arrays;
431import java.util.Collections;
432import java.util.Comparator;
433import java.util.Date;
434import java.util.HashMap;
435import java.util.HashSet;
436import java.util.Iterator;
437import java.util.List;
438import java.util.Locale;
439import java.util.Map;
440import java.util.Objects;
441import java.util.Set;
442import java.util.concurrent.CountDownLatch;
443import java.util.concurrent.atomic.AtomicBoolean;
444import java.util.concurrent.atomic.AtomicLong;
445
446import dalvik.system.VMRuntime;
447import libcore.io.IoUtils;
448import libcore.util.EmptyArray;
449
450public class ActivityManagerService extends IActivityManager.Stub
451        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
452
453    /**
454     * Priority we boost main thread and RT of top app to.
455     */
456    public static final int TOP_APP_PRIORITY_BOOST = -10;
457
458    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
459    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
460    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
461    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
462    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
463    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
464    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
465    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
466    private static final String TAG_LRU = TAG + POSTFIX_LRU;
467    private static final String TAG_MU = TAG + POSTFIX_MU;
468    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
469    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
470    private static final String TAG_POWER = TAG + POSTFIX_POWER;
471    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
472    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
473    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
474    private static final String TAG_PSS = TAG + POSTFIX_PSS;
475    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
476    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
477    private static final String TAG_STACK = TAG + POSTFIX_STACK;
478    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
479    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
480    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
481    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
482
483    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
484    // here so that while the job scheduler can depend on AMS, the other way around
485    // need not be the case.
486    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
487
488    /** Control over CPU and battery monitoring */
489    // write battery stats every 30 minutes.
490    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
491    static final boolean MONITOR_CPU_USAGE = true;
492    // don't sample cpu less than every 5 seconds.
493    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
494    // wait possibly forever for next cpu sample.
495    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
496    static final boolean MONITOR_THREAD_CPU_USAGE = false;
497
498    // The flags that are set for all calls we make to the package manager.
499    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
500
501    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
502
503    // Amount of time after a call to stopAppSwitches() during which we will
504    // prevent further untrusted switches from happening.
505    static final long APP_SWITCH_DELAY_TIME = 5*1000;
506
507    // How long we wait for a launched process to attach to the activity manager
508    // before we decide it's never going to come up for real.
509    static final int PROC_START_TIMEOUT = 10*1000;
510    // How long we wait for an attached process to publish its content providers
511    // before we decide it must be hung.
512    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
513
514    // How long we wait for a launched process to attach to the activity manager
515    // before we decide it's never going to come up for real, when the process was
516    // started with a wrapper for instrumentation (such as Valgrind) because it
517    // could take much longer than usual.
518    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
519
520    // How long we allow a receiver to run before giving up on it.
521    static final int BROADCAST_FG_TIMEOUT = 10*1000;
522    static final int BROADCAST_BG_TIMEOUT = 60*1000;
523
524    // How long we wait until we timeout on key dispatching.
525    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
526
527    // How long we wait until we timeout on key dispatching during instrumentation.
528    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
529
530    // How long to wait in getAssistContextExtras for the activity and foreground services
531    // to respond with the result.
532    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
533
534    // How long top wait when going through the modern assist (which doesn't need to block
535    // on getting this result before starting to launch its UI).
536    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
537
538    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
539    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
540
541    // Maximum number of persisted Uri grants a package is allowed
542    static final int MAX_PERSISTED_URI_GRANTS = 128;
543
544    static final int MY_PID = myPid();
545
546    static final String[] EMPTY_STRING_ARRAY = new String[0];
547
548    // How many bytes to write into the dropbox log before truncating
549    static final int DROPBOX_MAX_SIZE = 192 * 1024;
550    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
551    // as one line, but close enough for now.
552    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
553
554    // Access modes for handleIncomingUser.
555    static final int ALLOW_NON_FULL = 0;
556    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
557    static final int ALLOW_FULL_ONLY = 2;
558
559    // Necessary ApplicationInfo flags to mark an app as persistent
560    private static final int PERSISTENT_MASK =
561            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
562
563    // Intent sent when remote bugreport collection has been completed
564    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
565            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
566
567    // Used to indicate that an app transition should be animated.
568    static final boolean ANIMATE = true;
569
570    // Determines whether to take full screen screenshots
571    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
572
573    /**
574     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
575     */
576    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
577
578    /**
579     * State indicating that there is no need for any blocking for network.
580     */
581    @VisibleForTesting
582    static final int NETWORK_STATE_NO_CHANGE = 0;
583
584    /**
585     * State indicating that the main thread needs to be informed about the network wait.
586     */
587    @VisibleForTesting
588    static final int NETWORK_STATE_BLOCK = 1;
589
590    /**
591     * State indicating that any threads waiting for network state to get updated can be unblocked.
592     */
593    @VisibleForTesting
594    static final int NETWORK_STATE_UNBLOCK = 2;
595
596    // Max character limit for a notification title. If the notification title is larger than this
597    // the notification will not be legible to the user.
598    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
599
600    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
601
602    /** All system services */
603    SystemServiceManager mSystemServiceManager;
604    AssistUtils mAssistUtils;
605
606    private Installer mInstaller;
607
608    /** Run all ActivityStacks through this */
609    final ActivityStackSupervisor mStackSupervisor;
610    private final KeyguardController mKeyguardController;
611
612    final ActivityStarter mActivityStarter;
613
614    final TaskChangeNotificationController mTaskChangeNotificationController;
615
616    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
617
618    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
619
620    public final IntentFirewall mIntentFirewall;
621
622    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
623    // default action automatically.  Important for devices without direct input
624    // devices.
625    private boolean mShowDialogs = true;
626
627    private final VrController mVrController;
628
629    // VR Vr2d Display Id.
630    int mVr2dDisplayId = INVALID_DISPLAY;
631
632    // Whether we should use SCHED_FIFO for UI and RenderThreads.
633    private boolean mUseFifoUiScheduling = false;
634
635    BroadcastQueue mFgBroadcastQueue;
636    BroadcastQueue mBgBroadcastQueue;
637    // Convenient for easy iteration over the queues. Foreground is first
638    // so that dispatch of foreground broadcasts gets precedence.
639    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
640
641    BroadcastStats mLastBroadcastStats;
642    BroadcastStats mCurBroadcastStats;
643
644    BroadcastQueue broadcastQueueForIntent(Intent intent) {
645        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
646        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
647                "Broadcast intent " + intent + " on "
648                + (isFg ? "foreground" : "background") + " queue");
649        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
650    }
651
652    /**
653     * The last resumed activity. This is identical to the current resumed activity most
654     * of the time but could be different when we're pausing one activity before we resume
655     * another activity.
656     */
657    private ActivityRecord mLastResumedActivity;
658
659    /**
660     * If non-null, we are tracking the time the user spends in the currently focused app.
661     */
662    private AppTimeTracker mCurAppTimeTracker;
663
664    /**
665     * List of intents that were used to start the most recent tasks.
666     */
667    final RecentTasks mRecentTasks;
668
669    /**
670     * For addAppTask: cached of the last activity component that was added.
671     */
672    ComponentName mLastAddedTaskComponent;
673
674    /**
675     * For addAppTask: cached of the last activity uid that was added.
676     */
677    int mLastAddedTaskUid;
678
679    /**
680     * For addAppTask: cached of the last ActivityInfo that was added.
681     */
682    ActivityInfo mLastAddedTaskActivity;
683
684    /**
685     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
686     */
687    String mDeviceOwnerName;
688
689    /**
690     * The controller for all operations related to locktask.
691     */
692    final LockTaskController mLockTaskController;
693
694    final UserController mUserController;
695
696    final AppErrors mAppErrors;
697
698    /**
699     * Dump of the activity state at the time of the last ANR. Cleared after
700     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
701     */
702    String mLastANRState;
703
704    /**
705     * Indicates the maximum time spent waiting for the network rules to get updated.
706     */
707    @VisibleForTesting
708    long mWaitForNetworkTimeoutMs;
709
710    public boolean canShowErrorDialogs() {
711        return mShowDialogs && !mSleeping && !mShuttingDown
712                && !mKeyguardController.isKeyguardShowing()
713                && !(UserManager.isDeviceInDemoMode(mContext)
714                        && mUserController.getCurrentUser().isDemo());
715    }
716
717    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
718            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
719
720    static void boostPriorityForLockedSection() {
721        sThreadPriorityBooster.boost();
722    }
723
724    static void resetPriorityAfterLockedSection() {
725        sThreadPriorityBooster.reset();
726    }
727
728    public class PendingAssistExtras extends Binder implements Runnable {
729        public final ActivityRecord activity;
730        public boolean isHome;
731        public final Bundle extras;
732        public final Intent intent;
733        public final String hint;
734        public final IResultReceiver receiver;
735        public final int userHandle;
736        public boolean haveResult = false;
737        public Bundle result = null;
738        public AssistStructure structure = null;
739        public AssistContent content = null;
740        public Bundle receiverExtras;
741
742        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
743                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
744            activity = _activity;
745            extras = _extras;
746            intent = _intent;
747            hint = _hint;
748            receiver = _receiver;
749            receiverExtras = _receiverExtras;
750            userHandle = _userHandle;
751        }
752
753        @Override
754        public void run() {
755            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
756            synchronized (this) {
757                haveResult = true;
758                notifyAll();
759            }
760            pendingAssistExtrasTimedOut(this);
761        }
762    }
763
764    final ArrayList<PendingAssistExtras> mPendingAssistExtras
765            = new ArrayList<PendingAssistExtras>();
766
767    /**
768     * Process management.
769     */
770    final ProcessList mProcessList = new ProcessList();
771
772    /**
773     * All of the applications we currently have running organized by name.
774     * The keys are strings of the application package name (as
775     * returned by the package manager), and the keys are ApplicationRecord
776     * objects.
777     */
778    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
779
780    /**
781     * Tracking long-term execution of processes to look for abuse and other
782     * bad app behavior.
783     */
784    final ProcessStatsService mProcessStats;
785
786    /**
787     * The currently running isolated processes.
788     */
789    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
790
791    /**
792     * Counter for assigning isolated process uids, to avoid frequently reusing the
793     * same ones.
794     */
795    int mNextIsolatedProcessUid = 0;
796
797    /**
798     * The currently running heavy-weight process, if any.
799     */
800    ProcessRecord mHeavyWeightProcess = null;
801
802    /**
803     * Non-persistent appId whitelist for background restrictions
804     */
805    int[] mBackgroundAppIdWhitelist = new int[] {
806            BLUETOOTH_UID
807    };
808
809    /**
810     * Broadcast actions that will always be deliverable to unlaunched/background apps
811     */
812    ArraySet<String> mBackgroundLaunchBroadcasts;
813
814    /**
815     * All of the processes we currently have running organized by pid.
816     * The keys are the pid running the application.
817     *
818     * <p>NOTE: This object is protected by its own lock, NOT the global
819     * activity manager lock!
820     */
821    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
822
823    /**
824     * All of the processes that have been forced to be important.  The key
825     * is the pid of the caller who requested it (we hold a death
826     * link on it).
827     */
828    abstract class ImportanceToken implements IBinder.DeathRecipient {
829        final int pid;
830        final IBinder token;
831        final String reason;
832
833        ImportanceToken(int _pid, IBinder _token, String _reason) {
834            pid = _pid;
835            token = _token;
836            reason = _reason;
837        }
838
839        @Override
840        public String toString() {
841            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
842                    + " " + reason + " " + pid + " " + token + " }";
843        }
844    }
845    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
846
847    /**
848     * List of records for processes that someone had tried to start before the
849     * system was ready.  We don't start them at that point, but ensure they
850     * are started by the time booting is complete.
851     */
852    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
853
854    /**
855     * List of persistent applications that are in the process
856     * of being started.
857     */
858    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
859
860    /**
861     * Processes that are being forcibly torn down.
862     */
863    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
864
865    /**
866     * List of running applications, sorted by recent usage.
867     * The first entry in the list is the least recently used.
868     */
869    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
870
871    /**
872     * Where in mLruProcesses that the processes hosting activities start.
873     */
874    int mLruProcessActivityStart = 0;
875
876    /**
877     * Where in mLruProcesses that the processes hosting services start.
878     * This is after (lower index) than mLruProcessesActivityStart.
879     */
880    int mLruProcessServiceStart = 0;
881
882    /**
883     * List of processes that should gc as soon as things are idle.
884     */
885    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
886
887    /**
888     * Processes we want to collect PSS data from.
889     */
890    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
891
892    private boolean mBinderTransactionTrackingEnabled = false;
893
894    /**
895     * Last time we requested PSS data of all processes.
896     */
897    long mLastFullPssTime = SystemClock.uptimeMillis();
898
899    /**
900     * If set, the next time we collect PSS data we should do a full collection
901     * with data from native processes and the kernel.
902     */
903    boolean mFullPssPending = false;
904
905    /**
906     * This is the process holding what we currently consider to be
907     * the "home" activity.
908     */
909    ProcessRecord mHomeProcess;
910
911    /**
912     * This is the process holding the activity the user last visited that
913     * is in a different process from the one they are currently in.
914     */
915    ProcessRecord mPreviousProcess;
916
917    /**
918     * The time at which the previous process was last visible.
919     */
920    long mPreviousProcessVisibleTime;
921
922    /**
923     * Track all uids that have actively running processes.
924     */
925    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
926
927    /**
928     * This is for verifying the UID report flow.
929     */
930    static final boolean VALIDATE_UID_STATES = true;
931    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
932
933    /**
934     * Packages that the user has asked to have run in screen size
935     * compatibility mode instead of filling the screen.
936     */
937    final CompatModePackages mCompatModePackages;
938
939    /**
940     * Set of IntentSenderRecord objects that are currently active.
941     */
942    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
943            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
944
945    /**
946     * Fingerprints (hashCode()) of stack traces that we've
947     * already logged DropBox entries for.  Guarded by itself.  If
948     * something (rogue user app) forces this over
949     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
950     */
951    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
952    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
953
954    /**
955     * Strict Mode background batched logging state.
956     *
957     * The string buffer is guarded by itself, and its lock is also
958     * used to determine if another batched write is already
959     * in-flight.
960     */
961    private final StringBuilder mStrictModeBuffer = new StringBuilder();
962
963    /**
964     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
965     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
966     */
967    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
968
969    /**
970     * Resolver for broadcast intents to registered receivers.
971     * Holds BroadcastFilter (subclass of IntentFilter).
972     */
973    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
974            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
975        @Override
976        protected boolean allowFilterResult(
977                BroadcastFilter filter, List<BroadcastFilter> dest) {
978            IBinder target = filter.receiverList.receiver.asBinder();
979            for (int i = dest.size() - 1; i >= 0; i--) {
980                if (dest.get(i).receiverList.receiver.asBinder() == target) {
981                    return false;
982                }
983            }
984            return true;
985        }
986
987        @Override
988        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
989            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
990                    || userId == filter.owningUserId) {
991                return super.newResult(filter, match, userId);
992            }
993            return null;
994        }
995
996        @Override
997        protected BroadcastFilter[] newArray(int size) {
998            return new BroadcastFilter[size];
999        }
1000
1001        @Override
1002        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1003            return packageName.equals(filter.packageName);
1004        }
1005    };
1006
1007    /**
1008     * State of all active sticky broadcasts per user.  Keys are the action of the
1009     * sticky Intent, values are an ArrayList of all broadcasted intents with
1010     * that action (which should usually be one).  The SparseArray is keyed
1011     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1012     * for stickies that are sent to all users.
1013     */
1014    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1015            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1016
1017    final ActiveServices mServices;
1018
1019    final static class Association {
1020        final int mSourceUid;
1021        final String mSourceProcess;
1022        final int mTargetUid;
1023        final ComponentName mTargetComponent;
1024        final String mTargetProcess;
1025
1026        int mCount;
1027        long mTime;
1028
1029        int mNesting;
1030        long mStartTime;
1031
1032        // states of the source process when the bind occurred.
1033        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1034        long mLastStateUptime;
1035        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1036                - ActivityManager.MIN_PROCESS_STATE+1];
1037
1038        Association(int sourceUid, String sourceProcess, int targetUid,
1039                ComponentName targetComponent, String targetProcess) {
1040            mSourceUid = sourceUid;
1041            mSourceProcess = sourceProcess;
1042            mTargetUid = targetUid;
1043            mTargetComponent = targetComponent;
1044            mTargetProcess = targetProcess;
1045        }
1046    }
1047
1048    /**
1049     * When service association tracking is enabled, this is all of the associations we
1050     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1051     * -> association data.
1052     */
1053    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1054            mAssociations = new SparseArray<>();
1055    boolean mTrackingAssociations;
1056
1057    /**
1058     * Backup/restore process management
1059     */
1060    String mBackupAppName = null;
1061    BackupRecord mBackupTarget = null;
1062
1063    final ProviderMap mProviderMap;
1064
1065    /**
1066     * List of content providers who have clients waiting for them.  The
1067     * application is currently being launched and the provider will be
1068     * removed from this list once it is published.
1069     */
1070    final ArrayList<ContentProviderRecord> mLaunchingProviders
1071            = new ArrayList<ContentProviderRecord>();
1072
1073    /**
1074     * File storing persisted {@link #mGrantedUriPermissions}.
1075     */
1076    private final AtomicFile mGrantFile;
1077
1078    /** XML constants used in {@link #mGrantFile} */
1079    private static final String TAG_URI_GRANTS = "uri-grants";
1080    private static final String TAG_URI_GRANT = "uri-grant";
1081    private static final String ATTR_USER_HANDLE = "userHandle";
1082    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1083    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1084    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1085    private static final String ATTR_TARGET_PKG = "targetPkg";
1086    private static final String ATTR_URI = "uri";
1087    private static final String ATTR_MODE_FLAGS = "modeFlags";
1088    private static final String ATTR_CREATED_TIME = "createdTime";
1089    private static final String ATTR_PREFIX = "prefix";
1090
1091    /**
1092     * Global set of specific {@link Uri} permissions that have been granted.
1093     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1094     * to {@link UriPermission#uri} to {@link UriPermission}.
1095     */
1096    @GuardedBy("this")
1097    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1098            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1099
1100    public static class GrantUri {
1101        public final int sourceUserId;
1102        public final Uri uri;
1103        public boolean prefix;
1104
1105        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1106            this.sourceUserId = sourceUserId;
1107            this.uri = uri;
1108            this.prefix = prefix;
1109        }
1110
1111        @Override
1112        public int hashCode() {
1113            int hashCode = 1;
1114            hashCode = 31 * hashCode + sourceUserId;
1115            hashCode = 31 * hashCode + uri.hashCode();
1116            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1117            return hashCode;
1118        }
1119
1120        @Override
1121        public boolean equals(Object o) {
1122            if (o instanceof GrantUri) {
1123                GrantUri other = (GrantUri) o;
1124                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1125                        && prefix == other.prefix;
1126            }
1127            return false;
1128        }
1129
1130        @Override
1131        public String toString() {
1132            String result = uri.toString() + " [user " + sourceUserId + "]";
1133            if (prefix) result += " [prefix]";
1134            return result;
1135        }
1136
1137        public String toSafeString() {
1138            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1139            if (prefix) result += " [prefix]";
1140            return result;
1141        }
1142
1143        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1144            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1145                    ContentProvider.getUriWithoutUserId(uri), false);
1146        }
1147    }
1148
1149    CoreSettingsObserver mCoreSettingsObserver;
1150
1151    FontScaleSettingObserver mFontScaleSettingObserver;
1152
1153    private final class FontScaleSettingObserver extends ContentObserver {
1154        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1155
1156        public FontScaleSettingObserver() {
1157            super(mHandler);
1158            ContentResolver resolver = mContext.getContentResolver();
1159            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1160        }
1161
1162        @Override
1163        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1164            if (mFontScaleUri.equals(uri)) {
1165                updateFontScaleIfNeeded(userId);
1166            }
1167        }
1168    }
1169
1170    /**
1171     * Thread-local storage used to carry caller permissions over through
1172     * indirect content-provider access.
1173     */
1174    private class Identity {
1175        public final IBinder token;
1176        public final int pid;
1177        public final int uid;
1178
1179        Identity(IBinder _token, int _pid, int _uid) {
1180            token = _token;
1181            pid = _pid;
1182            uid = _uid;
1183        }
1184    }
1185
1186    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1187
1188    /**
1189     * All information we have collected about the runtime performance of
1190     * any user id that can impact battery performance.
1191     */
1192    final BatteryStatsService mBatteryStatsService;
1193
1194    /**
1195     * Information about component usage
1196     */
1197    UsageStatsManagerInternal mUsageStatsService;
1198
1199    /**
1200     * Access to DeviceIdleController service.
1201     */
1202    DeviceIdleController.LocalService mLocalDeviceIdleController;
1203
1204    /**
1205     * Set of app ids that are whitelisted for device idle and thus background check.
1206     */
1207    int[] mDeviceIdleWhitelist = new int[0];
1208
1209    /**
1210     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1211     */
1212    int[] mDeviceIdleTempWhitelist = new int[0];
1213
1214    static final class PendingTempWhitelist {
1215        final int targetUid;
1216        final long duration;
1217        final String tag;
1218
1219        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1220            targetUid = _targetUid;
1221            duration = _duration;
1222            tag = _tag;
1223        }
1224    }
1225
1226    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1227
1228    /**
1229     * Information about and control over application operations
1230     */
1231    final AppOpsService mAppOpsService;
1232
1233    /** Current sequencing integer of the configuration, for skipping old configurations. */
1234    private int mConfigurationSeq;
1235
1236    /**
1237     * Temp object used when global and/or display override configuration is updated. It is also
1238     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1239     * anyone...
1240     */
1241    private Configuration mTempConfig = new Configuration();
1242
1243    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1244            new UpdateConfigurationResult();
1245    private static final class UpdateConfigurationResult {
1246        // Configuration changes that were updated.
1247        int changes;
1248        // If the activity was relaunched to match the new configuration.
1249        boolean activityRelaunched;
1250
1251        void reset() {
1252            changes = 0;
1253            activityRelaunched = false;
1254        }
1255    }
1256
1257    boolean mSuppressResizeConfigChanges;
1258
1259    /**
1260     * Hardware-reported OpenGLES version.
1261     */
1262    final int GL_ES_VERSION;
1263
1264    /**
1265     * List of initialization arguments to pass to all processes when binding applications to them.
1266     * For example, references to the commonly used services.
1267     */
1268    HashMap<String, IBinder> mAppBindArgs;
1269    HashMap<String, IBinder> mIsolatedAppBindArgs;
1270
1271    /**
1272     * Temporary to avoid allocations.  Protected by main lock.
1273     */
1274    final StringBuilder mStringBuilder = new StringBuilder(256);
1275
1276    /**
1277     * Used to control how we initialize the service.
1278     */
1279    ComponentName mTopComponent;
1280    String mTopAction = Intent.ACTION_MAIN;
1281    String mTopData;
1282
1283    volatile boolean mProcessesReady = false;
1284    volatile boolean mSystemReady = false;
1285    volatile boolean mOnBattery = false;
1286    volatile int mFactoryTest;
1287
1288    @GuardedBy("this") boolean mBooting = false;
1289    @GuardedBy("this") boolean mCallFinishBooting = false;
1290    @GuardedBy("this") boolean mBootAnimationComplete = false;
1291    @GuardedBy("this") boolean mLaunchWarningShown = false;
1292    @GuardedBy("this") boolean mCheckedForSetup = false;
1293
1294    final Context mContext;
1295
1296    /**
1297     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1298     * change at runtime. Use mContext for non-UI purposes.
1299     */
1300    final Context mUiContext;
1301
1302    /**
1303     * The time at which we will allow normal application switches again,
1304     * after a call to {@link #stopAppSwitches()}.
1305     */
1306    long mAppSwitchesAllowedTime;
1307
1308    /**
1309     * This is set to true after the first switch after mAppSwitchesAllowedTime
1310     * is set; any switches after that will clear the time.
1311     */
1312    boolean mDidAppSwitch;
1313
1314    /**
1315     * Last time (in uptime) at which we checked for power usage.
1316     */
1317    long mLastPowerCheckUptime;
1318
1319    /**
1320     * Set while we are wanting to sleep, to prevent any
1321     * activities from being started/resumed.
1322     *
1323     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1324     *
1325     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1326     * while in the sleep state until there is a pending transition out of sleep, in which case
1327     * mSleeping is set to false, and remains false while awake.
1328     *
1329     * Whether mSleeping can quickly toggled between true/false without the device actually
1330     * display changing states is undefined.
1331     */
1332    private boolean mSleeping = false;
1333
1334    /**
1335     * The process state used for processes that are running the top activities.
1336     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1337     */
1338    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1339
1340    /**
1341     * Set while we are running a voice interaction.  This overrides
1342     * sleeping while it is active.
1343     */
1344    IVoiceInteractionSession mRunningVoice;
1345
1346    /**
1347     * For some direct access we need to power manager.
1348     */
1349    PowerManagerInternal mLocalPowerManager;
1350
1351    /**
1352     * We want to hold a wake lock while running a voice interaction session, since
1353     * this may happen with the screen off and we need to keep the CPU running to
1354     * be able to continue to interact with the user.
1355     */
1356    PowerManager.WakeLock mVoiceWakeLock;
1357
1358    /**
1359     * State of external calls telling us if the device is awake or asleep.
1360     */
1361    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1362
1363    /**
1364     * Set if we are shutting down the system, similar to sleeping.
1365     */
1366    boolean mShuttingDown = false;
1367
1368    /**
1369     * Current sequence id for oom_adj computation traversal.
1370     */
1371    int mAdjSeq = 0;
1372
1373    /**
1374     * Current sequence id for process LRU updating.
1375     */
1376    int mLruSeq = 0;
1377
1378    /**
1379     * Keep track of the non-cached/empty process we last found, to help
1380     * determine how to distribute cached/empty processes next time.
1381     */
1382    int mNumNonCachedProcs = 0;
1383
1384    /**
1385     * Keep track of the number of cached hidden procs, to balance oom adj
1386     * distribution between those and empty procs.
1387     */
1388    int mNumCachedHiddenProcs = 0;
1389
1390    /**
1391     * Keep track of the number of service processes we last found, to
1392     * determine on the next iteration which should be B services.
1393     */
1394    int mNumServiceProcs = 0;
1395    int mNewNumAServiceProcs = 0;
1396    int mNewNumServiceProcs = 0;
1397
1398    /**
1399     * Allow the current computed overall memory level of the system to go down?
1400     * This is set to false when we are killing processes for reasons other than
1401     * memory management, so that the now smaller process list will not be taken as
1402     * an indication that memory is tighter.
1403     */
1404    boolean mAllowLowerMemLevel = false;
1405
1406    /**
1407     * The last computed memory level, for holding when we are in a state that
1408     * processes are going away for other reasons.
1409     */
1410    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1411
1412    /**
1413     * The last total number of process we have, to determine if changes actually look
1414     * like a shrinking number of process due to lower RAM.
1415     */
1416    int mLastNumProcesses;
1417
1418    /**
1419     * The uptime of the last time we performed idle maintenance.
1420     */
1421    long mLastIdleTime = SystemClock.uptimeMillis();
1422
1423    /**
1424     * Total time spent with RAM that has been added in the past since the last idle time.
1425     */
1426    long mLowRamTimeSinceLastIdle = 0;
1427
1428    /**
1429     * If RAM is currently low, when that horrible situation started.
1430     */
1431    long mLowRamStartTime = 0;
1432
1433    /**
1434     * For reporting to battery stats the current top application.
1435     */
1436    private String mCurResumedPackage = null;
1437    private int mCurResumedUid = -1;
1438
1439    /**
1440     * For reporting to battery stats the apps currently running foreground
1441     * service.  The ProcessMap is package/uid tuples; each of these contain
1442     * an array of the currently foreground processes.
1443     */
1444    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1445            = new ProcessMap<ArrayList<ProcessRecord>>();
1446
1447    /**
1448     * Set if the systemServer made a call to enterSafeMode.
1449     */
1450    boolean mSafeMode;
1451
1452    /**
1453     * If true, we are running under a test environment so will sample PSS from processes
1454     * much more rapidly to try to collect better data when the tests are rapidly
1455     * running through apps.
1456     */
1457    boolean mTestPssMode = false;
1458
1459    String mDebugApp = null;
1460    boolean mWaitForDebugger = false;
1461    boolean mDebugTransient = false;
1462    String mOrigDebugApp = null;
1463    boolean mOrigWaitForDebugger = false;
1464    boolean mAlwaysFinishActivities = false;
1465    boolean mForceResizableActivities;
1466    /**
1467     * Flag that indicates if multi-window is enabled.
1468     *
1469     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1470     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1471     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1472     * At least one of the forms of multi-window must be enabled in order for this flag to be
1473     * initialized to 'true'.
1474     *
1475     * @see #mSupportsSplitScreenMultiWindow
1476     * @see #mSupportsFreeformWindowManagement
1477     * @see #mSupportsPictureInPicture
1478     * @see #mSupportsMultiDisplay
1479     */
1480    boolean mSupportsMultiWindow;
1481    boolean mSupportsSplitScreenMultiWindow;
1482    boolean mSupportsFreeformWindowManagement;
1483    boolean mSupportsPictureInPicture;
1484    boolean mSupportsMultiDisplay;
1485    boolean mSupportsLeanbackOnly;
1486    IActivityController mController = null;
1487    boolean mControllerIsAMonkey = false;
1488    String mProfileApp = null;
1489    ProcessRecord mProfileProc = null;
1490    ProfilerInfo mProfilerInfo = null;
1491    int mProfileType = 0;
1492    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1493    String mMemWatchDumpProcName;
1494    String mMemWatchDumpFile;
1495    int mMemWatchDumpPid;
1496    int mMemWatchDumpUid;
1497    String mTrackAllocationApp = null;
1498    String mNativeDebuggingApp = null;
1499
1500    final long[] mTmpLong = new long[2];
1501
1502    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1503
1504    /**
1505     * A global counter for generating sequence numbers.
1506     * This value will be used when incrementing sequence numbers in individual uidRecords.
1507     *
1508     * Having a global counter ensures that seq numbers are monotonically increasing for a
1509     * particular uid even when the uidRecord is re-created.
1510     */
1511    @GuardedBy("this")
1512    @VisibleForTesting
1513    long mProcStateSeqCounter = 0;
1514
1515    private final Injector mInjector;
1516
1517    static final class ProcessChangeItem {
1518        static final int CHANGE_ACTIVITIES = 1<<0;
1519        int changes;
1520        int uid;
1521        int pid;
1522        int processState;
1523        boolean foregroundActivities;
1524    }
1525
1526    static final class UidObserverRegistration {
1527        final int uid;
1528        final String pkg;
1529        final int which;
1530        final int cutpoint;
1531
1532        final SparseIntArray lastProcStates;
1533
1534        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1535            uid = _uid;
1536            pkg = _pkg;
1537            which = _which;
1538            cutpoint = _cutpoint;
1539            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1540                lastProcStates = new SparseIntArray();
1541            } else {
1542                lastProcStates = null;
1543            }
1544        }
1545    }
1546
1547    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1548    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1549
1550    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1551    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1552
1553    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1554    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1555
1556    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1557    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1558
1559    OomAdjObserver mCurOomAdjObserver;
1560    int mCurOomAdjUid;
1561
1562    interface OomAdjObserver {
1563        void onOomAdjMessage(String msg);
1564    }
1565
1566    /**
1567     * Runtime CPU use collection thread.  This object's lock is used to
1568     * perform synchronization with the thread (notifying it to run).
1569     */
1570    final Thread mProcessCpuThread;
1571
1572    /**
1573     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1574     * Must acquire this object's lock when accessing it.
1575     * NOTE: this lock will be held while doing long operations (trawling
1576     * through all processes in /proc), so it should never be acquired by
1577     * any critical paths such as when holding the main activity manager lock.
1578     */
1579    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1580            MONITOR_THREAD_CPU_USAGE);
1581    final AtomicLong mLastCpuTime = new AtomicLong(0);
1582    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1583    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1584
1585    long mLastWriteTime = 0;
1586
1587    /**
1588     * Used to retain an update lock when the foreground activity is in
1589     * immersive mode.
1590     */
1591    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1592
1593    /**
1594     * Set to true after the system has finished booting.
1595     */
1596    boolean mBooted = false;
1597
1598    WindowManagerService mWindowManager;
1599    final ActivityThread mSystemThread;
1600
1601    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1602        final ProcessRecord mApp;
1603        final int mPid;
1604        final IApplicationThread mAppThread;
1605
1606        AppDeathRecipient(ProcessRecord app, int pid,
1607                IApplicationThread thread) {
1608            if (DEBUG_ALL) Slog.v(
1609                TAG, "New death recipient " + this
1610                + " for thread " + thread.asBinder());
1611            mApp = app;
1612            mPid = pid;
1613            mAppThread = thread;
1614        }
1615
1616        @Override
1617        public void binderDied() {
1618            if (DEBUG_ALL) Slog.v(
1619                TAG, "Death received in " + this
1620                + " for thread " + mAppThread.asBinder());
1621            synchronized(ActivityManagerService.this) {
1622                appDiedLocked(mApp, mPid, mAppThread, true);
1623            }
1624        }
1625    }
1626
1627    static final int SHOW_ERROR_UI_MSG = 1;
1628    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1629    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1630    static final int UPDATE_CONFIGURATION_MSG = 4;
1631    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1632    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1633    static final int SERVICE_TIMEOUT_MSG = 12;
1634    static final int UPDATE_TIME_ZONE = 13;
1635    static final int SHOW_UID_ERROR_UI_MSG = 14;
1636    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1637    static final int PROC_START_TIMEOUT_MSG = 20;
1638    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1639    static final int KILL_APPLICATION_MSG = 22;
1640    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1641    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1642    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1643    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1644    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1645    static final int CLEAR_DNS_CACHE_MSG = 28;
1646    static final int UPDATE_HTTP_PROXY_MSG = 29;
1647    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1648    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1649    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1650    static final int REPORT_MEM_USAGE_MSG = 33;
1651    static final int REPORT_USER_SWITCH_MSG = 34;
1652    static final int CONTINUE_USER_SWITCH_MSG = 35;
1653    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1654    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1655    static final int PERSIST_URI_GRANTS_MSG = 38;
1656    static final int REQUEST_ALL_PSS_MSG = 39;
1657    static final int START_PROFILES_MSG = 40;
1658    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1659    static final int SYSTEM_USER_START_MSG = 42;
1660    static final int SYSTEM_USER_CURRENT_MSG = 43;
1661    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1662    static final int FINISH_BOOTING_MSG = 45;
1663    static final int START_USER_SWITCH_UI_MSG = 46;
1664    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1665    static final int DISMISS_DIALOG_UI_MSG = 48;
1666    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1667    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1668    static final int DELETE_DUMPHEAP_MSG = 51;
1669    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1670    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1671    static final int REPORT_TIME_TRACKER_MSG = 54;
1672    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1673    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1674    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1675    static final int IDLE_UIDS_MSG = 58;
1676    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1677    static final int LOG_STACK_STATE = 60;
1678    static final int VR_MODE_CHANGE_MSG = 61;
1679    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1680    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1681    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1682    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1683    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1684    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1685    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1686    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1687    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1688    static final int USER_SWITCH_CALLBACKS_TIMEOUT_MSG = 71;
1689    static final int START_USER_SWITCH_FG_MSG = 712;
1690
1691    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1692    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1693    static final int FIRST_COMPAT_MODE_MSG = 300;
1694    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1695
1696    static ServiceThread sKillThread = null;
1697    static KillHandler sKillHandler = null;
1698
1699    CompatModeDialog mCompatModeDialog;
1700    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1701    long mLastMemUsageReportTime = 0;
1702
1703    /**
1704     * Flag whether the current user is a "monkey", i.e. whether
1705     * the UI is driven by a UI automation tool.
1706     */
1707    private boolean mUserIsMonkey;
1708
1709    /** Flag whether the device has a Recents UI */
1710    boolean mHasRecents;
1711
1712    /** The dimensions of the thumbnails in the Recents UI. */
1713    int mThumbnailWidth;
1714    int mThumbnailHeight;
1715    float mFullscreenThumbnailScale;
1716
1717    final ServiceThread mHandlerThread;
1718    final MainHandler mHandler;
1719    final Handler mUiHandler;
1720
1721    final ActivityManagerConstants mConstants;
1722
1723    PackageManagerInternal mPackageManagerInt;
1724
1725    // VoiceInteraction session ID that changes for each new request except when
1726    // being called for multiwindow assist in a single session.
1727    private int mViSessionId = 1000;
1728
1729    final boolean mPermissionReviewRequired;
1730
1731    private static String sTheRealBuildSerial = Build.UNKNOWN;
1732
1733    /**
1734     * Current global configuration information. Contains general settings for the entire system,
1735     * also corresponds to the merged configuration of the default display.
1736     */
1737    Configuration getGlobalConfiguration() {
1738        return mStackSupervisor.getConfiguration();
1739    }
1740
1741    final class KillHandler extends Handler {
1742        static final int KILL_PROCESS_GROUP_MSG = 4000;
1743
1744        public KillHandler(Looper looper) {
1745            super(looper, null, true);
1746        }
1747
1748        @Override
1749        public void handleMessage(Message msg) {
1750            switch (msg.what) {
1751                case KILL_PROCESS_GROUP_MSG:
1752                {
1753                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1754                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1755                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1756                }
1757                break;
1758
1759                default:
1760                    super.handleMessage(msg);
1761            }
1762        }
1763    }
1764
1765    final class UiHandler extends Handler {
1766        public UiHandler() {
1767            super(com.android.server.UiThread.get().getLooper(), null, true);
1768        }
1769
1770        @Override
1771        public void handleMessage(Message msg) {
1772            switch (msg.what) {
1773            case SHOW_ERROR_UI_MSG: {
1774                mAppErrors.handleShowAppErrorUi(msg);
1775                ensureBootCompleted();
1776            } break;
1777            case SHOW_NOT_RESPONDING_UI_MSG: {
1778                mAppErrors.handleShowAnrUi(msg);
1779                ensureBootCompleted();
1780            } break;
1781            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1782                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1783                synchronized (ActivityManagerService.this) {
1784                    ProcessRecord proc = (ProcessRecord) data.get("app");
1785                    if (proc == null) {
1786                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1787                        break;
1788                    }
1789                    if (proc.crashDialog != null) {
1790                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1791                        return;
1792                    }
1793                    AppErrorResult res = (AppErrorResult) data.get("result");
1794                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1795                        Dialog d = new StrictModeViolationDialog(mUiContext,
1796                                ActivityManagerService.this, res, proc);
1797                        d.show();
1798                        proc.crashDialog = d;
1799                    } else {
1800                        // The device is asleep, so just pretend that the user
1801                        // saw a crash dialog and hit "force quit".
1802                        res.set(0);
1803                    }
1804                }
1805                ensureBootCompleted();
1806            } break;
1807            case SHOW_FACTORY_ERROR_UI_MSG: {
1808                Dialog d = new FactoryErrorDialog(
1809                        mUiContext, msg.getData().getCharSequence("msg"));
1810                d.show();
1811                ensureBootCompleted();
1812            } break;
1813            case WAIT_FOR_DEBUGGER_UI_MSG: {
1814                synchronized (ActivityManagerService.this) {
1815                    ProcessRecord app = (ProcessRecord)msg.obj;
1816                    if (msg.arg1 != 0) {
1817                        if (!app.waitedForDebugger) {
1818                            Dialog d = new AppWaitingForDebuggerDialog(
1819                                    ActivityManagerService.this,
1820                                    mUiContext, app);
1821                            app.waitDialog = d;
1822                            app.waitedForDebugger = true;
1823                            d.show();
1824                        }
1825                    } else {
1826                        if (app.waitDialog != null) {
1827                            app.waitDialog.dismiss();
1828                            app.waitDialog = null;
1829                        }
1830                    }
1831                }
1832            } break;
1833            case SHOW_UID_ERROR_UI_MSG: {
1834                if (mShowDialogs) {
1835                    AlertDialog d = new BaseErrorDialog(mUiContext);
1836                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1837                    d.setCancelable(false);
1838                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1839                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1840                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1841                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1842                    d.show();
1843                }
1844            } break;
1845            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1846                if (mShowDialogs) {
1847                    AlertDialog d = new BaseErrorDialog(mUiContext);
1848                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1849                    d.setCancelable(false);
1850                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1851                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1852                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1853                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1854                    d.show();
1855                }
1856            } break;
1857            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1858                synchronized (ActivityManagerService.this) {
1859                    ActivityRecord ar = (ActivityRecord) msg.obj;
1860                    if (mCompatModeDialog != null) {
1861                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1862                                ar.info.applicationInfo.packageName)) {
1863                            return;
1864                        }
1865                        mCompatModeDialog.dismiss();
1866                        mCompatModeDialog = null;
1867                    }
1868                    if (ar != null && false) {
1869                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1870                                ar.packageName)) {
1871                            int mode = mCompatModePackages.computeCompatModeLocked(
1872                                    ar.info.applicationInfo);
1873                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1874                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1875                                mCompatModeDialog = new CompatModeDialog(
1876                                        ActivityManagerService.this, mUiContext,
1877                                        ar.info.applicationInfo);
1878                                mCompatModeDialog.show();
1879                            }
1880                        }
1881                    }
1882                }
1883                break;
1884            }
1885            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1886                synchronized (ActivityManagerService.this) {
1887                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1888                    if (mUnsupportedDisplaySizeDialog != null) {
1889                        mUnsupportedDisplaySizeDialog.dismiss();
1890                        mUnsupportedDisplaySizeDialog = null;
1891                    }
1892                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1893                            ar.packageName)) {
1894                        // TODO(multi-display): Show dialog on appropriate display.
1895                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1896                                ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1897                        mUnsupportedDisplaySizeDialog.show();
1898                    }
1899                }
1900                break;
1901            }
1902            case START_USER_SWITCH_UI_MSG: {
1903                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1904                break;
1905            }
1906            case DISMISS_DIALOG_UI_MSG: {
1907                final Dialog d = (Dialog) msg.obj;
1908                d.dismiss();
1909                break;
1910            }
1911            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1912                dispatchProcessesChanged();
1913                break;
1914            }
1915            case DISPATCH_PROCESS_DIED_UI_MSG: {
1916                final int pid = msg.arg1;
1917                final int uid = msg.arg2;
1918                dispatchProcessDied(pid, uid);
1919                break;
1920            }
1921            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1922                dispatchUidsChanged();
1923            } break;
1924            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1925                dispatchOomAdjObserver((String)msg.obj);
1926            } break;
1927            case PUSH_TEMP_WHITELIST_UI_MSG: {
1928                pushTempWhitelist();
1929            } break;
1930            }
1931        }
1932    }
1933
1934    final class MainHandler extends Handler {
1935        public MainHandler(Looper looper) {
1936            super(looper, null, true);
1937        }
1938
1939        @Override
1940        public void handleMessage(Message msg) {
1941            switch (msg.what) {
1942            case UPDATE_CONFIGURATION_MSG: {
1943                final ContentResolver resolver = mContext.getContentResolver();
1944                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1945                        msg.arg1);
1946            } break;
1947            case GC_BACKGROUND_PROCESSES_MSG: {
1948                synchronized (ActivityManagerService.this) {
1949                    performAppGcsIfAppropriateLocked();
1950                }
1951            } break;
1952            case SERVICE_TIMEOUT_MSG: {
1953                mServices.serviceTimeout((ProcessRecord)msg.obj);
1954            } break;
1955            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1956                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1957            } break;
1958            case SERVICE_FOREGROUND_CRASH_MSG: {
1959                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1960            } break;
1961            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1962                RemoteCallbackList<IResultReceiver> callbacks
1963                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
1964                int N = callbacks.beginBroadcast();
1965                for (int i = 0; i < N; i++) {
1966                    try {
1967                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1968                    } catch (RemoteException e) {
1969                    }
1970                }
1971                callbacks.finishBroadcast();
1972            } break;
1973            case UPDATE_TIME_ZONE: {
1974                synchronized (ActivityManagerService.this) {
1975                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1976                        ProcessRecord r = mLruProcesses.get(i);
1977                        if (r.thread != null) {
1978                            try {
1979                                r.thread.updateTimeZone();
1980                            } catch (RemoteException ex) {
1981                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1982                            }
1983                        }
1984                    }
1985                }
1986            } break;
1987            case CLEAR_DNS_CACHE_MSG: {
1988                synchronized (ActivityManagerService.this) {
1989                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1990                        ProcessRecord r = mLruProcesses.get(i);
1991                        if (r.thread != null) {
1992                            try {
1993                                r.thread.clearDnsCache();
1994                            } catch (RemoteException ex) {
1995                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1996                            }
1997                        }
1998                    }
1999                }
2000            } break;
2001            case UPDATE_HTTP_PROXY_MSG: {
2002                ProxyInfo proxy = (ProxyInfo)msg.obj;
2003                String host = "";
2004                String port = "";
2005                String exclList = "";
2006                Uri pacFileUrl = Uri.EMPTY;
2007                if (proxy != null) {
2008                    host = proxy.getHost();
2009                    port = Integer.toString(proxy.getPort());
2010                    exclList = proxy.getExclusionListAsString();
2011                    pacFileUrl = proxy.getPacFileUrl();
2012                }
2013                synchronized (ActivityManagerService.this) {
2014                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2015                        ProcessRecord r = mLruProcesses.get(i);
2016                        if (r.thread != null) {
2017                            try {
2018                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2019                            } catch (RemoteException ex) {
2020                                Slog.w(TAG, "Failed to update http proxy for: " +
2021                                        r.info.processName);
2022                            }
2023                        }
2024                    }
2025                }
2026            } break;
2027            case PROC_START_TIMEOUT_MSG: {
2028                ProcessRecord app = (ProcessRecord)msg.obj;
2029                synchronized (ActivityManagerService.this) {
2030                    processStartTimedOutLocked(app);
2031                }
2032            } break;
2033            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2034                ProcessRecord app = (ProcessRecord)msg.obj;
2035                synchronized (ActivityManagerService.this) {
2036                    processContentProviderPublishTimedOutLocked(app);
2037                }
2038            } break;
2039            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2040                synchronized (ActivityManagerService.this) {
2041                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2042                }
2043            } break;
2044            case KILL_APPLICATION_MSG: {
2045                synchronized (ActivityManagerService.this) {
2046                    final int appId = msg.arg1;
2047                    final int userId = msg.arg2;
2048                    Bundle bundle = (Bundle)msg.obj;
2049                    String pkg = bundle.getString("pkg");
2050                    String reason = bundle.getString("reason");
2051                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2052                            false, userId, reason);
2053                }
2054            } break;
2055            case FINALIZE_PENDING_INTENT_MSG: {
2056                ((PendingIntentRecord)msg.obj).completeFinalize();
2057            } break;
2058            case POST_HEAVY_NOTIFICATION_MSG: {
2059                INotificationManager inm = NotificationManager.getService();
2060                if (inm == null) {
2061                    return;
2062                }
2063
2064                ActivityRecord root = (ActivityRecord)msg.obj;
2065                ProcessRecord process = root.app;
2066                if (process == null) {
2067                    return;
2068                }
2069
2070                try {
2071                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2072                    String text = mContext.getString(R.string.heavy_weight_notification,
2073                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2074                    Notification notification =
2075                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2076                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2077                            .setWhen(0)
2078                            .setOngoing(true)
2079                            .setTicker(text)
2080                            .setColor(mContext.getColor(
2081                                    com.android.internal.R.color.system_notification_accent_color))
2082                            .setContentTitle(text)
2083                            .setContentText(
2084                                    mContext.getText(R.string.heavy_weight_notification_detail))
2085                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2086                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2087                                    new UserHandle(root.userId)))
2088                            .build();
2089                    try {
2090                        inm.enqueueNotificationWithTag("android", "android", null,
2091                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2092                                notification, root.userId);
2093                    } catch (RuntimeException e) {
2094                        Slog.w(ActivityManagerService.TAG,
2095                                "Error showing notification for heavy-weight app", e);
2096                    } catch (RemoteException e) {
2097                    }
2098                } catch (NameNotFoundException e) {
2099                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2100                }
2101            } break;
2102            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2103                INotificationManager inm = NotificationManager.getService();
2104                if (inm == null) {
2105                    return;
2106                }
2107                try {
2108                    inm.cancelNotificationWithTag("android", null,
2109                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2110                } catch (RuntimeException e) {
2111                    Slog.w(ActivityManagerService.TAG,
2112                            "Error canceling notification for service", e);
2113                } catch (RemoteException e) {
2114                }
2115            } break;
2116            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2117                synchronized (ActivityManagerService.this) {
2118                    checkExcessivePowerUsageLocked();
2119                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2120                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2121                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2122                }
2123            } break;
2124            case REPORT_MEM_USAGE_MSG: {
2125                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2126                Thread thread = new Thread() {
2127                    @Override public void run() {
2128                        reportMemUsage(memInfos);
2129                    }
2130                };
2131                thread.start();
2132                break;
2133            }
2134            case START_USER_SWITCH_FG_MSG: {
2135                mUserController.startUserInForeground(msg.arg1);
2136                break;
2137            }
2138            case REPORT_USER_SWITCH_MSG: {
2139                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2140                break;
2141            }
2142            case CONTINUE_USER_SWITCH_MSG: {
2143                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2144                break;
2145            }
2146            case USER_SWITCH_TIMEOUT_MSG: {
2147                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2148                break;
2149            }
2150            case USER_SWITCH_CALLBACKS_TIMEOUT_MSG: {
2151                mUserController.timeoutUserSwitchCallbacks(msg.arg1, msg.arg2);
2152                break;
2153            }
2154            case IMMERSIVE_MODE_LOCK_MSG: {
2155                final boolean nextState = (msg.arg1 != 0);
2156                if (mUpdateLock.isHeld() != nextState) {
2157                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2158                            "Applying new update lock state '" + nextState
2159                            + "' for " + (ActivityRecord)msg.obj);
2160                    if (nextState) {
2161                        mUpdateLock.acquire();
2162                    } else {
2163                        mUpdateLock.release();
2164                    }
2165                }
2166                break;
2167            }
2168            case PERSIST_URI_GRANTS_MSG: {
2169                writeGrantedUriPermissions();
2170                break;
2171            }
2172            case REQUEST_ALL_PSS_MSG: {
2173                synchronized (ActivityManagerService.this) {
2174                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2175                }
2176                break;
2177            }
2178            case START_PROFILES_MSG: {
2179                synchronized (ActivityManagerService.this) {
2180                    mUserController.startProfilesLocked();
2181                }
2182                break;
2183            }
2184            case UPDATE_TIME_PREFERENCE_MSG: {
2185                // The user's time format preference might have changed.
2186                // For convenience we re-use the Intent extra values.
2187                synchronized (ActivityManagerService.this) {
2188                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2189                        ProcessRecord r = mLruProcesses.get(i);
2190                        if (r.thread != null) {
2191                            try {
2192                                r.thread.updateTimePrefs(msg.arg1);
2193                            } catch (RemoteException ex) {
2194                                Slog.w(TAG, "Failed to update preferences for: "
2195                                        + r.info.processName);
2196                            }
2197                        }
2198                    }
2199                }
2200                break;
2201            }
2202            case SYSTEM_USER_START_MSG: {
2203                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2204                        Integer.toString(msg.arg1), msg.arg1);
2205                mSystemServiceManager.startUser(msg.arg1);
2206                break;
2207            }
2208            case SYSTEM_USER_UNLOCK_MSG: {
2209                final int userId = msg.arg1;
2210                mSystemServiceManager.unlockUser(userId);
2211                synchronized (ActivityManagerService.this) {
2212                    mRecentTasks.loadUserRecentsLocked(userId);
2213                }
2214                if (userId == UserHandle.USER_SYSTEM) {
2215                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2216                }
2217                installEncryptionUnawareProviders(userId);
2218                mUserController.finishUserUnlocked((UserState) msg.obj);
2219                break;
2220            }
2221            case SYSTEM_USER_CURRENT_MSG: {
2222                mBatteryStatsService.noteEvent(
2223                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2224                        Integer.toString(msg.arg2), msg.arg2);
2225                mBatteryStatsService.noteEvent(
2226                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2227                        Integer.toString(msg.arg1), msg.arg1);
2228                mSystemServiceManager.switchUser(msg.arg1);
2229                break;
2230            }
2231            case ENTER_ANIMATION_COMPLETE_MSG: {
2232                synchronized (ActivityManagerService.this) {
2233                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2234                    if (r != null && r.app != null && r.app.thread != null) {
2235                        try {
2236                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2237                        } catch (RemoteException e) {
2238                        }
2239                    }
2240                }
2241                break;
2242            }
2243            case FINISH_BOOTING_MSG: {
2244                if (msg.arg1 != 0) {
2245                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2246                    finishBooting();
2247                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2248                }
2249                if (msg.arg2 != 0) {
2250                    enableScreenAfterBoot();
2251                }
2252                break;
2253            }
2254            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2255                try {
2256                    Locale l = (Locale) msg.obj;
2257                    IBinder service = ServiceManager.getService("mount");
2258                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2259                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2260                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2261                } catch (RemoteException e) {
2262                    Log.e(TAG, "Error storing locale for decryption UI", e);
2263                }
2264                break;
2265            }
2266            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2267                final int uid = msg.arg1;
2268                final byte[] firstPacket = (byte[]) msg.obj;
2269
2270                synchronized (mPidsSelfLocked) {
2271                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2272                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2273                        if (p.uid == uid) {
2274                            try {
2275                                p.thread.notifyCleartextNetwork(firstPacket);
2276                            } catch (RemoteException ignored) {
2277                            }
2278                        }
2279                    }
2280                }
2281                break;
2282            }
2283            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2284                final String procName;
2285                final int uid;
2286                final long memLimit;
2287                final String reportPackage;
2288                synchronized (ActivityManagerService.this) {
2289                    procName = mMemWatchDumpProcName;
2290                    uid = mMemWatchDumpUid;
2291                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2292                    if (val == null) {
2293                        val = mMemWatchProcesses.get(procName, 0);
2294                    }
2295                    if (val != null) {
2296                        memLimit = val.first;
2297                        reportPackage = val.second;
2298                    } else {
2299                        memLimit = 0;
2300                        reportPackage = null;
2301                    }
2302                }
2303                if (procName == null) {
2304                    return;
2305                }
2306
2307                if (DEBUG_PSS) Slog.d(TAG_PSS,
2308                        "Showing dump heap notification from " + procName + "/" + uid);
2309
2310                INotificationManager inm = NotificationManager.getService();
2311                if (inm == null) {
2312                    return;
2313                }
2314
2315                String text = mContext.getString(R.string.dump_heap_notification, procName);
2316
2317
2318                Intent deleteIntent = new Intent();
2319                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2320                Intent intent = new Intent();
2321                intent.setClassName("android", DumpHeapActivity.class.getName());
2322                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2323                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2324                if (reportPackage != null) {
2325                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2326                }
2327                int userId = UserHandle.getUserId(uid);
2328                Notification notification =
2329                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2330                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2331                        .setWhen(0)
2332                        .setOngoing(true)
2333                        .setAutoCancel(true)
2334                        .setTicker(text)
2335                        .setColor(mContext.getColor(
2336                                com.android.internal.R.color.system_notification_accent_color))
2337                        .setContentTitle(text)
2338                        .setContentText(
2339                                mContext.getText(R.string.dump_heap_notification_detail))
2340                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2341                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2342                                new UserHandle(userId)))
2343                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2344                                deleteIntent, 0, UserHandle.SYSTEM))
2345                        .build();
2346
2347                try {
2348                    inm.enqueueNotificationWithTag("android", "android", null,
2349                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2350                            notification, userId);
2351                } catch (RuntimeException e) {
2352                    Slog.w(ActivityManagerService.TAG,
2353                            "Error showing notification for dump heap", e);
2354                } catch (RemoteException e) {
2355                }
2356            } break;
2357            case DELETE_DUMPHEAP_MSG: {
2358                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2359                        null, DumpHeapActivity.JAVA_URI,
2360                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2361                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2362                        UserHandle.myUserId());
2363                synchronized (ActivityManagerService.this) {
2364                    mMemWatchDumpFile = null;
2365                    mMemWatchDumpProcName = null;
2366                    mMemWatchDumpPid = -1;
2367                    mMemWatchDumpUid = -1;
2368                }
2369            } break;
2370            case FOREGROUND_PROFILE_CHANGED_MSG: {
2371                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2372            } break;
2373            case REPORT_TIME_TRACKER_MSG: {
2374                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2375                tracker.deliverResult(mContext);
2376            } break;
2377            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2378                mUserController.dispatchUserSwitchComplete(msg.arg1);
2379            } break;
2380            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2381                mUserController.dispatchLockedBootComplete(msg.arg1);
2382            } break;
2383            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2384                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2385                try {
2386                    connection.shutdown();
2387                } catch (RemoteException e) {
2388                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2389                }
2390                // Only a UiAutomation can set this flag and now that
2391                // it is finished we make sure it is reset to its default.
2392                mUserIsMonkey = false;
2393            } break;
2394            case IDLE_UIDS_MSG: {
2395                idleUids();
2396            } break;
2397            case VR_MODE_CHANGE_MSG: {
2398                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2399                    return;
2400                }
2401                synchronized (ActivityManagerService.this) {
2402                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2403                    mWindowManager.disableNonVrUi(disableNonVrUi);
2404                    if (disableNonVrUi) {
2405                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2406                        // then remove the pinned stack.
2407                        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2408                                PINNED_STACK_ID);
2409                        if (pinnedStack != null) {
2410                            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2411                        }
2412                    }
2413                }
2414            } break;
2415            case NOTIFY_VR_SLEEPING_MSG: {
2416                notifyVrManagerOfSleepState(msg.arg1 != 0);
2417            } break;
2418            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2419                synchronized (ActivityManagerService.this) {
2420                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2421                        ProcessRecord r = mLruProcesses.get(i);
2422                        if (r.thread != null) {
2423                            try {
2424                                r.thread.handleTrustStorageUpdate();
2425                            } catch (RemoteException ex) {
2426                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2427                                        r.info.processName);
2428                            }
2429                        }
2430                    }
2431                }
2432            } break;
2433            }
2434        }
2435    };
2436
2437    static final int COLLECT_PSS_BG_MSG = 1;
2438
2439    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2440        @Override
2441        public void handleMessage(Message msg) {
2442            switch (msg.what) {
2443            case COLLECT_PSS_BG_MSG: {
2444                long start = SystemClock.uptimeMillis();
2445                MemInfoReader memInfo = null;
2446                synchronized (ActivityManagerService.this) {
2447                    if (mFullPssPending) {
2448                        mFullPssPending = false;
2449                        memInfo = new MemInfoReader();
2450                    }
2451                }
2452                if (memInfo != null) {
2453                    updateCpuStatsNow();
2454                    long nativeTotalPss = 0;
2455                    final List<ProcessCpuTracker.Stats> stats;
2456                    synchronized (mProcessCpuTracker) {
2457                        stats = mProcessCpuTracker.getStats( (st)-> {
2458                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2459                        });
2460                    }
2461                    final int N = stats.size();
2462                    for (int j = 0; j < N; j++) {
2463                        synchronized (mPidsSelfLocked) {
2464                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2465                                // This is one of our own processes; skip it.
2466                                continue;
2467                            }
2468                        }
2469                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2470                    }
2471                    memInfo.readMemInfo();
2472                    synchronized (ActivityManagerService.this) {
2473                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2474                                + (SystemClock.uptimeMillis()-start) + "ms");
2475                        final long cachedKb = memInfo.getCachedSizeKb();
2476                        final long freeKb = memInfo.getFreeSizeKb();
2477                        final long zramKb = memInfo.getZramTotalSizeKb();
2478                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2479                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2480                                kernelKb*1024, nativeTotalPss*1024);
2481                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2482                                nativeTotalPss);
2483                    }
2484                }
2485
2486                int num = 0;
2487                long[] tmp = new long[2];
2488                do {
2489                    ProcessRecord proc;
2490                    int procState;
2491                    int pid;
2492                    long lastPssTime;
2493                    synchronized (ActivityManagerService.this) {
2494                        if (mPendingPssProcesses.size() <= 0) {
2495                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2496                                    "Collected PSS of " + num + " processes in "
2497                                    + (SystemClock.uptimeMillis() - start) + "ms");
2498                            mPendingPssProcesses.clear();
2499                            return;
2500                        }
2501                        proc = mPendingPssProcesses.remove(0);
2502                        procState = proc.pssProcState;
2503                        lastPssTime = proc.lastPssTime;
2504                        if (proc.thread != null && procState == proc.setProcState
2505                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2506                                        < SystemClock.uptimeMillis()) {
2507                            pid = proc.pid;
2508                        } else {
2509                            proc = null;
2510                            pid = 0;
2511                        }
2512                    }
2513                    if (proc != null) {
2514                        long pss = Debug.getPss(pid, tmp, null);
2515                        synchronized (ActivityManagerService.this) {
2516                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2517                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2518                                num++;
2519                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2520                                        SystemClock.uptimeMillis());
2521                            }
2522                        }
2523                    }
2524                } while (true);
2525            }
2526            }
2527        }
2528    };
2529
2530    public void setSystemProcess() {
2531        try {
2532            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2533            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2534            ServiceManager.addService("meminfo", new MemBinder(this));
2535            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2536            ServiceManager.addService("dbinfo", new DbBinder(this));
2537            if (MONITOR_CPU_USAGE) {
2538                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2539            }
2540            ServiceManager.addService("permission", new PermissionController(this));
2541            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2542
2543            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2544                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2545            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2546
2547            synchronized (this) {
2548                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2549                app.persistent = true;
2550                app.pid = MY_PID;
2551                app.maxAdj = ProcessList.SYSTEM_ADJ;
2552                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2553                synchronized (mPidsSelfLocked) {
2554                    mPidsSelfLocked.put(app.pid, app);
2555                }
2556                updateLruProcessLocked(app, false, null);
2557                updateOomAdjLocked();
2558            }
2559        } catch (PackageManager.NameNotFoundException e) {
2560            throw new RuntimeException(
2561                    "Unable to find android system package", e);
2562        }
2563    }
2564
2565    public void setWindowManager(WindowManagerService wm) {
2566        mWindowManager = wm;
2567        mStackSupervisor.setWindowManager(wm);
2568        mActivityStarter.setWindowManager(wm);
2569        mLockTaskController.setWindowManager(wm);
2570    }
2571
2572    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2573        mUsageStatsService = usageStatsManager;
2574    }
2575
2576    public void startObservingNativeCrashes() {
2577        final NativeCrashListener ncl = new NativeCrashListener(this);
2578        ncl.start();
2579    }
2580
2581    public IAppOpsService getAppOpsService() {
2582        return mAppOpsService;
2583    }
2584
2585    static class MemBinder extends Binder {
2586        ActivityManagerService mActivityManagerService;
2587        MemBinder(ActivityManagerService activityManagerService) {
2588            mActivityManagerService = activityManagerService;
2589        }
2590
2591        @Override
2592        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2593            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2594                    "meminfo", pw)) return;
2595            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2596        }
2597    }
2598
2599    static class GraphicsBinder extends Binder {
2600        ActivityManagerService mActivityManagerService;
2601        GraphicsBinder(ActivityManagerService activityManagerService) {
2602            mActivityManagerService = activityManagerService;
2603        }
2604
2605        @Override
2606        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2607            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2608                    "gfxinfo", pw)) return;
2609            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2610        }
2611    }
2612
2613    static class DbBinder extends Binder {
2614        ActivityManagerService mActivityManagerService;
2615        DbBinder(ActivityManagerService activityManagerService) {
2616            mActivityManagerService = activityManagerService;
2617        }
2618
2619        @Override
2620        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2621            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2622                    "dbinfo", pw)) return;
2623            mActivityManagerService.dumpDbInfo(fd, pw, args);
2624        }
2625    }
2626
2627    static class CpuBinder extends Binder {
2628        ActivityManagerService mActivityManagerService;
2629        CpuBinder(ActivityManagerService activityManagerService) {
2630            mActivityManagerService = activityManagerService;
2631        }
2632
2633        @Override
2634        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2635            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2636                    "cpuinfo", pw)) return;
2637            synchronized (mActivityManagerService.mProcessCpuTracker) {
2638                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2639                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2640                        SystemClock.uptimeMillis()));
2641            }
2642        }
2643    }
2644
2645    public static final class Lifecycle extends SystemService {
2646        private final ActivityManagerService mService;
2647
2648        public Lifecycle(Context context) {
2649            super(context);
2650            mService = new ActivityManagerService(context);
2651        }
2652
2653        @Override
2654        public void onStart() {
2655            mService.start();
2656        }
2657
2658        @Override
2659        public void onCleanupUser(int userId) {
2660            mService.mBatteryStatsService.onCleanupUser(userId);
2661        }
2662
2663        public ActivityManagerService getService() {
2664            return mService;
2665        }
2666    }
2667
2668    @VisibleForTesting
2669    public ActivityManagerService(Injector injector) {
2670        mInjector = injector;
2671        mContext = mInjector.getContext();
2672        mUiContext = null;
2673        GL_ES_VERSION = 0;
2674        mActivityStarter = null;
2675        mAppErrors = null;
2676        mAppOpsService = mInjector.getAppOpsService(null, null);
2677        mBatteryStatsService = null;
2678        mCompatModePackages = null;
2679        mConstants = null;
2680        mGrantFile = null;
2681        mHandler = null;
2682        mHandlerThread = null;
2683        mIntentFirewall = null;
2684        mKeyguardController = null;
2685        mPermissionReviewRequired = false;
2686        mProcessCpuThread = null;
2687        mProcessStats = null;
2688        mProviderMap = null;
2689        mRecentTasks = null;
2690        mServices = null;
2691        mStackSupervisor = null;
2692        mSystemThread = null;
2693        mTaskChangeNotificationController = null;
2694        mUiHandler = injector.getUiHandler(null);
2695        mUserController = null;
2696        mVrController = null;
2697        mLockTaskController = null;
2698    }
2699
2700    // Note: This method is invoked on the main thread but may need to attach various
2701    // handlers to other threads.  So take care to be explicit about the looper.
2702    public ActivityManagerService(Context systemContext) {
2703        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2704        mInjector = new Injector();
2705        mContext = systemContext;
2706
2707        mFactoryTest = FactoryTest.getMode();
2708        mSystemThread = ActivityThread.currentActivityThread();
2709        mUiContext = mSystemThread.getSystemUiContext();
2710
2711        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2712
2713        mPermissionReviewRequired = mContext.getResources().getBoolean(
2714                com.android.internal.R.bool.config_permissionReviewRequired);
2715
2716        mHandlerThread = new ServiceThread(TAG,
2717                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2718        mHandlerThread.start();
2719        mHandler = new MainHandler(mHandlerThread.getLooper());
2720        mUiHandler = mInjector.getUiHandler(this);
2721
2722        mConstants = new ActivityManagerConstants(this, mHandler);
2723
2724        /* static; one-time init here */
2725        if (sKillHandler == null) {
2726            sKillThread = new ServiceThread(TAG + ":kill",
2727                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2728            sKillThread.start();
2729            sKillHandler = new KillHandler(sKillThread.getLooper());
2730        }
2731
2732        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2733                "foreground", BROADCAST_FG_TIMEOUT, false);
2734        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2735                "background", BROADCAST_BG_TIMEOUT, true);
2736        mBroadcastQueues[0] = mFgBroadcastQueue;
2737        mBroadcastQueues[1] = mBgBroadcastQueue;
2738
2739        mServices = new ActiveServices(this);
2740        mProviderMap = new ProviderMap(this);
2741        mAppErrors = new AppErrors(mUiContext, this);
2742
2743        // TODO: Move creation of battery stats service outside of activity manager service.
2744        File dataDir = Environment.getDataDirectory();
2745        File systemDir = new File(dataDir, "system");
2746        systemDir.mkdirs();
2747        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2748        mBatteryStatsService.getActiveStatistics().readLocked();
2749        mBatteryStatsService.scheduleWriteToDisk();
2750        mOnBattery = DEBUG_POWER ? true
2751                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2752        mBatteryStatsService.getActiveStatistics().setCallback(this);
2753
2754        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2755
2756        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2757        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2758                new IAppOpsCallback.Stub() {
2759                    @Override public void opChanged(int op, int uid, String packageName) {
2760                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2761                            if (mAppOpsService.checkOperation(op, uid, packageName)
2762                                    != AppOpsManager.MODE_ALLOWED) {
2763                                runInBackgroundDisabled(uid);
2764                            }
2765                        }
2766                    }
2767                });
2768
2769        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2770
2771        mUserController = new UserController(this);
2772
2773        mVrController = new VrController(this);
2774
2775        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2776            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2777
2778        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2779            mUseFifoUiScheduling = true;
2780        }
2781
2782        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2783        mTempConfig.setToDefaults();
2784        mTempConfig.setLocales(LocaleList.getDefault());
2785        mConfigurationSeq = mTempConfig.seq = 1;
2786        mStackSupervisor = createStackSupervisor();
2787        mStackSupervisor.onConfigurationChanged(mTempConfig);
2788        mKeyguardController = mStackSupervisor.mKeyguardController;
2789        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2790        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2791        mTaskChangeNotificationController =
2792                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2793        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2794        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2795        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
2796
2797        mProcessCpuThread = new Thread("CpuTracker") {
2798            @Override
2799            public void run() {
2800                synchronized (mProcessCpuTracker) {
2801                    mProcessCpuInitLatch.countDown();
2802                    mProcessCpuTracker.init();
2803                }
2804                while (true) {
2805                    try {
2806                        try {
2807                            synchronized(this) {
2808                                final long now = SystemClock.uptimeMillis();
2809                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2810                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2811                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2812                                //        + ", write delay=" + nextWriteDelay);
2813                                if (nextWriteDelay < nextCpuDelay) {
2814                                    nextCpuDelay = nextWriteDelay;
2815                                }
2816                                if (nextCpuDelay > 0) {
2817                                    mProcessCpuMutexFree.set(true);
2818                                    this.wait(nextCpuDelay);
2819                                }
2820                            }
2821                        } catch (InterruptedException e) {
2822                        }
2823                        updateCpuStatsNow();
2824                    } catch (Exception e) {
2825                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2826                    }
2827                }
2828            }
2829        };
2830
2831        Watchdog.getInstance().addMonitor(this);
2832        Watchdog.getInstance().addThread(mHandler);
2833    }
2834
2835    protected ActivityStackSupervisor createStackSupervisor() {
2836        return new ActivityStackSupervisor(this, mHandler.getLooper());
2837    }
2838
2839    public void setSystemServiceManager(SystemServiceManager mgr) {
2840        mSystemServiceManager = mgr;
2841    }
2842
2843    public void setInstaller(Installer installer) {
2844        mInstaller = installer;
2845    }
2846
2847    private void start() {
2848        removeAllProcessGroups();
2849        mProcessCpuThread.start();
2850
2851        mBatteryStatsService.publish();
2852        mAppOpsService.publish(mContext);
2853        Slog.d("AppOps", "AppOpsService published");
2854        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2855        // Wait for the synchronized block started in mProcessCpuThread,
2856        // so that any other acccess to mProcessCpuTracker from main thread
2857        // will be blocked during mProcessCpuTracker initialization.
2858        try {
2859            mProcessCpuInitLatch.await();
2860        } catch (InterruptedException e) {
2861            Slog.wtf(TAG, "Interrupted wait during start", e);
2862            Thread.currentThread().interrupt();
2863            throw new IllegalStateException("Interrupted wait during start");
2864        }
2865    }
2866
2867    void onUserStoppedLocked(int userId) {
2868        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2869    }
2870
2871    public void initPowerManagement() {
2872        mStackSupervisor.initPowerManagement();
2873        mBatteryStatsService.initPowerManagement();
2874        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2875        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2876        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2877        mVoiceWakeLock.setReferenceCounted(false);
2878    }
2879
2880    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2881        if (mBackgroundLaunchBroadcasts == null) {
2882            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2883        }
2884        return mBackgroundLaunchBroadcasts;
2885    }
2886
2887    @Override
2888    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2889            throws RemoteException {
2890        if (code == SYSPROPS_TRANSACTION) {
2891            // We need to tell all apps about the system property change.
2892            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2893            synchronized(this) {
2894                final int NP = mProcessNames.getMap().size();
2895                for (int ip=0; ip<NP; ip++) {
2896                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2897                    final int NA = apps.size();
2898                    for (int ia=0; ia<NA; ia++) {
2899                        ProcessRecord app = apps.valueAt(ia);
2900                        if (app.thread != null) {
2901                            procs.add(app.thread.asBinder());
2902                        }
2903                    }
2904                }
2905            }
2906
2907            int N = procs.size();
2908            for (int i=0; i<N; i++) {
2909                Parcel data2 = Parcel.obtain();
2910                try {
2911                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2912                            Binder.FLAG_ONEWAY);
2913                } catch (RemoteException e) {
2914                }
2915                data2.recycle();
2916            }
2917        }
2918        try {
2919            return super.onTransact(code, data, reply, flags);
2920        } catch (RuntimeException e) {
2921            // The activity manager only throws security exceptions, so let's
2922            // log all others.
2923            if (!(e instanceof SecurityException)) {
2924                Slog.wtf(TAG, "Activity Manager Crash."
2925                        + " UID:" + Binder.getCallingUid()
2926                        + " PID:" + Binder.getCallingPid()
2927                        + " TRANS:" + code, e);
2928            }
2929            throw e;
2930        }
2931    }
2932
2933    void updateCpuStats() {
2934        final long now = SystemClock.uptimeMillis();
2935        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2936            return;
2937        }
2938        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2939            synchronized (mProcessCpuThread) {
2940                mProcessCpuThread.notify();
2941            }
2942        }
2943    }
2944
2945    void updateCpuStatsNow() {
2946        synchronized (mProcessCpuTracker) {
2947            mProcessCpuMutexFree.set(false);
2948            final long now = SystemClock.uptimeMillis();
2949            boolean haveNewCpuStats = false;
2950
2951            if (MONITOR_CPU_USAGE &&
2952                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2953                mLastCpuTime.set(now);
2954                mProcessCpuTracker.update();
2955                if (mProcessCpuTracker.hasGoodLastStats()) {
2956                    haveNewCpuStats = true;
2957                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2958                    //Slog.i(TAG, "Total CPU usage: "
2959                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2960
2961                    // Slog the cpu usage if the property is set.
2962                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2963                        int user = mProcessCpuTracker.getLastUserTime();
2964                        int system = mProcessCpuTracker.getLastSystemTime();
2965                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2966                        int irq = mProcessCpuTracker.getLastIrqTime();
2967                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2968                        int idle = mProcessCpuTracker.getLastIdleTime();
2969
2970                        int total = user + system + iowait + irq + softIrq + idle;
2971                        if (total == 0) total = 1;
2972
2973                        EventLog.writeEvent(EventLogTags.CPU,
2974                                ((user+system+iowait+irq+softIrq) * 100) / total,
2975                                (user * 100) / total,
2976                                (system * 100) / total,
2977                                (iowait * 100) / total,
2978                                (irq * 100) / total,
2979                                (softIrq * 100) / total);
2980                    }
2981                }
2982            }
2983
2984            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2985            synchronized(bstats) {
2986                synchronized(mPidsSelfLocked) {
2987                    if (haveNewCpuStats) {
2988                        if (bstats.startAddingCpuLocked()) {
2989                            int totalUTime = 0;
2990                            int totalSTime = 0;
2991                            final int N = mProcessCpuTracker.countStats();
2992                            for (int i=0; i<N; i++) {
2993                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2994                                if (!st.working) {
2995                                    continue;
2996                                }
2997                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2998                                totalUTime += st.rel_utime;
2999                                totalSTime += st.rel_stime;
3000                                if (pr != null) {
3001                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3002                                    if (ps == null || !ps.isActive()) {
3003                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3004                                                pr.info.uid, pr.processName);
3005                                    }
3006                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3007                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3008                                    if (pr.lastCpuTime == 0) {
3009                                        pr.lastCpuTime = pr.curCpuTime;
3010                                    }
3011                                } else {
3012                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3013                                    if (ps == null || !ps.isActive()) {
3014                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3015                                                bstats.mapUid(st.uid), st.name);
3016                                    }
3017                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3018                                }
3019                            }
3020                            final int userTime = mProcessCpuTracker.getLastUserTime();
3021                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3022                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3023                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3024                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3025                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3026                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3027                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3028                        }
3029                    }
3030                }
3031
3032                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3033                    mLastWriteTime = now;
3034                    mBatteryStatsService.scheduleWriteToDisk();
3035                }
3036            }
3037        }
3038    }
3039
3040    @Override
3041    public void batteryNeedsCpuUpdate() {
3042        updateCpuStatsNow();
3043    }
3044
3045    @Override
3046    public void batteryPowerChanged(boolean onBattery) {
3047        // When plugging in, update the CPU stats first before changing
3048        // the plug state.
3049        updateCpuStatsNow();
3050        synchronized (this) {
3051            synchronized(mPidsSelfLocked) {
3052                mOnBattery = DEBUG_POWER ? true : onBattery;
3053            }
3054        }
3055    }
3056
3057    @Override
3058    public void batterySendBroadcast(Intent intent) {
3059        synchronized (this) {
3060            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3061                    AppOpsManager.OP_NONE, null, false, false,
3062                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3063        }
3064    }
3065
3066    /**
3067     * Initialize the application bind args. These are passed to each
3068     * process when the bindApplication() IPC is sent to the process. They're
3069     * lazily setup to make sure the services are running when they're asked for.
3070     */
3071    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3072        // Isolated processes won't get this optimization, so that we don't
3073        // violate the rules about which services they have access to.
3074        if (isolated) {
3075            if (mIsolatedAppBindArgs == null) {
3076                mIsolatedAppBindArgs = new HashMap<>();
3077                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3078            }
3079            return mIsolatedAppBindArgs;
3080        }
3081
3082        if (mAppBindArgs == null) {
3083            mAppBindArgs = new HashMap<>();
3084
3085            // Setup the application init args
3086            mAppBindArgs.put("package", ServiceManager.getService("package"));
3087            mAppBindArgs.put("window", ServiceManager.getService("window"));
3088            mAppBindArgs.put(Context.ALARM_SERVICE,
3089                    ServiceManager.getService(Context.ALARM_SERVICE));
3090        }
3091        return mAppBindArgs;
3092    }
3093
3094    /**
3095     * Update AMS states when an activity is resumed. This should only be called by
3096     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3097     */
3098    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3099        final TaskRecord task = r.getTask();
3100        if (task.isActivityTypeStandard()) {
3101            if (mCurAppTimeTracker != r.appTimeTracker) {
3102                // We are switching app tracking.  Complete the current one.
3103                if (mCurAppTimeTracker != null) {
3104                    mCurAppTimeTracker.stop();
3105                    mHandler.obtainMessage(
3106                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3107                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3108                    mCurAppTimeTracker = null;
3109                }
3110                if (r.appTimeTracker != null) {
3111                    mCurAppTimeTracker = r.appTimeTracker;
3112                    startTimeTrackingFocusedActivityLocked();
3113                }
3114            } else {
3115                startTimeTrackingFocusedActivityLocked();
3116            }
3117        } else {
3118            r.appTimeTracker = null;
3119        }
3120        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3121        // TODO: Probably not, because we don't want to resume voice on switching
3122        // back to this activity
3123        if (task.voiceInteractor != null) {
3124            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3125        } else {
3126            finishRunningVoiceLocked();
3127
3128            if (mLastResumedActivity != null) {
3129                final IVoiceInteractionSession session;
3130
3131                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3132                if (lastResumedActivityTask != null
3133                        && lastResumedActivityTask.voiceSession != null) {
3134                    session = lastResumedActivityTask.voiceSession;
3135                } else {
3136                    session = mLastResumedActivity.voiceSession;
3137                }
3138
3139                if (session != null) {
3140                    // We had been in a voice interaction session, but now focused has
3141                    // move to something different.  Just finish the session, we can't
3142                    // return to it and retain the proper state and synchronization with
3143                    // the voice interaction service.
3144                    finishVoiceTask(session);
3145                }
3146            }
3147        }
3148
3149        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3150            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3151            mHandler.obtainMessage(
3152                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3153        }
3154        mLastResumedActivity = r;
3155
3156        mWindowManager.setFocusedApp(r.appToken, true);
3157
3158        applyUpdateLockStateLocked(r);
3159        applyUpdateVrModeLocked(r);
3160
3161        EventLogTags.writeAmSetResumedActivity(
3162                r == null ? -1 : r.userId,
3163                r == null ? "NULL" : r.shortComponentName,
3164                reason);
3165    }
3166
3167    @Override
3168    public void setFocusedStack(int stackId) {
3169        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3170        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3171        final long callingId = Binder.clearCallingIdentity();
3172        try {
3173            synchronized (this) {
3174                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3175                if (stack == null) {
3176                    return;
3177                }
3178                final ActivityRecord r = stack.topRunningActivityLocked();
3179                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3180                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3181                }
3182            }
3183        } finally {
3184            Binder.restoreCallingIdentity(callingId);
3185        }
3186    }
3187
3188    @Override
3189    public void setFocusedTask(int taskId) {
3190        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3191        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3192        final long callingId = Binder.clearCallingIdentity();
3193        try {
3194            synchronized (this) {
3195                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3196                if (task == null) {
3197                    return;
3198                }
3199                final ActivityRecord r = task.topRunningActivityLocked();
3200                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3201                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3202                }
3203            }
3204        } finally {
3205            Binder.restoreCallingIdentity(callingId);
3206        }
3207    }
3208
3209    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3210    @Override
3211    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3212        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3213        mTaskChangeNotificationController.registerTaskStackListener(listener);
3214    }
3215
3216    /**
3217     * Unregister a task stack listener so that it stops receiving callbacks.
3218     */
3219    @Override
3220    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3221         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3222         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3223     }
3224
3225    @Override
3226    public void notifyActivityDrawn(IBinder token) {
3227        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3228        synchronized (this) {
3229            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3230            if (r != null) {
3231                r.getStack().notifyActivityDrawnLocked(r);
3232            }
3233        }
3234    }
3235
3236    final void applyUpdateLockStateLocked(ActivityRecord r) {
3237        // Modifications to the UpdateLock state are done on our handler, outside
3238        // the activity manager's locks.  The new state is determined based on the
3239        // state *now* of the relevant activity record.  The object is passed to
3240        // the handler solely for logging detail, not to be consulted/modified.
3241        final boolean nextState = r != null && r.immersive;
3242        mHandler.sendMessage(
3243                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3244    }
3245
3246    final void applyUpdateVrModeLocked(ActivityRecord r) {
3247        // VR apps are expected to run in a main display. If an app is turning on VR for
3248        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3249        // fullscreen stack before enabling VR Mode.
3250        // TODO: The goal of this code is to keep the VR app on the main display. When the
3251        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3252        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3253        // option would be a better choice here.
3254        if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3255            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3256                    + " to main stack for VR");
3257            moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3258        }
3259        mHandler.sendMessage(
3260                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3261    }
3262
3263    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3264        mHandler.sendMessage(
3265                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3266    }
3267
3268    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3269        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3270        if (vrService == null) {
3271            return;
3272        }
3273        vrService.onSleepStateChanged(isSleeping);
3274    }
3275
3276    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3277        Message msg = Message.obtain();
3278        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3279        msg.obj = r.getTask().askedCompatMode ? null : r;
3280        mUiHandler.sendMessage(msg);
3281    }
3282
3283    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3284        final Configuration globalConfig = getGlobalConfiguration();
3285        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3286                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3287            final Message msg = Message.obtain();
3288            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3289            msg.obj = r;
3290            mUiHandler.sendMessage(msg);
3291        }
3292    }
3293
3294    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3295            String what, Object obj, ProcessRecord srcApp) {
3296        app.lastActivityTime = now;
3297
3298        if (app.activities.size() > 0) {
3299            // Don't want to touch dependent processes that are hosting activities.
3300            return index;
3301        }
3302
3303        int lrui = mLruProcesses.lastIndexOf(app);
3304        if (lrui < 0) {
3305            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3306                    + what + " " + obj + " from " + srcApp);
3307            return index;
3308        }
3309
3310        if (lrui >= index) {
3311            // Don't want to cause this to move dependent processes *back* in the
3312            // list as if they were less frequently used.
3313            return index;
3314        }
3315
3316        if (lrui >= mLruProcessActivityStart) {
3317            // Don't want to touch dependent processes that are hosting activities.
3318            return index;
3319        }
3320
3321        mLruProcesses.remove(lrui);
3322        if (index > 0) {
3323            index--;
3324        }
3325        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3326                + " in LRU list: " + app);
3327        mLruProcesses.add(index, app);
3328        return index;
3329    }
3330
3331    static void killProcessGroup(int uid, int pid) {
3332        if (sKillHandler != null) {
3333            sKillHandler.sendMessage(
3334                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3335        } else {
3336            Slog.w(TAG, "Asked to kill process group before system bringup!");
3337            Process.killProcessGroup(uid, pid);
3338        }
3339    }
3340
3341    final void removeLruProcessLocked(ProcessRecord app) {
3342        int lrui = mLruProcesses.lastIndexOf(app);
3343        if (lrui >= 0) {
3344            if (!app.killed) {
3345                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3346                killProcessQuiet(app.pid);
3347                killProcessGroup(app.uid, app.pid);
3348            }
3349            if (lrui <= mLruProcessActivityStart) {
3350                mLruProcessActivityStart--;
3351            }
3352            if (lrui <= mLruProcessServiceStart) {
3353                mLruProcessServiceStart--;
3354            }
3355            mLruProcesses.remove(lrui);
3356        }
3357    }
3358
3359    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3360            ProcessRecord client) {
3361        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3362                || app.treatLikeActivity;
3363        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3364        if (!activityChange && hasActivity) {
3365            // The process has activities, so we are only allowing activity-based adjustments
3366            // to move it.  It should be kept in the front of the list with other
3367            // processes that have activities, and we don't want those to change their
3368            // order except due to activity operations.
3369            return;
3370        }
3371
3372        mLruSeq++;
3373        final long now = SystemClock.uptimeMillis();
3374        app.lastActivityTime = now;
3375
3376        // First a quick reject: if the app is already at the position we will
3377        // put it, then there is nothing to do.
3378        if (hasActivity) {
3379            final int N = mLruProcesses.size();
3380            if (N > 0 && mLruProcesses.get(N-1) == app) {
3381                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3382                return;
3383            }
3384        } else {
3385            if (mLruProcessServiceStart > 0
3386                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3387                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3388                return;
3389            }
3390        }
3391
3392        int lrui = mLruProcesses.lastIndexOf(app);
3393
3394        if (app.persistent && lrui >= 0) {
3395            // We don't care about the position of persistent processes, as long as
3396            // they are in the list.
3397            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3398            return;
3399        }
3400
3401        /* In progress: compute new position first, so we can avoid doing work
3402           if the process is not actually going to move.  Not yet working.
3403        int addIndex;
3404        int nextIndex;
3405        boolean inActivity = false, inService = false;
3406        if (hasActivity) {
3407            // Process has activities, put it at the very tipsy-top.
3408            addIndex = mLruProcesses.size();
3409            nextIndex = mLruProcessServiceStart;
3410            inActivity = true;
3411        } else if (hasService) {
3412            // Process has services, put it at the top of the service list.
3413            addIndex = mLruProcessActivityStart;
3414            nextIndex = mLruProcessServiceStart;
3415            inActivity = true;
3416            inService = true;
3417        } else  {
3418            // Process not otherwise of interest, it goes to the top of the non-service area.
3419            addIndex = mLruProcessServiceStart;
3420            if (client != null) {
3421                int clientIndex = mLruProcesses.lastIndexOf(client);
3422                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3423                        + app);
3424                if (clientIndex >= 0 && addIndex > clientIndex) {
3425                    addIndex = clientIndex;
3426                }
3427            }
3428            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3429        }
3430
3431        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3432                + mLruProcessActivityStart + "): " + app);
3433        */
3434
3435        if (lrui >= 0) {
3436            if (lrui < mLruProcessActivityStart) {
3437                mLruProcessActivityStart--;
3438            }
3439            if (lrui < mLruProcessServiceStart) {
3440                mLruProcessServiceStart--;
3441            }
3442            /*
3443            if (addIndex > lrui) {
3444                addIndex--;
3445            }
3446            if (nextIndex > lrui) {
3447                nextIndex--;
3448            }
3449            */
3450            mLruProcesses.remove(lrui);
3451        }
3452
3453        /*
3454        mLruProcesses.add(addIndex, app);
3455        if (inActivity) {
3456            mLruProcessActivityStart++;
3457        }
3458        if (inService) {
3459            mLruProcessActivityStart++;
3460        }
3461        */
3462
3463        int nextIndex;
3464        if (hasActivity) {
3465            final int N = mLruProcesses.size();
3466            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3467                // Process doesn't have activities, but has clients with
3468                // activities...  move it up, but one below the top (the top
3469                // should always have a real activity).
3470                if (DEBUG_LRU) Slog.d(TAG_LRU,
3471                        "Adding to second-top of LRU activity list: " + app);
3472                mLruProcesses.add(N - 1, app);
3473                // To keep it from spamming the LRU list (by making a bunch of clients),
3474                // we will push down any other entries owned by the app.
3475                final int uid = app.info.uid;
3476                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3477                    ProcessRecord subProc = mLruProcesses.get(i);
3478                    if (subProc.info.uid == uid) {
3479                        // We want to push this one down the list.  If the process after
3480                        // it is for the same uid, however, don't do so, because we don't
3481                        // want them internally to be re-ordered.
3482                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3483                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3484                                    "Pushing uid " + uid + " swapping at " + i + ": "
3485                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3486                            ProcessRecord tmp = mLruProcesses.get(i);
3487                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3488                            mLruProcesses.set(i - 1, tmp);
3489                            i--;
3490                        }
3491                    } else {
3492                        // A gap, we can stop here.
3493                        break;
3494                    }
3495                }
3496            } else {
3497                // Process has activities, put it at the very tipsy-top.
3498                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3499                mLruProcesses.add(app);
3500            }
3501            nextIndex = mLruProcessServiceStart;
3502        } else if (hasService) {
3503            // Process has services, put it at the top of the service list.
3504            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3505            mLruProcesses.add(mLruProcessActivityStart, app);
3506            nextIndex = mLruProcessServiceStart;
3507            mLruProcessActivityStart++;
3508        } else  {
3509            // Process not otherwise of interest, it goes to the top of the non-service area.
3510            int index = mLruProcessServiceStart;
3511            if (client != null) {
3512                // If there is a client, don't allow the process to be moved up higher
3513                // in the list than that client.
3514                int clientIndex = mLruProcesses.lastIndexOf(client);
3515                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3516                        + " when updating " + app);
3517                if (clientIndex <= lrui) {
3518                    // Don't allow the client index restriction to push it down farther in the
3519                    // list than it already is.
3520                    clientIndex = lrui;
3521                }
3522                if (clientIndex >= 0 && index > clientIndex) {
3523                    index = clientIndex;
3524                }
3525            }
3526            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3527            mLruProcesses.add(index, app);
3528            nextIndex = index-1;
3529            mLruProcessActivityStart++;
3530            mLruProcessServiceStart++;
3531        }
3532
3533        // If the app is currently using a content provider or service,
3534        // bump those processes as well.
3535        for (int j=app.connections.size()-1; j>=0; j--) {
3536            ConnectionRecord cr = app.connections.valueAt(j);
3537            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3538                    && cr.binding.service.app != null
3539                    && cr.binding.service.app.lruSeq != mLruSeq
3540                    && !cr.binding.service.app.persistent) {
3541                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3542                        "service connection", cr, app);
3543            }
3544        }
3545        for (int j=app.conProviders.size()-1; j>=0; j--) {
3546            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3547            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3548                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3549                        "provider reference", cpr, app);
3550            }
3551        }
3552    }
3553
3554    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3555        if (uid == SYSTEM_UID) {
3556            // The system gets to run in any process.  If there are multiple
3557            // processes with the same uid, just pick the first (this
3558            // should never happen).
3559            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3560            if (procs == null) return null;
3561            final int procCount = procs.size();
3562            for (int i = 0; i < procCount; i++) {
3563                final int procUid = procs.keyAt(i);
3564                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3565                    // Don't use an app process or different user process for system component.
3566                    continue;
3567                }
3568                return procs.valueAt(i);
3569            }
3570        }
3571        ProcessRecord proc = mProcessNames.get(processName, uid);
3572        if (false && proc != null && !keepIfLarge
3573                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3574                && proc.lastCachedPss >= 4000) {
3575            // Turn this condition on to cause killing to happen regularly, for testing.
3576            if (proc.baseProcessTracker != null) {
3577                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3578            }
3579            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3580        } else if (proc != null && !keepIfLarge
3581                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3582                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3583            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3584            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3585                if (proc.baseProcessTracker != null) {
3586                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3587                }
3588                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3589            }
3590        }
3591        return proc;
3592    }
3593
3594    void notifyPackageUse(String packageName, int reason) {
3595        synchronized(this) {
3596            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3597        }
3598    }
3599
3600    boolean isNextTransitionForward() {
3601        int transit = mWindowManager.getPendingAppTransition();
3602        return transit == TRANSIT_ACTIVITY_OPEN
3603                || transit == TRANSIT_TASK_OPEN
3604                || transit == TRANSIT_TASK_TO_FRONT;
3605    }
3606
3607    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3608            String processName, String abiOverride, int uid, Runnable crashHandler) {
3609        synchronized(this) {
3610            ApplicationInfo info = new ApplicationInfo();
3611            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3612            // For isolated processes, the former contains the parent's uid and the latter the
3613            // actual uid of the isolated process.
3614            // In the special case introduced by this method (which is, starting an isolated
3615            // process directly from the SystemServer without an actual parent app process) the
3616            // closest thing to a parent's uid is SYSTEM_UID.
3617            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3618            // the |isolated| logic in the ProcessRecord constructor.
3619            info.uid = SYSTEM_UID;
3620            info.processName = processName;
3621            info.className = entryPoint;
3622            info.packageName = "android";
3623            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3624            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3625                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3626                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3627                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3628                    crashHandler);
3629            return proc != null ? proc.pid : 0;
3630        }
3631    }
3632
3633    final ProcessRecord startProcessLocked(String processName,
3634            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3635            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3636            boolean isolated, boolean keepIfLarge) {
3637        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3638                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3639                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3640                null /* crashHandler */);
3641    }
3642
3643    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3644            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3645            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3646            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3647        long startTime = SystemClock.elapsedRealtime();
3648        ProcessRecord app;
3649        if (!isolated) {
3650            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3651            checkTime(startTime, "startProcess: after getProcessRecord");
3652
3653            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3654                // If we are in the background, then check to see if this process
3655                // is bad.  If so, we will just silently fail.
3656                if (mAppErrors.isBadProcessLocked(info)) {
3657                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3658                            + "/" + info.processName);
3659                    return null;
3660                }
3661            } else {
3662                // When the user is explicitly starting a process, then clear its
3663                // crash count so that we won't make it bad until they see at
3664                // least one crash dialog again, and make the process good again
3665                // if it had been bad.
3666                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3667                        + "/" + info.processName);
3668                mAppErrors.resetProcessCrashTimeLocked(info);
3669                if (mAppErrors.isBadProcessLocked(info)) {
3670                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3671                            UserHandle.getUserId(info.uid), info.uid,
3672                            info.processName);
3673                    mAppErrors.clearBadProcessLocked(info);
3674                    if (app != null) {
3675                        app.bad = false;
3676                    }
3677                }
3678            }
3679        } else {
3680            // If this is an isolated process, it can't re-use an existing process.
3681            app = null;
3682        }
3683
3684        // We don't have to do anything more if:
3685        // (1) There is an existing application record; and
3686        // (2) The caller doesn't think it is dead, OR there is no thread
3687        //     object attached to it so we know it couldn't have crashed; and
3688        // (3) There is a pid assigned to it, so it is either starting or
3689        //     already running.
3690        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3691                + " app=" + app + " knownToBeDead=" + knownToBeDead
3692                + " thread=" + (app != null ? app.thread : null)
3693                + " pid=" + (app != null ? app.pid : -1));
3694        if (app != null && app.pid > 0) {
3695            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3696                // We already have the app running, or are waiting for it to
3697                // come up (we have a pid but not yet its thread), so keep it.
3698                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3699                // If this is a new package in the process, add the package to the list
3700                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3701                checkTime(startTime, "startProcess: done, added package to proc");
3702                return app;
3703            }
3704
3705            // An application record is attached to a previous process,
3706            // clean it up now.
3707            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3708            checkTime(startTime, "startProcess: bad proc running, killing");
3709            killProcessGroup(app.uid, app.pid);
3710            handleAppDiedLocked(app, true, true);
3711            checkTime(startTime, "startProcess: done killing old proc");
3712        }
3713
3714        String hostingNameStr = hostingName != null
3715                ? hostingName.flattenToShortString() : null;
3716
3717        if (app == null) {
3718            checkTime(startTime, "startProcess: creating new process record");
3719            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3720            if (app == null) {
3721                Slog.w(TAG, "Failed making new process record for "
3722                        + processName + "/" + info.uid + " isolated=" + isolated);
3723                return null;
3724            }
3725            app.crashHandler = crashHandler;
3726            app.isolatedEntryPoint = entryPoint;
3727            app.isolatedEntryPointArgs = entryPointArgs;
3728            checkTime(startTime, "startProcess: done creating new process record");
3729        } else {
3730            // If this is a new package in the process, add the package to the list
3731            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3732            checkTime(startTime, "startProcess: added package to existing proc");
3733        }
3734
3735        // If the system is not ready yet, then hold off on starting this
3736        // process until it is.
3737        if (!mProcessesReady
3738                && !isAllowedWhileBooting(info)
3739                && !allowWhileBooting) {
3740            if (!mProcessesOnHold.contains(app)) {
3741                mProcessesOnHold.add(app);
3742            }
3743            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3744                    "System not ready, putting on hold: " + app);
3745            checkTime(startTime, "startProcess: returning with proc on hold");
3746            return app;
3747        }
3748
3749        checkTime(startTime, "startProcess: stepping in to startProcess");
3750        startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
3751        checkTime(startTime, "startProcess: done starting proc!");
3752        return (app.pid != 0) ? app : null;
3753    }
3754
3755    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3756        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3757    }
3758
3759    private final void startProcessLocked(ProcessRecord app,
3760            String hostingType, String hostingNameStr) {
3761        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
3762    }
3763
3764    private final void startProcessLocked(ProcessRecord app, String hostingType,
3765            String hostingNameStr, String abiOverride) {
3766        long startTime = SystemClock.elapsedRealtime();
3767        if (app.pid > 0 && app.pid != MY_PID) {
3768            checkTime(startTime, "startProcess: removing from pids map");
3769            synchronized (mPidsSelfLocked) {
3770                mPidsSelfLocked.remove(app.pid);
3771                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3772            }
3773            checkTime(startTime, "startProcess: done removing from pids map");
3774            app.setPid(0);
3775        }
3776
3777        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3778                "startProcessLocked removing on hold: " + app);
3779        mProcessesOnHold.remove(app);
3780
3781        checkTime(startTime, "startProcess: starting to update cpu stats");
3782        updateCpuStats();
3783        checkTime(startTime, "startProcess: done updating cpu stats");
3784
3785        try {
3786            try {
3787                final int userId = UserHandle.getUserId(app.uid);
3788                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3789            } catch (RemoteException e) {
3790                throw e.rethrowAsRuntimeException();
3791            }
3792
3793            int uid = app.uid;
3794            int[] gids = null;
3795            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3796            if (!app.isolated) {
3797                int[] permGids = null;
3798                try {
3799                    checkTime(startTime, "startProcess: getting gids from package manager");
3800                    final IPackageManager pm = AppGlobals.getPackageManager();
3801                    permGids = pm.getPackageGids(app.info.packageName,
3802                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3803                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3804                            StorageManagerInternal.class);
3805                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3806                            app.info.packageName);
3807                } catch (RemoteException e) {
3808                    throw e.rethrowAsRuntimeException();
3809                }
3810
3811                /*
3812                 * Add shared application and profile GIDs so applications can share some
3813                 * resources like shared libraries and access user-wide resources
3814                 */
3815                if (ArrayUtils.isEmpty(permGids)) {
3816                    gids = new int[3];
3817                } else {
3818                    gids = new int[permGids.length + 3];
3819                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3820                }
3821                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3822                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3823                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3824            }
3825            checkTime(startTime, "startProcess: building args");
3826            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3827                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3828                        && mTopComponent != null
3829                        && app.processName.equals(mTopComponent.getPackageName())) {
3830                    uid = 0;
3831                }
3832                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3833                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3834                    uid = 0;
3835                }
3836            }
3837            int runtimeFlags = 0;
3838            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3839                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
3840                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3841                // Also turn on CheckJNI for debuggable apps. It's quite
3842                // awkward to turn on otherwise.
3843                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3844            }
3845            // Run the app in safe mode if its manifest requests so or the
3846            // system is booted in safe mode.
3847            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3848                mSafeMode == true) {
3849                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3850            }
3851            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3852                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3853            }
3854            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3855            if ("true".equals(genDebugInfoProperty)) {
3856                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3857            }
3858            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3859                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3860            }
3861            if ("1".equals(SystemProperties.get("debug.assert"))) {
3862                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3863            }
3864            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3865                // Enable all debug flags required by the native debugger.
3866                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3867                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3868                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3869                mNativeDebuggingApp = null;
3870            }
3871
3872            String invokeWith = null;
3873            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3874                // Debuggable apps may include a wrapper script with their library directory.
3875                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3876                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3877                try {
3878                    if (new File(wrapperFileName).exists()) {
3879                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3880                    }
3881                } finally {
3882                    StrictMode.setThreadPolicy(oldPolicy);
3883                }
3884            }
3885
3886            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3887            if (requiredAbi == null) {
3888                requiredAbi = Build.SUPPORTED_ABIS[0];
3889            }
3890
3891            String instructionSet = null;
3892            if (app.info.primaryCpuAbi != null) {
3893                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3894            }
3895
3896            app.gids = gids;
3897            app.requiredAbi = requiredAbi;
3898            app.instructionSet = instructionSet;
3899
3900            // the per-user SELinux context must be set
3901            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3902                Slog.wtf(TAG, "SELinux tag not defined",
3903                        new IllegalStateException("SELinux tag not defined for "
3904                        + app.info.packageName + " (uid " + app.uid + ")"));
3905            }
3906            final String seInfo = app.info.seInfo
3907                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3908            // Start the process.  It will either succeed and return a result containing
3909            // the PID of the new process, or else throw a RuntimeException.
3910            final String entryPoint = "android.app.ActivityThread";
3911            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3912                    app.processName);
3913            checkTime(startTime, "startProcess: asking zygote to start proc");
3914            ProcessStartResult startResult;
3915            if (hostingType.equals("webview_service")) {
3916                startResult = startWebView(entryPoint,
3917                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3918                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3919                        app.info.dataDir, null, null);
3920            } else {
3921                startResult = Process.start(entryPoint,
3922                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3923                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3924                        app.info.dataDir, invokeWith, null);
3925            }
3926            checkTime(startTime, "startProcess: returned from zygote!");
3927            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3928
3929            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3930            checkTime(startTime, "startProcess: done updating battery stats");
3931
3932            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3933                    UserHandle.getUserId(uid), startResult.pid, uid,
3934                    app.processName, hostingType,
3935                    hostingNameStr != null ? hostingNameStr : "");
3936
3937            try {
3938                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3939                        seInfo, app.info.sourceDir, startResult.pid);
3940            } catch (RemoteException ex) {
3941                // Ignore
3942            }
3943
3944            if (app.persistent) {
3945                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3946            }
3947
3948            checkTime(startTime, "startProcess: building log message");
3949            StringBuilder buf = mStringBuilder;
3950            buf.setLength(0);
3951            buf.append("Start proc ");
3952            buf.append(startResult.pid);
3953            buf.append(':');
3954            buf.append(app.processName);
3955            buf.append('/');
3956            UserHandle.formatUid(buf, uid);
3957            if (app.isolatedEntryPoint != null) {
3958                buf.append(" [");
3959                buf.append(app.isolatedEntryPoint);
3960                buf.append("]");
3961            }
3962            buf.append(" for ");
3963            buf.append(hostingType);
3964            if (hostingNameStr != null) {
3965                buf.append(" ");
3966                buf.append(hostingNameStr);
3967            }
3968            Slog.i(TAG, buf.toString());
3969            app.setPid(startResult.pid);
3970            app.usingWrapper = startResult.usingWrapper;
3971            app.removed = false;
3972            app.killed = false;
3973            app.killedByAm = false;
3974            checkTime(startTime, "startProcess: starting to update pids map");
3975            ProcessRecord oldApp;
3976            synchronized (mPidsSelfLocked) {
3977                oldApp = mPidsSelfLocked.get(startResult.pid);
3978            }
3979            // If there is already an app occupying that pid that hasn't been cleaned up
3980            if (oldApp != null && !app.isolated) {
3981                // Clean up anything relating to this pid first
3982                Slog.w(TAG, "Reusing pid " + startResult.pid
3983                        + " while app is still mapped to it");
3984                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3985                        true /*replacingPid*/);
3986            }
3987            synchronized (mPidsSelfLocked) {
3988                this.mPidsSelfLocked.put(startResult.pid, app);
3989                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3990                msg.obj = app;
3991                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3992                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3993            }
3994            checkTime(startTime, "startProcess: done updating pids map");
3995        } catch (RuntimeException e) {
3996            Slog.e(TAG, "Failure starting process " + app.processName, e);
3997
3998            // Something went very wrong while trying to start this process; one
3999            // common case is when the package is frozen due to an active
4000            // upgrade. To recover, clean up any active bookkeeping related to
4001            // starting this process. (We already invoked this method once when
4002            // the package was initially frozen through KILL_APPLICATION_MSG, so
4003            // it doesn't hurt to use it again.)
4004            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4005                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4006        }
4007    }
4008
4009    void updateUsageStats(ActivityRecord component, boolean resumed) {
4010        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4011                "updateUsageStats: comp=" + component + "res=" + resumed);
4012        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4013        if (resumed) {
4014            if (mUsageStatsService != null) {
4015                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4016                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4017            }
4018            synchronized (stats) {
4019                stats.noteActivityResumedLocked(component.app.uid);
4020            }
4021        } else {
4022            if (mUsageStatsService != null) {
4023                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4024                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4025            }
4026            synchronized (stats) {
4027                stats.noteActivityPausedLocked(component.app.uid);
4028            }
4029        }
4030    }
4031
4032    Intent getHomeIntent() {
4033        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4034        intent.setComponent(mTopComponent);
4035        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4036        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4037            intent.addCategory(Intent.CATEGORY_HOME);
4038        }
4039        return intent;
4040    }
4041
4042    boolean startHomeActivityLocked(int userId, String reason) {
4043        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4044                && mTopAction == null) {
4045            // We are running in factory test mode, but unable to find
4046            // the factory test app, so just sit around displaying the
4047            // error message and don't try to start anything.
4048            return false;
4049        }
4050        Intent intent = getHomeIntent();
4051        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4052        if (aInfo != null) {
4053            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4054            // Don't do this if the home app is currently being
4055            // instrumented.
4056            aInfo = new ActivityInfo(aInfo);
4057            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4058            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4059                    aInfo.applicationInfo.uid, true);
4060            if (app == null || app.instr == null) {
4061                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4062                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4063                // For ANR debugging to verify if the user activity is the one that actually
4064                // launched.
4065                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4066                mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4067            }
4068        } else {
4069            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4070        }
4071
4072        return true;
4073    }
4074
4075    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4076        ActivityInfo ai = null;
4077        ComponentName comp = intent.getComponent();
4078        try {
4079            if (comp != null) {
4080                // Factory test.
4081                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4082            } else {
4083                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4084                        intent,
4085                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4086                        flags, userId);
4087
4088                if (info != null) {
4089                    ai = info.activityInfo;
4090                }
4091            }
4092        } catch (RemoteException e) {
4093            // ignore
4094        }
4095
4096        return ai;
4097    }
4098
4099    /**
4100     * Starts the "new version setup screen" if appropriate.
4101     */
4102    void startSetupActivityLocked() {
4103        // Only do this once per boot.
4104        if (mCheckedForSetup) {
4105            return;
4106        }
4107
4108        // We will show this screen if the current one is a different
4109        // version than the last one shown, and we are not running in
4110        // low-level factory test mode.
4111        final ContentResolver resolver = mContext.getContentResolver();
4112        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4113                Settings.Global.getInt(resolver,
4114                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4115            mCheckedForSetup = true;
4116
4117            // See if we should be showing the platform update setup UI.
4118            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4119            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4120                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4121            if (!ris.isEmpty()) {
4122                final ResolveInfo ri = ris.get(0);
4123                String vers = ri.activityInfo.metaData != null
4124                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4125                        : null;
4126                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4127                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4128                            Intent.METADATA_SETUP_VERSION);
4129                }
4130                String lastVers = Settings.Secure.getString(
4131                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4132                if (vers != null && !vers.equals(lastVers)) {
4133                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4134                    intent.setComponent(new ComponentName(
4135                            ri.activityInfo.packageName, ri.activityInfo.name));
4136                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4137                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4138                            null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4139                }
4140            }
4141        }
4142    }
4143
4144    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4145        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4146    }
4147
4148    void enforceNotIsolatedCaller(String caller) {
4149        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4150            throw new SecurityException("Isolated process not allowed to call " + caller);
4151        }
4152    }
4153
4154    void enforceShellRestriction(String restriction, int userHandle) {
4155        if (Binder.getCallingUid() == SHELL_UID) {
4156            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4157                throw new SecurityException("Shell does not have permission to access user "
4158                        + userHandle);
4159            }
4160        }
4161    }
4162
4163    @Override
4164    public int getFrontActivityScreenCompatMode() {
4165        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4166        synchronized (this) {
4167            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4168        }
4169    }
4170
4171    @Override
4172    public void setFrontActivityScreenCompatMode(int mode) {
4173        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4174                "setFrontActivityScreenCompatMode");
4175        synchronized (this) {
4176            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4177        }
4178    }
4179
4180    @Override
4181    public int getPackageScreenCompatMode(String packageName) {
4182        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4183        synchronized (this) {
4184            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4185        }
4186    }
4187
4188    @Override
4189    public void setPackageScreenCompatMode(String packageName, int mode) {
4190        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4191                "setPackageScreenCompatMode");
4192        synchronized (this) {
4193            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4194        }
4195    }
4196
4197    @Override
4198    public boolean getPackageAskScreenCompat(String packageName) {
4199        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4200        synchronized (this) {
4201            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4202        }
4203    }
4204
4205    @Override
4206    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4207        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4208                "setPackageAskScreenCompat");
4209        synchronized (this) {
4210            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4211        }
4212    }
4213
4214    private boolean hasUsageStatsPermission(String callingPackage) {
4215        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4216                Binder.getCallingUid(), callingPackage);
4217        if (mode == AppOpsManager.MODE_DEFAULT) {
4218            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4219                    == PackageManager.PERMISSION_GRANTED;
4220        }
4221        return mode == AppOpsManager.MODE_ALLOWED;
4222    }
4223
4224    @Override
4225    public int getPackageProcessState(String packageName, String callingPackage) {
4226        if (!hasUsageStatsPermission(callingPackage)) {
4227            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4228                    "getPackageProcessState");
4229        }
4230
4231        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4232        synchronized (this) {
4233            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4234                final ProcessRecord proc = mLruProcesses.get(i);
4235                if (procState > proc.setProcState) {
4236                    if (proc.pkgList.containsKey(packageName) ||
4237                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4238                        procState = proc.setProcState;
4239                    }
4240                }
4241            }
4242        }
4243        return procState;
4244    }
4245
4246    @Override
4247    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4248            throws RemoteException {
4249        synchronized (this) {
4250            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4251            if (app == null) {
4252                throw new IllegalArgumentException("Unknown process: " + process);
4253            }
4254            if (app.thread == null) {
4255                throw new IllegalArgumentException("Process has no app thread");
4256            }
4257            if (app.trimMemoryLevel >= level) {
4258                throw new IllegalArgumentException(
4259                        "Unable to set a higher trim level than current level");
4260            }
4261            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4262                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4263                throw new IllegalArgumentException("Unable to set a background trim level "
4264                    + "on a foreground process");
4265            }
4266            app.thread.scheduleTrimMemory(level);
4267            app.trimMemoryLevel = level;
4268            return true;
4269        }
4270    }
4271
4272    private void dispatchProcessesChanged() {
4273        int N;
4274        synchronized (this) {
4275            N = mPendingProcessChanges.size();
4276            if (mActiveProcessChanges.length < N) {
4277                mActiveProcessChanges = new ProcessChangeItem[N];
4278            }
4279            mPendingProcessChanges.toArray(mActiveProcessChanges);
4280            mPendingProcessChanges.clear();
4281            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4282                    "*** Delivering " + N + " process changes");
4283        }
4284
4285        int i = mProcessObservers.beginBroadcast();
4286        while (i > 0) {
4287            i--;
4288            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4289            if (observer != null) {
4290                try {
4291                    for (int j=0; j<N; j++) {
4292                        ProcessChangeItem item = mActiveProcessChanges[j];
4293                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4294                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4295                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4296                                    + item.uid + ": " + item.foregroundActivities);
4297                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4298                                    item.foregroundActivities);
4299                        }
4300                    }
4301                } catch (RemoteException e) {
4302                }
4303            }
4304        }
4305        mProcessObservers.finishBroadcast();
4306
4307        synchronized (this) {
4308            for (int j=0; j<N; j++) {
4309                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4310            }
4311        }
4312    }
4313
4314    private void dispatchProcessDied(int pid, int uid) {
4315        int i = mProcessObservers.beginBroadcast();
4316        while (i > 0) {
4317            i--;
4318            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4319            if (observer != null) {
4320                try {
4321                    observer.onProcessDied(pid, uid);
4322                } catch (RemoteException e) {
4323                }
4324            }
4325        }
4326        mProcessObservers.finishBroadcast();
4327    }
4328
4329    @VisibleForTesting
4330    void dispatchUidsChanged() {
4331        int N;
4332        synchronized (this) {
4333            N = mPendingUidChanges.size();
4334            if (mActiveUidChanges.length < N) {
4335                mActiveUidChanges = new UidRecord.ChangeItem[N];
4336            }
4337            for (int i=0; i<N; i++) {
4338                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4339                mActiveUidChanges[i] = change;
4340                if (change.uidRecord != null) {
4341                    change.uidRecord.pendingChange = null;
4342                    change.uidRecord = null;
4343                }
4344            }
4345            mPendingUidChanges.clear();
4346            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4347                    "*** Delivering " + N + " uid changes");
4348        }
4349
4350        int i = mUidObservers.beginBroadcast();
4351        while (i > 0) {
4352            i--;
4353            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4354                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4355        }
4356        mUidObservers.finishBroadcast();
4357
4358        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4359            for (int j = 0; j < N; ++j) {
4360                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4361                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4362                    mValidateUids.remove(item.uid);
4363                } else {
4364                    UidRecord validateUid = mValidateUids.get(item.uid);
4365                    if (validateUid == null) {
4366                        validateUid = new UidRecord(item.uid);
4367                        mValidateUids.put(item.uid, validateUid);
4368                    }
4369                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4370                        validateUid.idle = true;
4371                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4372                        validateUid.idle = false;
4373                    }
4374                    validateUid.curProcState = validateUid.setProcState = item.processState;
4375                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4376                }
4377            }
4378        }
4379
4380        synchronized (this) {
4381            for (int j = 0; j < N; j++) {
4382                mAvailUidChanges.add(mActiveUidChanges[j]);
4383            }
4384        }
4385    }
4386
4387    private void dispatchUidsChangedForObserver(IUidObserver observer,
4388            UidObserverRegistration reg, int changesSize) {
4389        if (observer == null) {
4390            return;
4391        }
4392        try {
4393            for (int j = 0; j < changesSize; j++) {
4394                UidRecord.ChangeItem item = mActiveUidChanges[j];
4395                final int change = item.change;
4396                if (change == UidRecord.CHANGE_PROCSTATE &&
4397                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4398                    // No-op common case: no significant change, the observer is not
4399                    // interested in all proc state changes.
4400                    continue;
4401                }
4402                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4403                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4404                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4405                                "UID idle uid=" + item.uid);
4406                        observer.onUidIdle(item.uid, item.ephemeral);
4407                    }
4408                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4409                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4410                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4411                                "UID active uid=" + item.uid);
4412                        observer.onUidActive(item.uid);
4413                    }
4414                }
4415                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4416                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4417                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4418                                "UID cached uid=" + item.uid);
4419                        observer.onUidCachedChanged(item.uid, true);
4420                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4421                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422                                "UID active uid=" + item.uid);
4423                        observer.onUidCachedChanged(item.uid, false);
4424                    }
4425                }
4426                if ((change & UidRecord.CHANGE_GONE) != 0) {
4427                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4428                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4429                                "UID gone uid=" + item.uid);
4430                        observer.onUidGone(item.uid, item.ephemeral);
4431                    }
4432                    if (reg.lastProcStates != null) {
4433                        reg.lastProcStates.delete(item.uid);
4434                    }
4435                } else {
4436                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4437                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4438                                "UID CHANGED uid=" + item.uid
4439                                        + ": " + item.processState);
4440                        boolean doReport = true;
4441                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4442                            final int lastState = reg.lastProcStates.get(item.uid,
4443                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4444                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4445                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4446                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4447                                doReport = lastAboveCut != newAboveCut;
4448                            } else {
4449                                doReport = item.processState
4450                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4451                            }
4452                        }
4453                        if (doReport) {
4454                            if (reg.lastProcStates != null) {
4455                                reg.lastProcStates.put(item.uid, item.processState);
4456                            }
4457                            observer.onUidStateChanged(item.uid, item.processState,
4458                                    item.procStateSeq);
4459                        }
4460                    }
4461                }
4462            }
4463        } catch (RemoteException e) {
4464        }
4465    }
4466
4467    void dispatchOomAdjObserver(String msg) {
4468        OomAdjObserver observer;
4469        synchronized (this) {
4470            observer = mCurOomAdjObserver;
4471        }
4472
4473        if (observer != null) {
4474            observer.onOomAdjMessage(msg);
4475        }
4476    }
4477
4478    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4479        synchronized (this) {
4480            mCurOomAdjUid = uid;
4481            mCurOomAdjObserver = observer;
4482        }
4483    }
4484
4485    void clearOomAdjObserver() {
4486        synchronized (this) {
4487            mCurOomAdjUid = -1;
4488            mCurOomAdjObserver = null;
4489        }
4490    }
4491
4492    void reportOomAdjMessageLocked(String tag, String msg) {
4493        Slog.d(tag, msg);
4494        if (mCurOomAdjObserver != null) {
4495            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4496        }
4497    }
4498
4499    @Override
4500    public final int startActivity(IApplicationThread caller, String callingPackage,
4501            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4502            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4503        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4504                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4505                UserHandle.getCallingUserId());
4506    }
4507
4508    @Override
4509    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4510            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4511            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4512        enforceNotIsolatedCaller("startActivity");
4513        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4514                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4515        // TODO: Switch to user app stacks here.
4516        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4517                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4518                profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4519    }
4520
4521    @Override
4522    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4523            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4524            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4525            int userId) {
4526
4527        // This is very dangerous -- it allows you to perform a start activity (including
4528        // permission grants) as any app that may launch one of your own activities.  So
4529        // we will only allow this to be done from activities that are part of the core framework,
4530        // and then only when they are running as the system.
4531        final ActivityRecord sourceRecord;
4532        final int targetUid;
4533        final String targetPackage;
4534        synchronized (this) {
4535            if (resultTo == null) {
4536                throw new SecurityException("Must be called from an activity");
4537            }
4538            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4539            if (sourceRecord == null) {
4540                throw new SecurityException("Called with bad activity token: " + resultTo);
4541            }
4542            if (!sourceRecord.info.packageName.equals("android")) {
4543                throw new SecurityException(
4544                        "Must be called from an activity that is declared in the android package");
4545            }
4546            if (sourceRecord.app == null) {
4547                throw new SecurityException("Called without a process attached to activity");
4548            }
4549            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4550                // This is still okay, as long as this activity is running under the
4551                // uid of the original calling activity.
4552                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4553                    throw new SecurityException(
4554                            "Calling activity in uid " + sourceRecord.app.uid
4555                                    + " must be system uid or original calling uid "
4556                                    + sourceRecord.launchedFromUid);
4557                }
4558            }
4559            if (ignoreTargetSecurity) {
4560                if (intent.getComponent() == null) {
4561                    throw new SecurityException(
4562                            "Component must be specified with ignoreTargetSecurity");
4563                }
4564                if (intent.getSelector() != null) {
4565                    throw new SecurityException(
4566                            "Selector not allowed with ignoreTargetSecurity");
4567                }
4568            }
4569            targetUid = sourceRecord.launchedFromUid;
4570            targetPackage = sourceRecord.launchedFromPackage;
4571        }
4572
4573        if (userId == UserHandle.USER_NULL) {
4574            userId = UserHandle.getUserId(sourceRecord.app.uid);
4575        }
4576
4577        // TODO: Switch to user app stacks here.
4578        try {
4579            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4580                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4581                    null, null, bOptions, ignoreTargetSecurity, userId, null,
4582                    "startActivityAsCaller");
4583            return ret;
4584        } catch (SecurityException e) {
4585            // XXX need to figure out how to propagate to original app.
4586            // A SecurityException here is generally actually a fault of the original
4587            // calling activity (such as a fairly granting permissions), so propagate it
4588            // back to them.
4589            /*
4590            StringBuilder msg = new StringBuilder();
4591            msg.append("While launching");
4592            msg.append(intent.toString());
4593            msg.append(": ");
4594            msg.append(e.getMessage());
4595            */
4596            throw e;
4597        }
4598    }
4599
4600    @Override
4601    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4602            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4603            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4604        enforceNotIsolatedCaller("startActivityAndWait");
4605        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4606                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4607        WaitResult res = new WaitResult();
4608        // TODO: Switch to user app stacks here.
4609        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4610                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4611                bOptions, false, userId, null, "startActivityAndWait");
4612        return res;
4613    }
4614
4615    @Override
4616    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4617            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4618            int startFlags, Configuration config, Bundle bOptions, int userId) {
4619        enforceNotIsolatedCaller("startActivityWithConfig");
4620        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4621                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4622        // TODO: Switch to user app stacks here.
4623        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4624                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4625                null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4626        return ret;
4627    }
4628
4629    @Override
4630    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4631            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4632            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4633            throws TransactionTooLargeException {
4634        enforceNotIsolatedCaller("startActivityIntentSender");
4635        // Refuse possible leaked file descriptors
4636        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4637            throw new IllegalArgumentException("File descriptors passed in Intent");
4638        }
4639
4640        if (!(target instanceof PendingIntentRecord)) {
4641            throw new IllegalArgumentException("Bad PendingIntent object");
4642        }
4643
4644        PendingIntentRecord pir = (PendingIntentRecord)target;
4645
4646        synchronized (this) {
4647            // If this is coming from the currently resumed activity, it is
4648            // effectively saying that app switches are allowed at this point.
4649            final ActivityStack stack = getFocusedStack();
4650            if (stack.mResumedActivity != null &&
4651                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4652                mAppSwitchesAllowedTime = 0;
4653            }
4654        }
4655        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4656                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4657        return ret;
4658    }
4659
4660    @Override
4661    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4662            Intent intent, String resolvedType, IVoiceInteractionSession session,
4663            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4664            Bundle bOptions, int userId) {
4665        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4666                != PackageManager.PERMISSION_GRANTED) {
4667            String msg = "Permission Denial: startVoiceActivity() from pid="
4668                    + Binder.getCallingPid()
4669                    + ", uid=" + Binder.getCallingUid()
4670                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4671            Slog.w(TAG, msg);
4672            throw new SecurityException(msg);
4673        }
4674        if (session == null || interactor == null) {
4675            throw new NullPointerException("null session or interactor");
4676        }
4677        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4678                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4679        // TODO: Switch to user app stacks here.
4680        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4681                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4682                null, bOptions, false, userId, null, "startVoiceActivity");
4683    }
4684
4685    @Override
4686    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4687            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4688        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4689                != PackageManager.PERMISSION_GRANTED) {
4690            final String msg = "Permission Denial: startAssistantActivity() from pid="
4691                    + Binder.getCallingPid()
4692                    + ", uid=" + Binder.getCallingUid()
4693                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4694            Slog.w(TAG, msg);
4695            throw new SecurityException(msg);
4696        }
4697        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4698                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4699        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4700                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4701                userId, null, "startAssistantActivity");
4702    }
4703
4704    @Override
4705    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4706            throws RemoteException {
4707        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4708        synchronized (this) {
4709            ActivityRecord activity = getFocusedStack().topActivity();
4710            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4711                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4712            }
4713            if (mRunningVoice != null || activity.getTask().voiceSession != null
4714                    || activity.voiceSession != null) {
4715                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4716                return;
4717            }
4718            if (activity.pendingVoiceInteractionStart) {
4719                Slog.w(TAG, "Pending start of voice interaction already.");
4720                return;
4721            }
4722            activity.pendingVoiceInteractionStart = true;
4723        }
4724        LocalServices.getService(VoiceInteractionManagerInternal.class)
4725                .startLocalVoiceInteraction(callingActivity, options);
4726    }
4727
4728    @Override
4729    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4730        LocalServices.getService(VoiceInteractionManagerInternal.class)
4731                .stopLocalVoiceInteraction(callingActivity);
4732    }
4733
4734    @Override
4735    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4736        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4737                .supportsLocalVoiceInteraction();
4738    }
4739
4740    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4741            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4742        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4743        if (activityToCallback == null) return;
4744        activityToCallback.setVoiceSessionLocked(voiceSession);
4745
4746        // Inform the activity
4747        try {
4748            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4749                    voiceInteractor);
4750            long token = Binder.clearCallingIdentity();
4751            try {
4752                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4753            } finally {
4754                Binder.restoreCallingIdentity(token);
4755            }
4756            // TODO: VI Should we cache the activity so that it's easier to find later
4757            // rather than scan through all the stacks and activities?
4758        } catch (RemoteException re) {
4759            activityToCallback.clearVoiceSessionLocked();
4760            // TODO: VI Should this terminate the voice session?
4761        }
4762    }
4763
4764    @Override
4765    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4766        synchronized (this) {
4767            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4768                if (keepAwake) {
4769                    mVoiceWakeLock.acquire();
4770                } else {
4771                    mVoiceWakeLock.release();
4772                }
4773            }
4774        }
4775    }
4776
4777    @Override
4778    public boolean startNextMatchingActivity(IBinder callingActivity,
4779            Intent intent, Bundle bOptions) {
4780        // Refuse possible leaked file descriptors
4781        if (intent != null && intent.hasFileDescriptors() == true) {
4782            throw new IllegalArgumentException("File descriptors passed in Intent");
4783        }
4784        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4785
4786        synchronized (this) {
4787            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4788            if (r == null) {
4789                ActivityOptions.abort(options);
4790                return false;
4791            }
4792            if (r.app == null || r.app.thread == null) {
4793                // The caller is not running...  d'oh!
4794                ActivityOptions.abort(options);
4795                return false;
4796            }
4797            intent = new Intent(intent);
4798            // The caller is not allowed to change the data.
4799            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4800            // And we are resetting to find the next component...
4801            intent.setComponent(null);
4802
4803            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4804
4805            ActivityInfo aInfo = null;
4806            try {
4807                List<ResolveInfo> resolves =
4808                    AppGlobals.getPackageManager().queryIntentActivities(
4809                            intent, r.resolvedType,
4810                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4811                            UserHandle.getCallingUserId()).getList();
4812
4813                // Look for the original activity in the list...
4814                final int N = resolves != null ? resolves.size() : 0;
4815                for (int i=0; i<N; i++) {
4816                    ResolveInfo rInfo = resolves.get(i);
4817                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4818                            && rInfo.activityInfo.name.equals(r.info.name)) {
4819                        // We found the current one...  the next matching is
4820                        // after it.
4821                        i++;
4822                        if (i<N) {
4823                            aInfo = resolves.get(i).activityInfo;
4824                        }
4825                        if (debug) {
4826                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4827                                    + "/" + r.info.name);
4828                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4829                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4830                        }
4831                        break;
4832                    }
4833                }
4834            } catch (RemoteException e) {
4835            }
4836
4837            if (aInfo == null) {
4838                // Nobody who is next!
4839                ActivityOptions.abort(options);
4840                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4841                return false;
4842            }
4843
4844            intent.setComponent(new ComponentName(
4845                    aInfo.applicationInfo.packageName, aInfo.name));
4846            intent.setFlags(intent.getFlags()&~(
4847                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4848                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4849                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4850                    Intent.FLAG_ACTIVITY_NEW_TASK));
4851
4852            // Okay now we need to start the new activity, replacing the
4853            // currently running activity.  This is a little tricky because
4854            // we want to start the new one as if the current one is finished,
4855            // but not finish the current one first so that there is no flicker.
4856            // And thus...
4857            final boolean wasFinishing = r.finishing;
4858            r.finishing = true;
4859
4860            // Propagate reply information over to the new activity.
4861            final ActivityRecord resultTo = r.resultTo;
4862            final String resultWho = r.resultWho;
4863            final int requestCode = r.requestCode;
4864            r.resultTo = null;
4865            if (resultTo != null) {
4866                resultTo.removeResultsLocked(r, resultWho, requestCode);
4867            }
4868
4869            final long origId = Binder.clearCallingIdentity();
4870            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4871                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4872                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4873                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4874                    false, false, null, null, "startNextMatchingActivity");
4875            Binder.restoreCallingIdentity(origId);
4876
4877            r.finishing = wasFinishing;
4878            if (res != ActivityManager.START_SUCCESS) {
4879                return false;
4880            }
4881            return true;
4882        }
4883    }
4884
4885    @Override
4886    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4887        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4888            String msg = "Permission Denial: startActivityFromRecents called without " +
4889                    START_TASKS_FROM_RECENTS;
4890            Slog.w(TAG, msg);
4891            throw new SecurityException(msg);
4892        }
4893        final long origId = Binder.clearCallingIdentity();
4894        try {
4895            synchronized (this) {
4896                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4897            }
4898        } finally {
4899            Binder.restoreCallingIdentity(origId);
4900        }
4901    }
4902
4903    final int startActivityInPackage(int uid, String callingPackage,
4904            Intent intent, String resolvedType, IBinder resultTo,
4905            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4906            TaskRecord inTask, String reason) {
4907
4908        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4909                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4910
4911        // TODO: Switch to user app stacks here.
4912        return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4913                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4914                null, null, null, bOptions, false, userId, inTask, reason);
4915    }
4916
4917    @Override
4918    public final int startActivities(IApplicationThread caller, String callingPackage,
4919            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4920            int userId) {
4921        final String reason = "startActivities";
4922        enforceNotIsolatedCaller(reason);
4923        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4924                userId, false, ALLOW_FULL_ONLY, reason, null);
4925        // TODO: Switch to user app stacks here.
4926        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4927                resolvedTypes, resultTo, bOptions, userId, reason);
4928        return ret;
4929    }
4930
4931    final int startActivitiesInPackage(int uid, String callingPackage,
4932            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4933            Bundle bOptions, int userId) {
4934
4935        final String reason = "startActivityInPackage";
4936        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4937                userId, false, ALLOW_FULL_ONLY, reason, null);
4938        // TODO: Switch to user app stacks here.
4939        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4940                resultTo, bOptions, userId, reason);
4941        return ret;
4942    }
4943
4944    @Override
4945    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4946        synchronized (this) {
4947            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4948            if (r == null) {
4949                return;
4950            }
4951            r.reportFullyDrawnLocked(restoredFromBundle);
4952        }
4953    }
4954
4955    @Override
4956    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4957        synchronized (this) {
4958            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4959            if (r == null) {
4960                return;
4961            }
4962            final long origId = Binder.clearCallingIdentity();
4963            try {
4964                r.setRequestedOrientation(requestedOrientation);
4965            } finally {
4966                Binder.restoreCallingIdentity(origId);
4967            }
4968        }
4969    }
4970
4971    @Override
4972    public int getRequestedOrientation(IBinder token) {
4973        synchronized (this) {
4974            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4975            if (r == null) {
4976                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4977            }
4978            return r.getRequestedOrientation();
4979        }
4980    }
4981
4982    @Override
4983    public final void requestActivityRelaunch(IBinder token) {
4984        synchronized(this) {
4985            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4986            if (r == null) {
4987                return;
4988            }
4989            final long origId = Binder.clearCallingIdentity();
4990            try {
4991                r.forceNewConfig = true;
4992                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4993                        true /* preserveWindow */);
4994            } finally {
4995                Binder.restoreCallingIdentity(origId);
4996            }
4997        }
4998    }
4999
5000    /**
5001     * This is the internal entry point for handling Activity.finish().
5002     *
5003     * @param token The Binder token referencing the Activity we want to finish.
5004     * @param resultCode Result code, if any, from this Activity.
5005     * @param resultData Result data (Intent), if any, from this Activity.
5006     * @param finishTask Whether to finish the task associated with this Activity.
5007     *
5008     * @return Returns true if the activity successfully finished, or false if it is still running.
5009     */
5010    @Override
5011    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5012            int finishTask) {
5013        // Refuse possible leaked file descriptors
5014        if (resultData != null && resultData.hasFileDescriptors() == true) {
5015            throw new IllegalArgumentException("File descriptors passed in Intent");
5016        }
5017
5018        synchronized(this) {
5019            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5020            if (r == null) {
5021                return true;
5022            }
5023            // Keep track of the root activity of the task before we finish it
5024            TaskRecord tr = r.getTask();
5025            ActivityRecord rootR = tr.getRootActivity();
5026            if (rootR == null) {
5027                Slog.w(TAG, "Finishing task with all activities already finished");
5028            }
5029            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5030            // finish.
5031            if (mLockTaskController.activityBlockedFromFinish(r)) {
5032                return false;
5033            }
5034
5035            if (mController != null) {
5036                // Find the first activity that is not finishing.
5037                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5038                if (next != null) {
5039                    // ask watcher if this is allowed
5040                    boolean resumeOK = true;
5041                    try {
5042                        resumeOK = mController.activityResuming(next.packageName);
5043                    } catch (RemoteException e) {
5044                        mController = null;
5045                        Watchdog.getInstance().setActivityController(null);
5046                    }
5047
5048                    if (!resumeOK) {
5049                        Slog.i(TAG, "Not finishing activity because controller resumed");
5050                        return false;
5051                    }
5052                }
5053            }
5054            final long origId = Binder.clearCallingIdentity();
5055            try {
5056                boolean res;
5057                final boolean finishWithRootActivity =
5058                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5059                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5060                        || (finishWithRootActivity && r == rootR)) {
5061                    // If requested, remove the task that is associated to this activity only if it
5062                    // was the root activity in the task. The result code and data is ignored
5063                    // because we don't support returning them across task boundaries. Also, to
5064                    // keep backwards compatibility we remove the task from recents when finishing
5065                    // task with root activity.
5066                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5067                    if (!res) {
5068                        Slog.i(TAG, "Removing task failed to finish activity");
5069                    }
5070                } else {
5071                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5072                            resultData, "app-request", true);
5073                    if (!res) {
5074                        Slog.i(TAG, "Failed to finish by app-request");
5075                    }
5076                }
5077                return res;
5078            } finally {
5079                Binder.restoreCallingIdentity(origId);
5080            }
5081        }
5082    }
5083
5084    @Override
5085    public final void finishHeavyWeightApp() {
5086        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5087                != PackageManager.PERMISSION_GRANTED) {
5088            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5089                    + Binder.getCallingPid()
5090                    + ", uid=" + Binder.getCallingUid()
5091                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5092            Slog.w(TAG, msg);
5093            throw new SecurityException(msg);
5094        }
5095
5096        synchronized(this) {
5097            if (mHeavyWeightProcess == null) {
5098                return;
5099            }
5100
5101            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5102            for (int i = 0; i < activities.size(); i++) {
5103                ActivityRecord r = activities.get(i);
5104                if (!r.finishing && r.isInStackLocked()) {
5105                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5106                            null, "finish-heavy", true);
5107                }
5108            }
5109
5110            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5111                    mHeavyWeightProcess.userId, 0));
5112            mHeavyWeightProcess = null;
5113        }
5114    }
5115
5116    @Override
5117    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5118            String message) {
5119        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5120                != PackageManager.PERMISSION_GRANTED) {
5121            String msg = "Permission Denial: crashApplication() from pid="
5122                    + Binder.getCallingPid()
5123                    + ", uid=" + Binder.getCallingUid()
5124                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5125            Slog.w(TAG, msg);
5126            throw new SecurityException(msg);
5127        }
5128
5129        synchronized(this) {
5130            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5131        }
5132    }
5133
5134    @Override
5135    public final void finishSubActivity(IBinder token, String resultWho,
5136            int requestCode) {
5137        synchronized(this) {
5138            final long origId = Binder.clearCallingIdentity();
5139            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5140            if (r != null) {
5141                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5142            }
5143            Binder.restoreCallingIdentity(origId);
5144        }
5145    }
5146
5147    @Override
5148    public boolean finishActivityAffinity(IBinder token) {
5149        synchronized(this) {
5150            final long origId = Binder.clearCallingIdentity();
5151            try {
5152                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5153                if (r == null) {
5154                    return false;
5155                }
5156
5157                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5158                // can finish.
5159                final TaskRecord task = r.getTask();
5160                if (mLockTaskController.activityBlockedFromFinish(r)) {
5161                    return false;
5162                }
5163                return task.getStack().finishActivityAffinityLocked(r);
5164            } finally {
5165                Binder.restoreCallingIdentity(origId);
5166            }
5167        }
5168    }
5169
5170    @Override
5171    public void finishVoiceTask(IVoiceInteractionSession session) {
5172        synchronized (this) {
5173            final long origId = Binder.clearCallingIdentity();
5174            try {
5175                // TODO: VI Consider treating local voice interactions and voice tasks
5176                // differently here
5177                mStackSupervisor.finishVoiceTask(session);
5178            } finally {
5179                Binder.restoreCallingIdentity(origId);
5180            }
5181        }
5182
5183    }
5184
5185    @Override
5186    public boolean releaseActivityInstance(IBinder token) {
5187        synchronized(this) {
5188            final long origId = Binder.clearCallingIdentity();
5189            try {
5190                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5191                if (r == null) {
5192                    return false;
5193                }
5194                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5195            } finally {
5196                Binder.restoreCallingIdentity(origId);
5197            }
5198        }
5199    }
5200
5201    @Override
5202    public void releaseSomeActivities(IApplicationThread appInt) {
5203        synchronized(this) {
5204            final long origId = Binder.clearCallingIdentity();
5205            try {
5206                ProcessRecord app = getRecordForAppLocked(appInt);
5207                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5208            } finally {
5209                Binder.restoreCallingIdentity(origId);
5210            }
5211        }
5212    }
5213
5214    @Override
5215    public boolean willActivityBeVisible(IBinder token) {
5216        synchronized(this) {
5217            ActivityStack stack = ActivityRecord.getStackLocked(token);
5218            if (stack != null) {
5219                return stack.willActivityBeVisibleLocked(token);
5220            }
5221            return false;
5222        }
5223    }
5224
5225    @Override
5226    public void overridePendingTransition(IBinder token, String packageName,
5227            int enterAnim, int exitAnim) {
5228        synchronized(this) {
5229            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5230            if (self == null) {
5231                return;
5232            }
5233
5234            final long origId = Binder.clearCallingIdentity();
5235
5236            if (self.state == ActivityState.RESUMED
5237                    || self.state == ActivityState.PAUSING) {
5238                mWindowManager.overridePendingAppTransition(packageName,
5239                        enterAnim, exitAnim, null);
5240            }
5241
5242            Binder.restoreCallingIdentity(origId);
5243        }
5244    }
5245
5246    /**
5247     * Main function for removing an existing process from the activity manager
5248     * as a result of that process going away.  Clears out all connections
5249     * to the process.
5250     */
5251    private final void handleAppDiedLocked(ProcessRecord app,
5252            boolean restarting, boolean allowRestart) {
5253        int pid = app.pid;
5254        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5255                false /*replacingPid*/);
5256        if (!kept && !restarting) {
5257            removeLruProcessLocked(app);
5258            if (pid > 0) {
5259                ProcessList.remove(pid);
5260            }
5261        }
5262
5263        if (mProfileProc == app) {
5264            clearProfilerLocked();
5265        }
5266
5267        // Remove this application's activities from active lists.
5268        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5269
5270        app.activities.clear();
5271
5272        if (app.instr != null) {
5273            Slog.w(TAG, "Crash of app " + app.processName
5274                  + " running instrumentation " + app.instr.mClass);
5275            Bundle info = new Bundle();
5276            info.putString("shortMsg", "Process crashed.");
5277            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5278        }
5279
5280        mWindowManager.deferSurfaceLayout();
5281        try {
5282            if (!restarting && hasVisibleActivities
5283                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5284                // If there was nothing to resume, and we are not already restarting this process, but
5285                // there is a visible activity that is hosted by the process...  then make sure all
5286                // visible activities are running, taking care of restarting this process.
5287                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5288            }
5289        } finally {
5290            mWindowManager.continueSurfaceLayout();
5291        }
5292    }
5293
5294    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5295        final IBinder threadBinder = thread.asBinder();
5296        // Find the application record.
5297        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5298            final ProcessRecord rec = mLruProcesses.get(i);
5299            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5300                return i;
5301            }
5302        }
5303        return -1;
5304    }
5305
5306    final ProcessRecord getRecordForAppLocked(
5307            IApplicationThread thread) {
5308        if (thread == null) {
5309            return null;
5310        }
5311
5312        int appIndex = getLRURecordIndexForAppLocked(thread);
5313        if (appIndex >= 0) {
5314            return mLruProcesses.get(appIndex);
5315        }
5316
5317        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5318        // double-check that.
5319        final IBinder threadBinder = thread.asBinder();
5320        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5321        for (int i = pmap.size()-1; i >= 0; i--) {
5322            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5323            for (int j = procs.size()-1; j >= 0; j--) {
5324                final ProcessRecord proc = procs.valueAt(j);
5325                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5326                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5327                            + proc);
5328                    return proc;
5329                }
5330            }
5331        }
5332
5333        return null;
5334    }
5335
5336    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5337        // If there are no longer any background processes running,
5338        // and the app that died was not running instrumentation,
5339        // then tell everyone we are now low on memory.
5340        boolean haveBg = false;
5341        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5342            ProcessRecord rec = mLruProcesses.get(i);
5343            if (rec.thread != null
5344                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5345                haveBg = true;
5346                break;
5347            }
5348        }
5349
5350        if (!haveBg) {
5351            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5352            if (doReport) {
5353                long now = SystemClock.uptimeMillis();
5354                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5355                    doReport = false;
5356                } else {
5357                    mLastMemUsageReportTime = now;
5358                }
5359            }
5360            final ArrayList<ProcessMemInfo> memInfos
5361                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5362            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5363            long now = SystemClock.uptimeMillis();
5364            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5365                ProcessRecord rec = mLruProcesses.get(i);
5366                if (rec == dyingProc || rec.thread == null) {
5367                    continue;
5368                }
5369                if (doReport) {
5370                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5371                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5372                }
5373                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5374                    // The low memory report is overriding any current
5375                    // state for a GC request.  Make sure to do
5376                    // heavy/important/visible/foreground processes first.
5377                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5378                        rec.lastRequestedGc = 0;
5379                    } else {
5380                        rec.lastRequestedGc = rec.lastLowMemory;
5381                    }
5382                    rec.reportLowMemory = true;
5383                    rec.lastLowMemory = now;
5384                    mProcessesToGc.remove(rec);
5385                    addProcessToGcListLocked(rec);
5386                }
5387            }
5388            if (doReport) {
5389                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5390                mHandler.sendMessage(msg);
5391            }
5392            scheduleAppGcsLocked();
5393        }
5394    }
5395
5396    final void appDiedLocked(ProcessRecord app) {
5397       appDiedLocked(app, app.pid, app.thread, false);
5398    }
5399
5400    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5401            boolean fromBinderDied) {
5402        // First check if this ProcessRecord is actually active for the pid.
5403        synchronized (mPidsSelfLocked) {
5404            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5405            if (curProc != app) {
5406                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5407                return;
5408            }
5409        }
5410
5411        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5412        synchronized (stats) {
5413            stats.noteProcessDiedLocked(app.info.uid, pid);
5414        }
5415
5416        if (!app.killed) {
5417            if (!fromBinderDied) {
5418                killProcessQuiet(pid);
5419            }
5420            killProcessGroup(app.uid, pid);
5421            app.killed = true;
5422        }
5423
5424        // Clean up already done if the process has been re-started.
5425        if (app.pid == pid && app.thread != null &&
5426                app.thread.asBinder() == thread.asBinder()) {
5427            boolean doLowMem = app.instr == null;
5428            boolean doOomAdj = doLowMem;
5429            if (!app.killedByAm) {
5430                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5431                        + ProcessList.makeOomAdjString(app.setAdj)
5432                        + ProcessList.makeProcStateString(app.setProcState));
5433                mAllowLowerMemLevel = true;
5434            } else {
5435                // Note that we always want to do oom adj to update our state with the
5436                // new number of procs.
5437                mAllowLowerMemLevel = false;
5438                doLowMem = false;
5439            }
5440            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5441                    app.setAdj, app.setProcState);
5442            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5443                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5444            handleAppDiedLocked(app, false, true);
5445
5446            if (doOomAdj) {
5447                updateOomAdjLocked();
5448            }
5449            if (doLowMem) {
5450                doLowMemReportIfNeededLocked(app);
5451            }
5452        } else if (app.pid != pid) {
5453            // A new process has already been started.
5454            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5455                    + ") has died and restarted (pid " + app.pid + ").");
5456            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5457        } else if (DEBUG_PROCESSES) {
5458            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5459                    + thread.asBinder());
5460        }
5461    }
5462
5463    /**
5464     * If a stack trace dump file is configured, dump process stack traces.
5465     * @param clearTraces causes the dump file to be erased prior to the new
5466     *    traces being written, if true; when false, the new traces will be
5467     *    appended to any existing file content.
5468     * @param firstPids of dalvik VM processes to dump stack traces for first
5469     * @param lastPids of dalvik VM processes to dump stack traces for last
5470     * @param nativePids optional list of native pids to dump stack crawls
5471     */
5472    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5473            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5474            ArrayList<Integer> nativePids) {
5475        ArrayList<Integer> extraPids = null;
5476
5477        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5478        // of the top users at the time of the request.
5479        if (processCpuTracker != null) {
5480            processCpuTracker.init();
5481            try {
5482                Thread.sleep(200);
5483            } catch (InterruptedException ignored) {
5484            }
5485
5486            processCpuTracker.update();
5487
5488            // We'll take the stack crawls of just the top apps using CPU.
5489            final int N = processCpuTracker.countWorkingStats();
5490            extraPids = new ArrayList<>();
5491            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5492                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5493                if (lastPids.indexOfKey(stats.pid) >= 0) {
5494                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5495
5496                    extraPids.add(stats.pid);
5497                } else if (DEBUG_ANR) {
5498                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5499                            + stats.pid);
5500                }
5501            }
5502        }
5503
5504        boolean useTombstonedForJavaTraces = false;
5505        File tracesFile;
5506
5507        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5508        if (tracesDirProp.isEmpty()) {
5509            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5510            // dumping scheme. All traces are written to a global trace file (usually
5511            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5512            // the file if requested.
5513            //
5514            // This mode of operation will be removed in the near future.
5515
5516
5517            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5518            if (globalTracesPath.isEmpty()) {
5519                Slog.w(TAG, "dumpStackTraces: no trace path configured");
5520                return null;
5521            }
5522
5523            tracesFile = new File(globalTracesPath);
5524            try {
5525                if (clearTraces && tracesFile.exists()) {
5526                    tracesFile.delete();
5527                }
5528
5529                tracesFile.createNewFile();
5530                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5531            } catch (IOException e) {
5532                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5533                return null;
5534            }
5535        } else {
5536            File tracesDir = new File(tracesDirProp);
5537            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5538            // Each set of ANR traces is written to a separate file and dumpstate will process
5539            // all such files and add them to a captured bug report if they're recent enough.
5540            maybePruneOldTraces(tracesDir);
5541
5542            // NOTE: We should consider creating the file in native code atomically once we've
5543            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5544            // can be removed.
5545            tracesFile = createAnrDumpFile(tracesDir);
5546            if (tracesFile == null) {
5547                return null;
5548            }
5549
5550            useTombstonedForJavaTraces = true;
5551        }
5552
5553        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5554                useTombstonedForJavaTraces);
5555        return tracesFile;
5556    }
5557
5558    @GuardedBy("ActivityManagerService.class")
5559    private static SimpleDateFormat sAnrFileDateFormat;
5560
5561    private static synchronized File createAnrDumpFile(File tracesDir) {
5562        if (sAnrFileDateFormat == null) {
5563            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5564        }
5565
5566        final String formattedDate = sAnrFileDateFormat.format(new Date());
5567        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5568
5569        try {
5570            if (anrFile.createNewFile()) {
5571                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5572                return anrFile;
5573            } else {
5574                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5575            }
5576        } catch (IOException ioe) {
5577            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5578        }
5579
5580        return null;
5581    }
5582
5583    /**
5584     * Prune all trace files that are more than a day old.
5585     *
5586     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5587     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5588     * since it's the system_server that creates trace files for most ANRs.
5589     */
5590    private static void maybePruneOldTraces(File tracesDir) {
5591        final long now = System.currentTimeMillis();
5592        final File[] traceFiles = tracesDir.listFiles();
5593
5594        if (traceFiles != null) {
5595            for (File file : traceFiles) {
5596                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5597                    if (!file.delete()) {
5598                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
5599                    }
5600                }
5601            }
5602        }
5603    }
5604
5605    /**
5606     * Legacy code, do not use. Existing users will be deleted.
5607     *
5608     * @deprecated
5609     */
5610    @Deprecated
5611    public static class DumpStackFileObserver extends FileObserver {
5612        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5613        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5614
5615        private final String mTracesPath;
5616        private boolean mClosed;
5617
5618        public DumpStackFileObserver(String tracesPath) {
5619            super(tracesPath, FileObserver.CLOSE_WRITE);
5620            mTracesPath = tracesPath;
5621        }
5622
5623        @Override
5624        public synchronized void onEvent(int event, String path) {
5625            mClosed = true;
5626            notify();
5627        }
5628
5629        public long dumpWithTimeout(int pid, long timeout) {
5630            sendSignal(pid, SIGNAL_QUIT);
5631            final long start = SystemClock.elapsedRealtime();
5632
5633            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5634            synchronized (this) {
5635                try {
5636                    wait(waitTime); // Wait for traces file to be closed.
5637                } catch (InterruptedException e) {
5638                    Slog.wtf(TAG, e);
5639                }
5640            }
5641
5642            // This avoids a corner case of passing a negative time to the native
5643            // trace in case we've already hit the overall timeout.
5644            final long timeWaited = SystemClock.elapsedRealtime() - start;
5645            if (timeWaited >= timeout) {
5646                return timeWaited;
5647            }
5648
5649            if (!mClosed) {
5650                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5651                       ". Attempting native stack collection.");
5652
5653                final long nativeDumpTimeoutMs = Math.min(
5654                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5655
5656                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5657                        (int) (nativeDumpTimeoutMs / 1000));
5658            }
5659
5660            final long end = SystemClock.elapsedRealtime();
5661            mClosed = false;
5662
5663            return (end - start);
5664        }
5665    }
5666
5667    /**
5668     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5669     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5670     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5671     * attempting to obtain native traces in the case of a failure. Returns the total time spent
5672     * capturing traces.
5673     */
5674    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5675        final long timeStart = SystemClock.elapsedRealtime();
5676        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5677            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5678                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
5679        }
5680
5681        return SystemClock.elapsedRealtime() - timeStart;
5682    }
5683
5684    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5685            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5686            boolean useTombstonedForJavaTraces) {
5687
5688        // We don't need any sort of inotify based monitoring when we're dumping traces via
5689        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5690        // control of all writes to the file in question.
5691        final DumpStackFileObserver observer;
5692        if (useTombstonedForJavaTraces) {
5693            observer = null;
5694        } else {
5695            // Use a FileObserver to detect when traces finish writing.
5696            // The order of traces is considered important to maintain for legibility.
5697            observer = new DumpStackFileObserver(tracesFile);
5698        }
5699
5700        // We must complete all stack dumps within 20 seconds.
5701        long remainingTime = 20 * 1000;
5702        try {
5703            if (observer != null) {
5704                observer.startWatching();
5705            }
5706
5707            // First collect all of the stacks of the most important pids.
5708            if (firstPids != null) {
5709                int num = firstPids.size();
5710                for (int i = 0; i < num; i++) {
5711                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5712                            + firstPids.get(i));
5713                    final long timeTaken;
5714                    if (useTombstonedForJavaTraces) {
5715                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5716                    } else {
5717                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5718                    }
5719
5720                    remainingTime -= timeTaken;
5721                    if (remainingTime <= 0) {
5722                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5723                            "); deadline exceeded.");
5724                        return;
5725                    }
5726
5727                    if (DEBUG_ANR) {
5728                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5729                    }
5730                }
5731            }
5732
5733            // Next collect the stacks of the native pids
5734            if (nativePids != null) {
5735                for (int pid : nativePids) {
5736                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5737                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5738
5739                    final long start = SystemClock.elapsedRealtime();
5740                    Debug.dumpNativeBacktraceToFileTimeout(
5741                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5742                    final long timeTaken = SystemClock.elapsedRealtime() - start;
5743
5744                    remainingTime -= timeTaken;
5745                    if (remainingTime <= 0) {
5746                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5747                            "); deadline exceeded.");
5748                        return;
5749                    }
5750
5751                    if (DEBUG_ANR) {
5752                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5753                    }
5754                }
5755            }
5756
5757            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5758            if (extraPids != null) {
5759                for (int pid : extraPids) {
5760                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5761
5762                    final long timeTaken;
5763                    if (useTombstonedForJavaTraces) {
5764                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5765                    } else {
5766                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5767                    }
5768
5769                    remainingTime -= timeTaken;
5770                    if (remainingTime <= 0) {
5771                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5772                                "); deadline exceeded.");
5773                        return;
5774                    }
5775
5776                    if (DEBUG_ANR) {
5777                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5778                    }
5779                }
5780            }
5781        } finally {
5782            if (observer != null) {
5783                observer.stopWatching();
5784            }
5785        }
5786    }
5787
5788    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5789        if (true || Build.IS_USER) {
5790            return;
5791        }
5792        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5793        if (tracesPath == null || tracesPath.length() == 0) {
5794            return;
5795        }
5796
5797        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5798        StrictMode.allowThreadDiskWrites();
5799        try {
5800            final File tracesFile = new File(tracesPath);
5801            final File tracesDir = tracesFile.getParentFile();
5802            final File tracesTmp = new File(tracesDir, "__tmp__");
5803            try {
5804                if (tracesFile.exists()) {
5805                    tracesTmp.delete();
5806                    tracesFile.renameTo(tracesTmp);
5807                }
5808                StringBuilder sb = new StringBuilder();
5809                Time tobj = new Time();
5810                tobj.set(System.currentTimeMillis());
5811                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5812                sb.append(": ");
5813                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5814                sb.append(" since ");
5815                sb.append(msg);
5816                FileOutputStream fos = new FileOutputStream(tracesFile);
5817                fos.write(sb.toString().getBytes());
5818                if (app == null) {
5819                    fos.write("\n*** No application process!".getBytes());
5820                }
5821                fos.close();
5822                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5823            } catch (IOException e) {
5824                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5825                return;
5826            }
5827
5828            if (app != null) {
5829                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5830                firstPids.add(app.pid);
5831                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5832            }
5833
5834            File lastTracesFile = null;
5835            File curTracesFile = null;
5836            for (int i=9; i>=0; i--) {
5837                String name = String.format(Locale.US, "slow%02d.txt", i);
5838                curTracesFile = new File(tracesDir, name);
5839                if (curTracesFile.exists()) {
5840                    if (lastTracesFile != null) {
5841                        curTracesFile.renameTo(lastTracesFile);
5842                    } else {
5843                        curTracesFile.delete();
5844                    }
5845                }
5846                lastTracesFile = curTracesFile;
5847            }
5848            tracesFile.renameTo(curTracesFile);
5849            if (tracesTmp.exists()) {
5850                tracesTmp.renameTo(tracesFile);
5851            }
5852        } finally {
5853            StrictMode.setThreadPolicy(oldPolicy);
5854        }
5855    }
5856
5857    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5858        if (!mLaunchWarningShown) {
5859            mLaunchWarningShown = true;
5860            mUiHandler.post(new Runnable() {
5861                @Override
5862                public void run() {
5863                    synchronized (ActivityManagerService.this) {
5864                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5865                        d.show();
5866                        mUiHandler.postDelayed(new Runnable() {
5867                            @Override
5868                            public void run() {
5869                                synchronized (ActivityManagerService.this) {
5870                                    d.dismiss();
5871                                    mLaunchWarningShown = false;
5872                                }
5873                            }
5874                        }, 4000);
5875                    }
5876                }
5877            });
5878        }
5879    }
5880
5881    @Override
5882    public boolean clearApplicationUserData(final String packageName,
5883            final IPackageDataObserver observer, int userId) {
5884        enforceNotIsolatedCaller("clearApplicationUserData");
5885        int uid = Binder.getCallingUid();
5886        int pid = Binder.getCallingPid();
5887        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5888                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5889
5890        final ApplicationInfo appInfo;
5891        final boolean isInstantApp;
5892
5893        long callingId = Binder.clearCallingIdentity();
5894        try {
5895            IPackageManager pm = AppGlobals.getPackageManager();
5896            synchronized(this) {
5897                // Instant packages are not protected
5898                if (getPackageManagerInternalLocked().isPackageDataProtected(
5899                        resolvedUserId, packageName)) {
5900                    throw new SecurityException(
5901                            "Cannot clear data for a protected package: " + packageName);
5902                }
5903
5904                ApplicationInfo applicationInfo = null;
5905                try {
5906                    applicationInfo = pm.getApplicationInfo(packageName,
5907                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5908                } catch (RemoteException e) {
5909                    /* ignore */
5910                }
5911                appInfo = applicationInfo;
5912
5913                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5914
5915                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5916                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5917                    throw new SecurityException("PID " + pid + " does not have permission "
5918                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5919                            + " of package " + packageName);
5920                }
5921
5922                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5923                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
5924                final boolean isUninstalledAppWithoutInstantMetadata =
5925                        (appInfo == null && !hasInstantMetadata);
5926                isInstantApp = (appInfo != null && appInfo.isInstantApp())
5927                        || hasInstantMetadata;
5928                final boolean canAccessInstantApps = checkComponentPermission(
5929                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5930                        == PackageManager.PERMISSION_GRANTED;
5931
5932                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5933                        && !canAccessInstantApps)) {
5934                    Slog.w(TAG, "Invalid packageName: " + packageName);
5935                    if (observer != null) {
5936                        try {
5937                            observer.onRemoveCompleted(packageName, false);
5938                        } catch (RemoteException e) {
5939                            Slog.i(TAG, "Observer no longer exists.");
5940                        }
5941                    }
5942                    return false;
5943                }
5944
5945                if (appInfo != null) {
5946                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5947                    // Remove all tasks match the cleared application package and user
5948                    for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5949                        final TaskRecord tr = mRecentTasks.get(i);
5950                        final String taskPackageName =
5951                                tr.getBaseIntent().getComponent().getPackageName();
5952                        if (tr.userId != resolvedUserId) continue;
5953                        if (!taskPackageName.equals(packageName)) continue;
5954                        mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5955                                REMOVE_FROM_RECENTS);
5956                    }
5957                }
5958            }
5959
5960            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5961                @Override
5962                public void onRemoveCompleted(String packageName, boolean succeeded)
5963                        throws RemoteException {
5964                    if (appInfo != null) {
5965                        synchronized (ActivityManagerService.this) {
5966                            finishForceStopPackageLocked(packageName, appInfo.uid);
5967                        }
5968                    }
5969                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5970                            Uri.fromParts("package", packageName, null));
5971                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5972                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5973                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5974                    if (isInstantApp) {
5975                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5976                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5977                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
5978                                resolvedUserId);
5979                    } else {
5980                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5981                                null, null, null, null, false, false, resolvedUserId);
5982                    }
5983
5984                    if (observer != null) {
5985                        observer.onRemoveCompleted(packageName, succeeded);
5986                    }
5987                }
5988            };
5989
5990            try {
5991                // Clear application user data
5992                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
5993
5994                if (appInfo != null) {
5995                    synchronized (this) {
5996                        // Remove all permissions granted from/to this package
5997                        removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
5998                    }
5999
6000                    // Reset notification settings.
6001                    INotificationManager inm = NotificationManager.getService();
6002                    inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6003                }
6004            } catch (RemoteException e) {
6005            }
6006        } finally {
6007            Binder.restoreCallingIdentity(callingId);
6008        }
6009        return true;
6010    }
6011
6012    @Override
6013    public void killBackgroundProcesses(final String packageName, int userId) {
6014        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6015                != PackageManager.PERMISSION_GRANTED &&
6016                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6017                        != PackageManager.PERMISSION_GRANTED) {
6018            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6019                    + Binder.getCallingPid()
6020                    + ", uid=" + Binder.getCallingUid()
6021                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6022            Slog.w(TAG, msg);
6023            throw new SecurityException(msg);
6024        }
6025
6026        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6027                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6028        long callingId = Binder.clearCallingIdentity();
6029        try {
6030            IPackageManager pm = AppGlobals.getPackageManager();
6031            synchronized(this) {
6032                int appId = -1;
6033                try {
6034                    appId = UserHandle.getAppId(
6035                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6036                } catch (RemoteException e) {
6037                }
6038                if (appId == -1) {
6039                    Slog.w(TAG, "Invalid packageName: " + packageName);
6040                    return;
6041                }
6042                killPackageProcessesLocked(packageName, appId, userId,
6043                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6044            }
6045        } finally {
6046            Binder.restoreCallingIdentity(callingId);
6047        }
6048    }
6049
6050    @Override
6051    public void killAllBackgroundProcesses() {
6052        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6053                != PackageManager.PERMISSION_GRANTED) {
6054            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6055                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6056                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6057            Slog.w(TAG, msg);
6058            throw new SecurityException(msg);
6059        }
6060
6061        final long callingId = Binder.clearCallingIdentity();
6062        try {
6063            synchronized (this) {
6064                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6065                final int NP = mProcessNames.getMap().size();
6066                for (int ip = 0; ip < NP; ip++) {
6067                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6068                    final int NA = apps.size();
6069                    for (int ia = 0; ia < NA; ia++) {
6070                        final ProcessRecord app = apps.valueAt(ia);
6071                        if (app.persistent) {
6072                            // We don't kill persistent processes.
6073                            continue;
6074                        }
6075                        if (app.removed) {
6076                            procs.add(app);
6077                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6078                            app.removed = true;
6079                            procs.add(app);
6080                        }
6081                    }
6082                }
6083
6084                final int N = procs.size();
6085                for (int i = 0; i < N; i++) {
6086                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6087                }
6088
6089                mAllowLowerMemLevel = true;
6090
6091                updateOomAdjLocked();
6092                doLowMemReportIfNeededLocked(null);
6093            }
6094        } finally {
6095            Binder.restoreCallingIdentity(callingId);
6096        }
6097    }
6098
6099    /**
6100     * Kills all background processes, except those matching any of the
6101     * specified properties.
6102     *
6103     * @param minTargetSdk the target SDK version at or above which to preserve
6104     *                     processes, or {@code -1} to ignore the target SDK
6105     * @param maxProcState the process state at or below which to preserve
6106     *                     processes, or {@code -1} to ignore the process state
6107     */
6108    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6109        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6110                != PackageManager.PERMISSION_GRANTED) {
6111            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6112                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6113                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6114            Slog.w(TAG, msg);
6115            throw new SecurityException(msg);
6116        }
6117
6118        final long callingId = Binder.clearCallingIdentity();
6119        try {
6120            synchronized (this) {
6121                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6122                final int NP = mProcessNames.getMap().size();
6123                for (int ip = 0; ip < NP; ip++) {
6124                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6125                    final int NA = apps.size();
6126                    for (int ia = 0; ia < NA; ia++) {
6127                        final ProcessRecord app = apps.valueAt(ia);
6128                        if (app.removed) {
6129                            procs.add(app);
6130                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6131                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6132                            app.removed = true;
6133                            procs.add(app);
6134                        }
6135                    }
6136                }
6137
6138                final int N = procs.size();
6139                for (int i = 0; i < N; i++) {
6140                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6141                }
6142            }
6143        } finally {
6144            Binder.restoreCallingIdentity(callingId);
6145        }
6146    }
6147
6148    @Override
6149    public void forceStopPackage(final String packageName, int userId) {
6150        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6151                != PackageManager.PERMISSION_GRANTED) {
6152            String msg = "Permission Denial: forceStopPackage() from pid="
6153                    + Binder.getCallingPid()
6154                    + ", uid=" + Binder.getCallingUid()
6155                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6156            Slog.w(TAG, msg);
6157            throw new SecurityException(msg);
6158        }
6159        final int callingPid = Binder.getCallingPid();
6160        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6161                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6162        long callingId = Binder.clearCallingIdentity();
6163        try {
6164            IPackageManager pm = AppGlobals.getPackageManager();
6165            synchronized(this) {
6166                int[] users = userId == UserHandle.USER_ALL
6167                        ? mUserController.getUsers() : new int[] { userId };
6168                for (int user : users) {
6169                    int pkgUid = -1;
6170                    try {
6171                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6172                                user);
6173                    } catch (RemoteException e) {
6174                    }
6175                    if (pkgUid == -1) {
6176                        Slog.w(TAG, "Invalid packageName: " + packageName);
6177                        continue;
6178                    }
6179                    try {
6180                        pm.setPackageStoppedState(packageName, true, user);
6181                    } catch (RemoteException e) {
6182                    } catch (IllegalArgumentException e) {
6183                        Slog.w(TAG, "Failed trying to unstop package "
6184                                + packageName + ": " + e);
6185                    }
6186                    if (mUserController.isUserRunningLocked(user, 0)) {
6187                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6188                        finishForceStopPackageLocked(packageName, pkgUid);
6189                    }
6190                }
6191            }
6192        } finally {
6193            Binder.restoreCallingIdentity(callingId);
6194        }
6195    }
6196
6197    @Override
6198    public void addPackageDependency(String packageName) {
6199        synchronized (this) {
6200            int callingPid = Binder.getCallingPid();
6201            if (callingPid == myPid()) {
6202                //  Yeah, um, no.
6203                return;
6204            }
6205            ProcessRecord proc;
6206            synchronized (mPidsSelfLocked) {
6207                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6208            }
6209            if (proc != null) {
6210                if (proc.pkgDeps == null) {
6211                    proc.pkgDeps = new ArraySet<String>(1);
6212                }
6213                proc.pkgDeps.add(packageName);
6214            }
6215        }
6216    }
6217
6218    /*
6219     * The pkg name and app id have to be specified.
6220     */
6221    @Override
6222    public void killApplication(String pkg, int appId, int userId, String reason) {
6223        if (pkg == null) {
6224            return;
6225        }
6226        // Make sure the uid is valid.
6227        if (appId < 0) {
6228            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6229            return;
6230        }
6231        int callerUid = Binder.getCallingUid();
6232        // Only the system server can kill an application
6233        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6234            // Post an aysnc message to kill the application
6235            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6236            msg.arg1 = appId;
6237            msg.arg2 = userId;
6238            Bundle bundle = new Bundle();
6239            bundle.putString("pkg", pkg);
6240            bundle.putString("reason", reason);
6241            msg.obj = bundle;
6242            mHandler.sendMessage(msg);
6243        } else {
6244            throw new SecurityException(callerUid + " cannot kill pkg: " +
6245                    pkg);
6246        }
6247    }
6248
6249    @Override
6250    public void closeSystemDialogs(String reason) {
6251        enforceNotIsolatedCaller("closeSystemDialogs");
6252
6253        final int pid = Binder.getCallingPid();
6254        final int uid = Binder.getCallingUid();
6255        final long origId = Binder.clearCallingIdentity();
6256        try {
6257            synchronized (this) {
6258                // Only allow this from foreground processes, so that background
6259                // applications can't abuse it to prevent system UI from being shown.
6260                if (uid >= FIRST_APPLICATION_UID) {
6261                    ProcessRecord proc;
6262                    synchronized (mPidsSelfLocked) {
6263                        proc = mPidsSelfLocked.get(pid);
6264                    }
6265                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6266                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6267                                + " from background process " + proc);
6268                        return;
6269                    }
6270                }
6271                closeSystemDialogsLocked(reason);
6272            }
6273        } finally {
6274            Binder.restoreCallingIdentity(origId);
6275        }
6276    }
6277
6278    void closeSystemDialogsLocked(String reason) {
6279        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6280        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6281                | Intent.FLAG_RECEIVER_FOREGROUND);
6282        if (reason != null) {
6283            intent.putExtra("reason", reason);
6284        }
6285        mWindowManager.closeSystemDialogs(reason);
6286
6287        mStackSupervisor.closeSystemDialogsLocked();
6288
6289        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6290                AppOpsManager.OP_NONE, null, false, false,
6291                -1, SYSTEM_UID, UserHandle.USER_ALL);
6292    }
6293
6294    @Override
6295    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6296        enforceNotIsolatedCaller("getProcessMemoryInfo");
6297        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6298        for (int i=pids.length-1; i>=0; i--) {
6299            ProcessRecord proc;
6300            int oomAdj;
6301            synchronized (this) {
6302                synchronized (mPidsSelfLocked) {
6303                    proc = mPidsSelfLocked.get(pids[i]);
6304                    oomAdj = proc != null ? proc.setAdj : 0;
6305                }
6306            }
6307            infos[i] = new Debug.MemoryInfo();
6308            Debug.getMemoryInfo(pids[i], infos[i]);
6309            if (proc != null) {
6310                synchronized (this) {
6311                    if (proc.thread != null && proc.setAdj == oomAdj) {
6312                        // Record this for posterity if the process has been stable.
6313                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6314                                infos[i].getTotalUss(), false, proc.pkgList);
6315                    }
6316                }
6317            }
6318        }
6319        return infos;
6320    }
6321
6322    @Override
6323    public long[] getProcessPss(int[] pids) {
6324        enforceNotIsolatedCaller("getProcessPss");
6325        long[] pss = new long[pids.length];
6326        for (int i=pids.length-1; i>=0; i--) {
6327            ProcessRecord proc;
6328            int oomAdj;
6329            synchronized (this) {
6330                synchronized (mPidsSelfLocked) {
6331                    proc = mPidsSelfLocked.get(pids[i]);
6332                    oomAdj = proc != null ? proc.setAdj : 0;
6333                }
6334            }
6335            long[] tmpUss = new long[1];
6336            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6337            if (proc != null) {
6338                synchronized (this) {
6339                    if (proc.thread != null && proc.setAdj == oomAdj) {
6340                        // Record this for posterity if the process has been stable.
6341                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6342                    }
6343                }
6344            }
6345        }
6346        return pss;
6347    }
6348
6349    @Override
6350    public void killApplicationProcess(String processName, int uid) {
6351        if (processName == null) {
6352            return;
6353        }
6354
6355        int callerUid = Binder.getCallingUid();
6356        // Only the system server can kill an application
6357        if (callerUid == SYSTEM_UID) {
6358            synchronized (this) {
6359                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6360                if (app != null && app.thread != null) {
6361                    try {
6362                        app.thread.scheduleSuicide();
6363                    } catch (RemoteException e) {
6364                        // If the other end already died, then our work here is done.
6365                    }
6366                } else {
6367                    Slog.w(TAG, "Process/uid not found attempting kill of "
6368                            + processName + " / " + uid);
6369                }
6370            }
6371        } else {
6372            throw new SecurityException(callerUid + " cannot kill app process: " +
6373                    processName);
6374        }
6375    }
6376
6377    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6378        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6379                false, true, false, false, UserHandle.getUserId(uid), reason);
6380    }
6381
6382    private void finishForceStopPackageLocked(final String packageName, int uid) {
6383        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6384                Uri.fromParts("package", packageName, null));
6385        if (!mProcessesReady) {
6386            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6387                    | Intent.FLAG_RECEIVER_FOREGROUND);
6388        }
6389        intent.putExtra(Intent.EXTRA_UID, uid);
6390        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6391        broadcastIntentLocked(null, null, intent,
6392                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6393                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6394    }
6395
6396
6397    private final boolean killPackageProcessesLocked(String packageName, int appId,
6398            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6399            boolean doit, boolean evenPersistent, String reason) {
6400        ArrayList<ProcessRecord> procs = new ArrayList<>();
6401
6402        // Remove all processes this package may have touched: all with the
6403        // same UID (except for the system or root user), and all whose name
6404        // matches the package name.
6405        final int NP = mProcessNames.getMap().size();
6406        for (int ip=0; ip<NP; ip++) {
6407            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6408            final int NA = apps.size();
6409            for (int ia=0; ia<NA; ia++) {
6410                ProcessRecord app = apps.valueAt(ia);
6411                if (app.persistent && !evenPersistent) {
6412                    // we don't kill persistent processes
6413                    continue;
6414                }
6415                if (app.removed) {
6416                    if (doit) {
6417                        procs.add(app);
6418                    }
6419                    continue;
6420                }
6421
6422                // Skip process if it doesn't meet our oom adj requirement.
6423                if (app.setAdj < minOomAdj) {
6424                    continue;
6425                }
6426
6427                // If no package is specified, we call all processes under the
6428                // give user id.
6429                if (packageName == null) {
6430                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6431                        continue;
6432                    }
6433                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6434                        continue;
6435                    }
6436                // Package has been specified, we want to hit all processes
6437                // that match it.  We need to qualify this by the processes
6438                // that are running under the specified app and user ID.
6439                } else {
6440                    final boolean isDep = app.pkgDeps != null
6441                            && app.pkgDeps.contains(packageName);
6442                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6443                        continue;
6444                    }
6445                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6446                        continue;
6447                    }
6448                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6449                        continue;
6450                    }
6451                }
6452
6453                // Process has passed all conditions, kill it!
6454                if (!doit) {
6455                    return true;
6456                }
6457                app.removed = true;
6458                procs.add(app);
6459            }
6460        }
6461
6462        int N = procs.size();
6463        for (int i=0; i<N; i++) {
6464            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6465        }
6466        updateOomAdjLocked();
6467        return N > 0;
6468    }
6469
6470    private void cleanupDisabledPackageComponentsLocked(
6471            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6472
6473        Set<String> disabledClasses = null;
6474        boolean packageDisabled = false;
6475        IPackageManager pm = AppGlobals.getPackageManager();
6476
6477        if (changedClasses == null) {
6478            // Nothing changed...
6479            return;
6480        }
6481
6482        // Determine enable/disable state of the package and its components.
6483        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6484        for (int i = changedClasses.length - 1; i >= 0; i--) {
6485            final String changedClass = changedClasses[i];
6486
6487            if (changedClass.equals(packageName)) {
6488                try {
6489                    // Entire package setting changed
6490                    enabled = pm.getApplicationEnabledSetting(packageName,
6491                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6492                } catch (Exception e) {
6493                    // No such package/component; probably racing with uninstall.  In any
6494                    // event it means we have nothing further to do here.
6495                    return;
6496                }
6497                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6498                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6499                if (packageDisabled) {
6500                    // Entire package is disabled.
6501                    // No need to continue to check component states.
6502                    disabledClasses = null;
6503                    break;
6504                }
6505            } else {
6506                try {
6507                    enabled = pm.getComponentEnabledSetting(
6508                            new ComponentName(packageName, changedClass),
6509                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6510                } catch (Exception e) {
6511                    // As above, probably racing with uninstall.
6512                    return;
6513                }
6514                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6515                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6516                    if (disabledClasses == null) {
6517                        disabledClasses = new ArraySet<>(changedClasses.length);
6518                    }
6519                    disabledClasses.add(changedClass);
6520                }
6521            }
6522        }
6523
6524        if (!packageDisabled && disabledClasses == null) {
6525            // Nothing to do here...
6526            return;
6527        }
6528
6529        // Clean-up disabled activities.
6530        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6531                packageName, disabledClasses, true, false, userId) && mBooted) {
6532            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6533            mStackSupervisor.scheduleIdleLocked();
6534        }
6535
6536        // Clean-up disabled tasks
6537        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6538
6539        // Clean-up disabled services.
6540        mServices.bringDownDisabledPackageServicesLocked(
6541                packageName, disabledClasses, userId, false, killProcess, true);
6542
6543        // Clean-up disabled providers.
6544        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6545        mProviderMap.collectPackageProvidersLocked(
6546                packageName, disabledClasses, true, false, userId, providers);
6547        for (int i = providers.size() - 1; i >= 0; i--) {
6548            removeDyingProviderLocked(null, providers.get(i), true);
6549        }
6550
6551        // Clean-up disabled broadcast receivers.
6552        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6553            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6554                    packageName, disabledClasses, userId, true);
6555        }
6556
6557    }
6558
6559    final boolean clearBroadcastQueueForUserLocked(int userId) {
6560        boolean didSomething = false;
6561        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6562            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6563                    null, null, userId, true);
6564        }
6565        return didSomething;
6566    }
6567
6568    final boolean forceStopPackageLocked(String packageName, int appId,
6569            boolean callerWillRestart, boolean purgeCache, boolean doit,
6570            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6571        int i;
6572
6573        if (userId == UserHandle.USER_ALL && packageName == null) {
6574            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6575        }
6576
6577        if (appId < 0 && packageName != null) {
6578            try {
6579                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6580                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6581            } catch (RemoteException e) {
6582            }
6583        }
6584
6585        if (doit) {
6586            if (packageName != null) {
6587                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6588                        + " user=" + userId + ": " + reason);
6589            } else {
6590                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6591            }
6592
6593            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6594        }
6595
6596        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6597                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6598                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6599
6600        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6601
6602        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6603                packageName, null, doit, evenPersistent, userId)) {
6604            if (!doit) {
6605                return true;
6606            }
6607            didSomething = true;
6608        }
6609
6610        if (mServices.bringDownDisabledPackageServicesLocked(
6611                packageName, null, userId, evenPersistent, true, doit)) {
6612            if (!doit) {
6613                return true;
6614            }
6615            didSomething = true;
6616        }
6617
6618        if (packageName == null) {
6619            // Remove all sticky broadcasts from this user.
6620            mStickyBroadcasts.remove(userId);
6621        }
6622
6623        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6624        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6625                userId, providers)) {
6626            if (!doit) {
6627                return true;
6628            }
6629            didSomething = true;
6630        }
6631        for (i = providers.size() - 1; i >= 0; i--) {
6632            removeDyingProviderLocked(null, providers.get(i), true);
6633        }
6634
6635        // Remove transient permissions granted from/to this package/user
6636        removeUriPermissionsForPackageLocked(packageName, userId, false);
6637
6638        if (doit) {
6639            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6640                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6641                        packageName, null, userId, doit);
6642            }
6643        }
6644
6645        if (packageName == null || uninstalling) {
6646            // Remove pending intents.  For now we only do this when force
6647            // stopping users, because we have some problems when doing this
6648            // for packages -- app widgets are not currently cleaned up for
6649            // such packages, so they can be left with bad pending intents.
6650            if (mIntentSenderRecords.size() > 0) {
6651                Iterator<WeakReference<PendingIntentRecord>> it
6652                        = mIntentSenderRecords.values().iterator();
6653                while (it.hasNext()) {
6654                    WeakReference<PendingIntentRecord> wpir = it.next();
6655                    if (wpir == null) {
6656                        it.remove();
6657                        continue;
6658                    }
6659                    PendingIntentRecord pir = wpir.get();
6660                    if (pir == null) {
6661                        it.remove();
6662                        continue;
6663                    }
6664                    if (packageName == null) {
6665                        // Stopping user, remove all objects for the user.
6666                        if (pir.key.userId != userId) {
6667                            // Not the same user, skip it.
6668                            continue;
6669                        }
6670                    } else {
6671                        if (UserHandle.getAppId(pir.uid) != appId) {
6672                            // Different app id, skip it.
6673                            continue;
6674                        }
6675                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6676                            // Different user, skip it.
6677                            continue;
6678                        }
6679                        if (!pir.key.packageName.equals(packageName)) {
6680                            // Different package, skip it.
6681                            continue;
6682                        }
6683                    }
6684                    if (!doit) {
6685                        return true;
6686                    }
6687                    didSomething = true;
6688                    it.remove();
6689                    makeIntentSenderCanceledLocked(pir);
6690                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6691                        pir.key.activity.pendingResults.remove(pir.ref);
6692                    }
6693                }
6694            }
6695        }
6696
6697        if (doit) {
6698            if (purgeCache && packageName != null) {
6699                AttributeCache ac = AttributeCache.instance();
6700                if (ac != null) {
6701                    ac.removePackage(packageName);
6702                }
6703            }
6704            if (mBooted) {
6705                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6706                mStackSupervisor.scheduleIdleLocked();
6707            }
6708        }
6709
6710        return didSomething;
6711    }
6712
6713    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6714        return removeProcessNameLocked(name, uid, null);
6715    }
6716
6717    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6718            final ProcessRecord expecting) {
6719        ProcessRecord old = mProcessNames.get(name, uid);
6720        // Only actually remove when the currently recorded value matches the
6721        // record that we expected; if it doesn't match then we raced with a
6722        // newly created process and we don't want to destroy the new one.
6723        if ((expecting == null) || (old == expecting)) {
6724            mProcessNames.remove(name, uid);
6725        }
6726        if (old != null && old.uidRecord != null) {
6727            old.uidRecord.numProcs--;
6728            if (old.uidRecord.numProcs == 0) {
6729                // No more processes using this uid, tell clients it is gone.
6730                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6731                        "No more processes in " + old.uidRecord);
6732                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6733                EventLogTags.writeAmUidStopped(uid);
6734                mActiveUids.remove(uid);
6735                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6736            }
6737            old.uidRecord = null;
6738        }
6739        mIsolatedProcesses.remove(uid);
6740        return old;
6741    }
6742
6743    private final void addProcessNameLocked(ProcessRecord proc) {
6744        // We shouldn't already have a process under this name, but just in case we
6745        // need to clean up whatever may be there now.
6746        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6747        if (old == proc && proc.persistent) {
6748            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6749            Slog.w(TAG, "Re-adding persistent process " + proc);
6750        } else if (old != null) {
6751            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6752        }
6753        UidRecord uidRec = mActiveUids.get(proc.uid);
6754        if (uidRec == null) {
6755            uidRec = new UidRecord(proc.uid);
6756            // This is the first appearance of the uid, report it now!
6757            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6758                    "Creating new process uid: " + uidRec);
6759            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6760                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6761                uidRec.setWhitelist = uidRec.curWhitelist = true;
6762            }
6763            uidRec.updateHasInternetPermission();
6764            mActiveUids.put(proc.uid, uidRec);
6765            EventLogTags.writeAmUidRunning(uidRec.uid);
6766            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6767        }
6768        proc.uidRecord = uidRec;
6769
6770        // Reset render thread tid if it was already set, so new process can set it again.
6771        proc.renderThreadTid = 0;
6772        uidRec.numProcs++;
6773        mProcessNames.put(proc.processName, proc.uid, proc);
6774        if (proc.isolated) {
6775            mIsolatedProcesses.put(proc.uid, proc);
6776        }
6777    }
6778
6779    boolean removeProcessLocked(ProcessRecord app,
6780            boolean callerWillRestart, boolean allowRestart, String reason) {
6781        final String name = app.processName;
6782        final int uid = app.uid;
6783        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6784            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6785
6786        ProcessRecord old = mProcessNames.get(name, uid);
6787        if (old != app) {
6788            // This process is no longer active, so nothing to do.
6789            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6790            return false;
6791        }
6792        removeProcessNameLocked(name, uid);
6793        if (mHeavyWeightProcess == app) {
6794            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6795                    mHeavyWeightProcess.userId, 0));
6796            mHeavyWeightProcess = null;
6797        }
6798        boolean needRestart = false;
6799        if (app.pid > 0 && app.pid != MY_PID) {
6800            int pid = app.pid;
6801            synchronized (mPidsSelfLocked) {
6802                mPidsSelfLocked.remove(pid);
6803                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6804            }
6805            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6806            boolean willRestart = false;
6807            if (app.persistent && !app.isolated) {
6808                if (!callerWillRestart) {
6809                    willRestart = true;
6810                } else {
6811                    needRestart = true;
6812                }
6813            }
6814            app.kill(reason, true);
6815            if (app.isolated) {
6816                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6817                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6818            }
6819            handleAppDiedLocked(app, willRestart, allowRestart);
6820            if (willRestart) {
6821                removeLruProcessLocked(app);
6822                addAppLocked(app.info, null, false, null /* ABI override */);
6823            }
6824        } else {
6825            mRemovedProcesses.add(app);
6826        }
6827
6828        return needRestart;
6829    }
6830
6831    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6832        cleanupAppInLaunchingProvidersLocked(app, true);
6833        removeProcessLocked(app, false, true, "timeout publishing content providers");
6834    }
6835
6836    private final void processStartTimedOutLocked(ProcessRecord app) {
6837        final int pid = app.pid;
6838        boolean gone = false;
6839        synchronized (mPidsSelfLocked) {
6840            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6841            if (knownApp != null && knownApp.thread == null) {
6842                mPidsSelfLocked.remove(pid);
6843                gone = true;
6844            }
6845        }
6846
6847        if (gone) {
6848            Slog.w(TAG, "Process " + app + " failed to attach");
6849            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6850                    pid, app.uid, app.processName);
6851            removeProcessNameLocked(app.processName, app.uid);
6852            if (mHeavyWeightProcess == app) {
6853                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6854                        mHeavyWeightProcess.userId, 0));
6855                mHeavyWeightProcess = null;
6856            }
6857            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6858            // Take care of any launching providers waiting for this process.
6859            cleanupAppInLaunchingProvidersLocked(app, true);
6860            // Take care of any services that are waiting for the process.
6861            mServices.processStartTimedOutLocked(app);
6862            app.kill("start timeout", true);
6863            if (app.isolated) {
6864                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6865            }
6866            removeLruProcessLocked(app);
6867            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6868                Slog.w(TAG, "Unattached app died before backup, skipping");
6869                mHandler.post(new Runnable() {
6870                @Override
6871                    public void run(){
6872                        try {
6873                            IBackupManager bm = IBackupManager.Stub.asInterface(
6874                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6875                            bm.agentDisconnected(app.info.packageName);
6876                        } catch (RemoteException e) {
6877                            // Can't happen; the backup manager is local
6878                        }
6879                    }
6880                });
6881            }
6882            if (isPendingBroadcastProcessLocked(pid)) {
6883                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6884                skipPendingBroadcastLocked(pid);
6885            }
6886        } else {
6887            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6888        }
6889    }
6890
6891    private final boolean attachApplicationLocked(IApplicationThread thread,
6892            int pid) {
6893
6894        // Find the application record that is being attached...  either via
6895        // the pid if we are running in multiple processes, or just pull the
6896        // next app record if we are emulating process with anonymous threads.
6897        ProcessRecord app;
6898        long startTime = SystemClock.uptimeMillis();
6899        if (pid != MY_PID && pid >= 0) {
6900            synchronized (mPidsSelfLocked) {
6901                app = mPidsSelfLocked.get(pid);
6902            }
6903        } else {
6904            app = null;
6905        }
6906
6907        if (app == null) {
6908            Slog.w(TAG, "No pending application record for pid " + pid
6909                    + " (IApplicationThread " + thread + "); dropping process");
6910            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6911            if (pid > 0 && pid != MY_PID) {
6912                killProcessQuiet(pid);
6913                //TODO: killProcessGroup(app.info.uid, pid);
6914            } else {
6915                try {
6916                    thread.scheduleExit();
6917                } catch (Exception e) {
6918                    // Ignore exceptions.
6919                }
6920            }
6921            return false;
6922        }
6923
6924        // If this application record is still attached to a previous
6925        // process, clean it up now.
6926        if (app.thread != null) {
6927            handleAppDiedLocked(app, true, true);
6928        }
6929
6930        // Tell the process all about itself.
6931
6932        if (DEBUG_ALL) Slog.v(
6933                TAG, "Binding process pid " + pid + " to record " + app);
6934
6935        final String processName = app.processName;
6936        try {
6937            AppDeathRecipient adr = new AppDeathRecipient(
6938                    app, pid, thread);
6939            thread.asBinder().linkToDeath(adr, 0);
6940            app.deathRecipient = adr;
6941        } catch (RemoteException e) {
6942            app.resetPackageList(mProcessStats);
6943            startProcessLocked(app, "link fail", processName);
6944            return false;
6945        }
6946
6947        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6948
6949        app.makeActive(thread, mProcessStats);
6950        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6951        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6952        app.forcingToImportant = null;
6953        updateProcessForegroundLocked(app, false, false);
6954        app.hasShownUi = false;
6955        app.debugging = false;
6956        app.cached = false;
6957        app.killedByAm = false;
6958        app.killed = false;
6959
6960
6961        // We carefully use the same state that PackageManager uses for
6962        // filtering, since we use this flag to decide if we need to install
6963        // providers when user is unlocked later
6964        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6965
6966        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6967
6968        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6969        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6970
6971        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6972            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6973            msg.obj = app;
6974            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6975        }
6976
6977        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6978
6979        if (!normalMode) {
6980            Slog.i(TAG, "Launching preboot mode app: " + app);
6981        }
6982
6983        if (DEBUG_ALL) Slog.v(
6984            TAG, "New app record " + app
6985            + " thread=" + thread.asBinder() + " pid=" + pid);
6986        try {
6987            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6988            if (mDebugApp != null && mDebugApp.equals(processName)) {
6989                testMode = mWaitForDebugger
6990                    ? ApplicationThreadConstants.DEBUG_WAIT
6991                    : ApplicationThreadConstants.DEBUG_ON;
6992                app.debugging = true;
6993                if (mDebugTransient) {
6994                    mDebugApp = mOrigDebugApp;
6995                    mWaitForDebugger = mOrigWaitForDebugger;
6996                }
6997            }
6998
6999            ProfilerInfo profilerInfo = null;
7000            String agent = null;
7001            if (mProfileApp != null && mProfileApp.equals(processName)) {
7002                mProfileProc = app;
7003                profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ?
7004                        new ProfilerInfo(mProfilerInfo) : null;
7005                agent = mProfilerInfo != null ? mProfilerInfo.agent : null;
7006            } else if (app.instr != null && app.instr.mProfileFile != null) {
7007                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7008                        null);
7009            }
7010
7011            boolean enableTrackAllocation = false;
7012            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7013                enableTrackAllocation = true;
7014                mTrackAllocationApp = null;
7015            }
7016
7017            // If the app is being launched for restore or full backup, set it up specially
7018            boolean isRestrictedBackupMode = false;
7019            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7020                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7021                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7022                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7023                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7024            }
7025
7026            if (app.instr != null) {
7027                notifyPackageUse(app.instr.mClass.getPackageName(),
7028                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7029            }
7030            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7031                    + processName + " with config " + getGlobalConfiguration());
7032            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7033            app.compat = compatibilityInfoForPackageLocked(appInfo);
7034
7035            if (profilerInfo != null && profilerInfo.profileFd != null) {
7036                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7037            }
7038
7039            // We deprecated Build.SERIAL and it is not accessible to
7040            // apps that target the v2 security sandbox. Since access to
7041            // the serial is now behind a permission we push down the value.
7042            String buildSerial = appInfo.targetSandboxVersion < 2
7043                    ? sTheRealBuildSerial : Build.UNKNOWN;
7044
7045            // Check if this is a secondary process that should be incorporated into some
7046            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7047            // stuff above because profiling can currently happen only in the primary
7048            // instrumentation process.)
7049            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7050                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7051                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7052                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7053                        if (aInstr.mTargetProcesses.length == 0) {
7054                            // This is the wildcard mode, where every process brought up for
7055                            // the target instrumentation should be included.
7056                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7057                                app.instr = aInstr;
7058                                aInstr.mRunningProcesses.add(app);
7059                            }
7060                        } else {
7061                            for (String proc : aInstr.mTargetProcesses) {
7062                                if (proc.equals(app.processName)) {
7063                                    app.instr = aInstr;
7064                                    aInstr.mRunningProcesses.add(app);
7065                                    break;
7066                                }
7067                            }
7068                        }
7069                    }
7070                }
7071            }
7072
7073            // If we were asked to attach an agent on startup, do so now, before we're binding
7074            // application code.
7075            if (agent != null) {
7076                thread.attachAgent(agent);
7077            }
7078
7079            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7080            mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7081            if (app.isolatedEntryPoint != null) {
7082                // This is an isolated process which should just call an entry point instead of
7083                // being bound to an application.
7084                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7085            } else if (app.instr != null) {
7086                thread.bindApplication(processName, appInfo, providers,
7087                        app.instr.mClass,
7088                        profilerInfo, app.instr.mArguments,
7089                        app.instr.mWatcher,
7090                        app.instr.mUiAutomationConnection, testMode,
7091                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7092                        isRestrictedBackupMode || !normalMode, app.persistent,
7093                        new Configuration(getGlobalConfiguration()), app.compat,
7094                        getCommonServicesLocked(app.isolated),
7095                        mCoreSettingsObserver.getCoreSettingsLocked(),
7096                        buildSerial);
7097            } else {
7098                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7099                        null, null, null, testMode,
7100                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7101                        isRestrictedBackupMode || !normalMode, app.persistent,
7102                        new Configuration(getGlobalConfiguration()), app.compat,
7103                        getCommonServicesLocked(app.isolated),
7104                        mCoreSettingsObserver.getCoreSettingsLocked(),
7105                        buildSerial);
7106            }
7107
7108            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7109            updateLruProcessLocked(app, false, null);
7110            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7111            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7112        } catch (Exception e) {
7113            // todo: Yikes!  What should we do?  For now we will try to
7114            // start another process, but that could easily get us in
7115            // an infinite loop of restarting processes...
7116            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7117
7118            app.resetPackageList(mProcessStats);
7119            app.unlinkDeathRecipient();
7120            startProcessLocked(app, "bind fail", processName);
7121            return false;
7122        }
7123
7124        // Remove this record from the list of starting applications.
7125        mPersistentStartingProcesses.remove(app);
7126        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7127                "Attach application locked removing on hold: " + app);
7128        mProcessesOnHold.remove(app);
7129
7130        boolean badApp = false;
7131        boolean didSomething = false;
7132
7133        // See if the top visible activity is waiting to run in this process...
7134        if (normalMode) {
7135            try {
7136                if (mStackSupervisor.attachApplicationLocked(app)) {
7137                    didSomething = true;
7138                }
7139            } catch (Exception e) {
7140                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7141                badApp = true;
7142            }
7143        }
7144
7145        // Find any services that should be running in this process...
7146        if (!badApp) {
7147            try {
7148                didSomething |= mServices.attachApplicationLocked(app, processName);
7149                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7150            } catch (Exception e) {
7151                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7152                badApp = true;
7153            }
7154        }
7155
7156        // Check if a next-broadcast receiver is in this process...
7157        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7158            try {
7159                didSomething |= sendPendingBroadcastsLocked(app);
7160                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7161            } catch (Exception e) {
7162                // If the app died trying to launch the receiver we declare it 'bad'
7163                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7164                badApp = true;
7165            }
7166        }
7167
7168        // Check whether the next backup agent is in this process...
7169        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7170            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7171                    "New app is backup target, launching agent for " + app);
7172            notifyPackageUse(mBackupTarget.appInfo.packageName,
7173                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7174            try {
7175                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7176                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7177                        mBackupTarget.backupMode);
7178            } catch (Exception e) {
7179                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7180                badApp = true;
7181            }
7182        }
7183
7184        if (badApp) {
7185            app.kill("error during init", true);
7186            handleAppDiedLocked(app, false, true);
7187            return false;
7188        }
7189
7190        if (!didSomething) {
7191            updateOomAdjLocked();
7192            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7193        }
7194
7195        return true;
7196    }
7197
7198    @Override
7199    public final void attachApplication(IApplicationThread thread) {
7200        synchronized (this) {
7201            int callingPid = Binder.getCallingPid();
7202            final long origId = Binder.clearCallingIdentity();
7203            attachApplicationLocked(thread, callingPid);
7204            Binder.restoreCallingIdentity(origId);
7205        }
7206    }
7207
7208    @Override
7209    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7210        final long origId = Binder.clearCallingIdentity();
7211        synchronized (this) {
7212            ActivityStack stack = ActivityRecord.getStackLocked(token);
7213            if (stack != null) {
7214                ActivityRecord r =
7215                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7216                                false /* processPausingActivities */, config);
7217                if (stopProfiling) {
7218                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7219                        clearProfilerLocked();
7220                    }
7221                }
7222            }
7223        }
7224        Binder.restoreCallingIdentity(origId);
7225    }
7226
7227    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7228        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7229                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7230    }
7231
7232    void enableScreenAfterBoot() {
7233        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7234                SystemClock.uptimeMillis());
7235        mWindowManager.enableScreenAfterBoot();
7236
7237        synchronized (this) {
7238            updateEventDispatchingLocked();
7239        }
7240    }
7241
7242    @Override
7243    public void showBootMessage(final CharSequence msg, final boolean always) {
7244        if (Binder.getCallingUid() != myUid()) {
7245            throw new SecurityException();
7246        }
7247        mWindowManager.showBootMessage(msg, always);
7248    }
7249
7250    @Override
7251    public void keyguardGoingAway(int flags) {
7252        enforceNotIsolatedCaller("keyguardGoingAway");
7253        final long token = Binder.clearCallingIdentity();
7254        try {
7255            synchronized (this) {
7256                mKeyguardController.keyguardGoingAway(flags);
7257            }
7258        } finally {
7259            Binder.restoreCallingIdentity(token);
7260        }
7261    }
7262
7263    /**
7264     * @return whther the keyguard is currently locked.
7265     */
7266    boolean isKeyguardLocked() {
7267        return mKeyguardController.isKeyguardLocked();
7268    }
7269
7270    final void finishBooting() {
7271        synchronized (this) {
7272            if (!mBootAnimationComplete) {
7273                mCallFinishBooting = true;
7274                return;
7275            }
7276            mCallFinishBooting = false;
7277        }
7278
7279        ArraySet<String> completedIsas = new ArraySet<String>();
7280        for (String abi : Build.SUPPORTED_ABIS) {
7281            zygoteProcess.establishZygoteConnectionForAbi(abi);
7282            final String instructionSet = VMRuntime.getInstructionSet(abi);
7283            if (!completedIsas.contains(instructionSet)) {
7284                try {
7285                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7286                } catch (InstallerException e) {
7287                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7288                            e.getMessage() +")");
7289                }
7290                completedIsas.add(instructionSet);
7291            }
7292        }
7293
7294        IntentFilter pkgFilter = new IntentFilter();
7295        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7296        pkgFilter.addDataScheme("package");
7297        mContext.registerReceiver(new BroadcastReceiver() {
7298            @Override
7299            public void onReceive(Context context, Intent intent) {
7300                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7301                if (pkgs != null) {
7302                    for (String pkg : pkgs) {
7303                        synchronized (ActivityManagerService.this) {
7304                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7305                                    0, "query restart")) {
7306                                setResultCode(Activity.RESULT_OK);
7307                                return;
7308                            }
7309                        }
7310                    }
7311                }
7312            }
7313        }, pkgFilter);
7314
7315        IntentFilter dumpheapFilter = new IntentFilter();
7316        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7317        mContext.registerReceiver(new BroadcastReceiver() {
7318            @Override
7319            public void onReceive(Context context, Intent intent) {
7320                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7321                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7322                } else {
7323                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7324                }
7325            }
7326        }, dumpheapFilter);
7327
7328        // Let system services know.
7329        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7330
7331        synchronized (this) {
7332            // Ensure that any processes we had put on hold are now started
7333            // up.
7334            final int NP = mProcessesOnHold.size();
7335            if (NP > 0) {
7336                ArrayList<ProcessRecord> procs =
7337                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7338                for (int ip=0; ip<NP; ip++) {
7339                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7340                            + procs.get(ip));
7341                    startProcessLocked(procs.get(ip), "on-hold", null);
7342                }
7343            }
7344
7345            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7346                // Start looking for apps that are abusing wake locks.
7347                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7348                mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7349                // Tell anyone interested that we are done booting!
7350                SystemProperties.set("sys.boot_completed", "1");
7351
7352                // And trigger dev.bootcomplete if we are not showing encryption progress
7353                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7354                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7355                    SystemProperties.set("dev.bootcomplete", "1");
7356                }
7357                mUserController.sendBootCompletedLocked(
7358                        new IIntentReceiver.Stub() {
7359                            @Override
7360                            public void performReceive(Intent intent, int resultCode,
7361                                    String data, Bundle extras, boolean ordered,
7362                                    boolean sticky, int sendingUser) {
7363                                synchronized (ActivityManagerService.this) {
7364                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7365                                            true, false);
7366                                }
7367                            }
7368                        });
7369                scheduleStartProfilesLocked();
7370            }
7371        }
7372    }
7373
7374    @Override
7375    public void bootAnimationComplete() {
7376        final boolean callFinishBooting;
7377        synchronized (this) {
7378            callFinishBooting = mCallFinishBooting;
7379            mBootAnimationComplete = true;
7380        }
7381        if (callFinishBooting) {
7382            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7383            finishBooting();
7384            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7385        }
7386    }
7387
7388    final void ensureBootCompleted() {
7389        boolean booting;
7390        boolean enableScreen;
7391        synchronized (this) {
7392            booting = mBooting;
7393            mBooting = false;
7394            enableScreen = !mBooted;
7395            mBooted = true;
7396        }
7397
7398        if (booting) {
7399            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7400            finishBooting();
7401            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7402        }
7403
7404        if (enableScreen) {
7405            enableScreenAfterBoot();
7406        }
7407    }
7408
7409    @Override
7410    public final void activityResumed(IBinder token) {
7411        final long origId = Binder.clearCallingIdentity();
7412        synchronized(this) {
7413            ActivityRecord.activityResumedLocked(token);
7414            mWindowManager.notifyAppResumedFinished(token);
7415        }
7416        Binder.restoreCallingIdentity(origId);
7417    }
7418
7419    @Override
7420    public final void activityPaused(IBinder token) {
7421        final long origId = Binder.clearCallingIdentity();
7422        synchronized(this) {
7423            ActivityStack stack = ActivityRecord.getStackLocked(token);
7424            if (stack != null) {
7425                stack.activityPausedLocked(token, false);
7426            }
7427        }
7428        Binder.restoreCallingIdentity(origId);
7429    }
7430
7431    @Override
7432    public final void activityStopped(IBinder token, Bundle icicle,
7433            PersistableBundle persistentState, CharSequence description) {
7434        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7435
7436        // Refuse possible leaked file descriptors
7437        if (icicle != null && icicle.hasFileDescriptors()) {
7438            throw new IllegalArgumentException("File descriptors passed in Bundle");
7439        }
7440
7441        final long origId = Binder.clearCallingIdentity();
7442
7443        synchronized (this) {
7444            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7445            if (r != null) {
7446                r.activityStoppedLocked(icicle, persistentState, description);
7447            }
7448        }
7449
7450        trimApplications();
7451
7452        Binder.restoreCallingIdentity(origId);
7453    }
7454
7455    @Override
7456    public final void activityDestroyed(IBinder token) {
7457        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7458        synchronized (this) {
7459            ActivityStack stack = ActivityRecord.getStackLocked(token);
7460            if (stack != null) {
7461                stack.activityDestroyedLocked(token, "activityDestroyed");
7462            }
7463        }
7464    }
7465
7466    @Override
7467    public final void activityRelaunched(IBinder token) {
7468        final long origId = Binder.clearCallingIdentity();
7469        synchronized (this) {
7470            mStackSupervisor.activityRelaunchedLocked(token);
7471        }
7472        Binder.restoreCallingIdentity(origId);
7473    }
7474
7475    @Override
7476    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7477            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7478        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7479                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7480        synchronized (this) {
7481            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7482            if (record == null) {
7483                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7484                        + "found for: " + token);
7485            }
7486            record.setSizeConfigurations(horizontalSizeConfiguration,
7487                    verticalSizeConfigurations, smallestSizeConfigurations);
7488        }
7489    }
7490
7491    @Override
7492    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7493        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7494    }
7495
7496    @Override
7497    public final void notifyEnterAnimationComplete(IBinder token) {
7498        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7499    }
7500
7501    @Override
7502    public String getCallingPackage(IBinder token) {
7503        synchronized (this) {
7504            ActivityRecord r = getCallingRecordLocked(token);
7505            return r != null ? r.info.packageName : null;
7506        }
7507    }
7508
7509    @Override
7510    public ComponentName getCallingActivity(IBinder token) {
7511        synchronized (this) {
7512            ActivityRecord r = getCallingRecordLocked(token);
7513            return r != null ? r.intent.getComponent() : null;
7514        }
7515    }
7516
7517    private ActivityRecord getCallingRecordLocked(IBinder token) {
7518        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7519        if (r == null) {
7520            return null;
7521        }
7522        return r.resultTo;
7523    }
7524
7525    @Override
7526    public ComponentName getActivityClassForToken(IBinder token) {
7527        synchronized(this) {
7528            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7529            if (r == null) {
7530                return null;
7531            }
7532            return r.intent.getComponent();
7533        }
7534    }
7535
7536    @Override
7537    public String getPackageForToken(IBinder token) {
7538        synchronized(this) {
7539            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7540            if (r == null) {
7541                return null;
7542            }
7543            return r.packageName;
7544        }
7545    }
7546
7547    @Override
7548    public boolean isRootVoiceInteraction(IBinder token) {
7549        synchronized(this) {
7550            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7551            if (r == null) {
7552                return false;
7553            }
7554            return r.rootVoiceInteraction;
7555        }
7556    }
7557
7558    @Override
7559    public IIntentSender getIntentSender(int type,
7560            String packageName, IBinder token, String resultWho,
7561            int requestCode, Intent[] intents, String[] resolvedTypes,
7562            int flags, Bundle bOptions, int userId) {
7563        enforceNotIsolatedCaller("getIntentSender");
7564        // Refuse possible leaked file descriptors
7565        if (intents != null) {
7566            if (intents.length < 1) {
7567                throw new IllegalArgumentException("Intents array length must be >= 1");
7568            }
7569            for (int i=0; i<intents.length; i++) {
7570                Intent intent = intents[i];
7571                if (intent != null) {
7572                    if (intent.hasFileDescriptors()) {
7573                        throw new IllegalArgumentException("File descriptors passed in Intent");
7574                    }
7575                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7576                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7577                        throw new IllegalArgumentException(
7578                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7579                    }
7580                    intents[i] = new Intent(intent);
7581                }
7582            }
7583            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7584                throw new IllegalArgumentException(
7585                        "Intent array length does not match resolvedTypes length");
7586            }
7587        }
7588        if (bOptions != null) {
7589            if (bOptions.hasFileDescriptors()) {
7590                throw new IllegalArgumentException("File descriptors passed in options");
7591            }
7592        }
7593
7594        synchronized(this) {
7595            int callingUid = Binder.getCallingUid();
7596            int origUserId = userId;
7597            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7598                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7599                    ALLOW_NON_FULL, "getIntentSender", null);
7600            if (origUserId == UserHandle.USER_CURRENT) {
7601                // We don't want to evaluate this until the pending intent is
7602                // actually executed.  However, we do want to always do the
7603                // security checking for it above.
7604                userId = UserHandle.USER_CURRENT;
7605            }
7606            try {
7607                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7608                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7609                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7610                    if (!UserHandle.isSameApp(callingUid, uid)) {
7611                        String msg = "Permission Denial: getIntentSender() from pid="
7612                            + Binder.getCallingPid()
7613                            + ", uid=" + Binder.getCallingUid()
7614                            + ", (need uid=" + uid + ")"
7615                            + " is not allowed to send as package " + packageName;
7616                        Slog.w(TAG, msg);
7617                        throw new SecurityException(msg);
7618                    }
7619                }
7620
7621                return getIntentSenderLocked(type, packageName, callingUid, userId,
7622                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7623
7624            } catch (RemoteException e) {
7625                throw new SecurityException(e);
7626            }
7627        }
7628    }
7629
7630    IIntentSender getIntentSenderLocked(int type, String packageName,
7631            int callingUid, int userId, IBinder token, String resultWho,
7632            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7633            Bundle bOptions) {
7634        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7635        ActivityRecord activity = null;
7636        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7637            activity = ActivityRecord.isInStackLocked(token);
7638            if (activity == null) {
7639                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7640                return null;
7641            }
7642            if (activity.finishing) {
7643                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7644                return null;
7645            }
7646        }
7647
7648        // We're going to be splicing together extras before sending, so we're
7649        // okay poking into any contained extras.
7650        if (intents != null) {
7651            for (int i = 0; i < intents.length; i++) {
7652                intents[i].setDefusable(true);
7653            }
7654        }
7655        Bundle.setDefusable(bOptions, true);
7656
7657        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7658        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7659        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7660        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7661                |PendingIntent.FLAG_UPDATE_CURRENT);
7662
7663        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7664                type, packageName, activity, resultWho,
7665                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7666        WeakReference<PendingIntentRecord> ref;
7667        ref = mIntentSenderRecords.get(key);
7668        PendingIntentRecord rec = ref != null ? ref.get() : null;
7669        if (rec != null) {
7670            if (!cancelCurrent) {
7671                if (updateCurrent) {
7672                    if (rec.key.requestIntent != null) {
7673                        rec.key.requestIntent.replaceExtras(intents != null ?
7674                                intents[intents.length - 1] : null);
7675                    }
7676                    if (intents != null) {
7677                        intents[intents.length-1] = rec.key.requestIntent;
7678                        rec.key.allIntents = intents;
7679                        rec.key.allResolvedTypes = resolvedTypes;
7680                    } else {
7681                        rec.key.allIntents = null;
7682                        rec.key.allResolvedTypes = null;
7683                    }
7684                }
7685                return rec;
7686            }
7687            makeIntentSenderCanceledLocked(rec);
7688            mIntentSenderRecords.remove(key);
7689        }
7690        if (noCreate) {
7691            return rec;
7692        }
7693        rec = new PendingIntentRecord(this, key, callingUid);
7694        mIntentSenderRecords.put(key, rec.ref);
7695        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7696            if (activity.pendingResults == null) {
7697                activity.pendingResults
7698                        = new HashSet<WeakReference<PendingIntentRecord>>();
7699            }
7700            activity.pendingResults.add(rec.ref);
7701        }
7702        return rec;
7703    }
7704
7705    @Override
7706    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7707            Intent intent, String resolvedType,
7708            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7709        if (target instanceof PendingIntentRecord) {
7710            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7711                    whitelistToken, finishedReceiver, requiredPermission, options);
7712        } else {
7713            if (intent == null) {
7714                // Weird case: someone has given us their own custom IIntentSender, and now
7715                // they have someone else trying to send to it but of course this isn't
7716                // really a PendingIntent, so there is no base Intent, and the caller isn't
7717                // supplying an Intent... but we never want to dispatch a null Intent to
7718                // a receiver, so um...  let's make something up.
7719                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7720                intent = new Intent(Intent.ACTION_MAIN);
7721            }
7722            try {
7723                target.send(code, intent, resolvedType, whitelistToken, null,
7724                        requiredPermission, options);
7725            } catch (RemoteException e) {
7726            }
7727            // Platform code can rely on getting a result back when the send is done, but if
7728            // this intent sender is from outside of the system we can't rely on it doing that.
7729            // So instead we don't give it the result receiver, and instead just directly
7730            // report the finish immediately.
7731            if (finishedReceiver != null) {
7732                try {
7733                    finishedReceiver.performReceive(intent, 0,
7734                            null, null, false, false, UserHandle.getCallingUserId());
7735                } catch (RemoteException e) {
7736                }
7737            }
7738            return 0;
7739        }
7740    }
7741
7742    @Override
7743    public void cancelIntentSender(IIntentSender sender) {
7744        if (!(sender instanceof PendingIntentRecord)) {
7745            return;
7746        }
7747        synchronized(this) {
7748            PendingIntentRecord rec = (PendingIntentRecord)sender;
7749            try {
7750                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7751                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7752                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7753                    String msg = "Permission Denial: cancelIntentSender() from pid="
7754                        + Binder.getCallingPid()
7755                        + ", uid=" + Binder.getCallingUid()
7756                        + " is not allowed to cancel package "
7757                        + rec.key.packageName;
7758                    Slog.w(TAG, msg);
7759                    throw new SecurityException(msg);
7760                }
7761            } catch (RemoteException e) {
7762                throw new SecurityException(e);
7763            }
7764            cancelIntentSenderLocked(rec, true);
7765        }
7766    }
7767
7768    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7769        makeIntentSenderCanceledLocked(rec);
7770        mIntentSenderRecords.remove(rec.key);
7771        if (cleanActivity && rec.key.activity != null) {
7772            rec.key.activity.pendingResults.remove(rec.ref);
7773        }
7774    }
7775
7776    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7777        rec.canceled = true;
7778        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7779        if (callbacks != null) {
7780            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7781        }
7782    }
7783
7784    @Override
7785    public String getPackageForIntentSender(IIntentSender pendingResult) {
7786        if (!(pendingResult instanceof PendingIntentRecord)) {
7787            return null;
7788        }
7789        try {
7790            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7791            return res.key.packageName;
7792        } catch (ClassCastException e) {
7793        }
7794        return null;
7795    }
7796
7797    @Override
7798    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7799        if (!(sender instanceof PendingIntentRecord)) {
7800            return;
7801        }
7802        synchronized(this) {
7803            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7804        }
7805    }
7806
7807    @Override
7808    public void unregisterIntentSenderCancelListener(IIntentSender sender,
7809            IResultReceiver receiver) {
7810        if (!(sender instanceof PendingIntentRecord)) {
7811            return;
7812        }
7813        synchronized(this) {
7814            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7815        }
7816    }
7817
7818    @Override
7819    public int getUidForIntentSender(IIntentSender sender) {
7820        if (sender instanceof PendingIntentRecord) {
7821            try {
7822                PendingIntentRecord res = (PendingIntentRecord)sender;
7823                return res.uid;
7824            } catch (ClassCastException e) {
7825            }
7826        }
7827        return -1;
7828    }
7829
7830    @Override
7831    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7832        if (!(pendingResult instanceof PendingIntentRecord)) {
7833            return false;
7834        }
7835        try {
7836            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7837            if (res.key.allIntents == null) {
7838                return false;
7839            }
7840            for (int i=0; i<res.key.allIntents.length; i++) {
7841                Intent intent = res.key.allIntents[i];
7842                if (intent.getPackage() != null && intent.getComponent() != null) {
7843                    return false;
7844                }
7845            }
7846            return true;
7847        } catch (ClassCastException e) {
7848        }
7849        return false;
7850    }
7851
7852    @Override
7853    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7854        if (!(pendingResult instanceof PendingIntentRecord)) {
7855            return false;
7856        }
7857        try {
7858            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7859            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7860                return true;
7861            }
7862            return false;
7863        } catch (ClassCastException e) {
7864        }
7865        return false;
7866    }
7867
7868    @Override
7869    public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
7870        if (pendingResult instanceof PendingIntentRecord) {
7871            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
7872            return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
7873        }
7874        return false;
7875    }
7876
7877    @Override
7878    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7879        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7880                "getIntentForIntentSender()");
7881        if (!(pendingResult instanceof PendingIntentRecord)) {
7882            return null;
7883        }
7884        try {
7885            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7886            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7887        } catch (ClassCastException e) {
7888        }
7889        return null;
7890    }
7891
7892    @Override
7893    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7894        if (!(pendingResult instanceof PendingIntentRecord)) {
7895            return null;
7896        }
7897        try {
7898            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7899            synchronized (this) {
7900                return getTagForIntentSenderLocked(res, prefix);
7901            }
7902        } catch (ClassCastException e) {
7903        }
7904        return null;
7905    }
7906
7907    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7908        final Intent intent = res.key.requestIntent;
7909        if (intent != null) {
7910            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7911                    || res.lastTagPrefix.equals(prefix))) {
7912                return res.lastTag;
7913            }
7914            res.lastTagPrefix = prefix;
7915            final StringBuilder sb = new StringBuilder(128);
7916            if (prefix != null) {
7917                sb.append(prefix);
7918            }
7919            if (intent.getAction() != null) {
7920                sb.append(intent.getAction());
7921            } else if (intent.getComponent() != null) {
7922                intent.getComponent().appendShortString(sb);
7923            } else {
7924                sb.append("?");
7925            }
7926            return res.lastTag = sb.toString();
7927        }
7928        return null;
7929    }
7930
7931    @Override
7932    public void setProcessLimit(int max) {
7933        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7934                "setProcessLimit()");
7935        synchronized (this) {
7936            mConstants.setOverrideMaxCachedProcesses(max);
7937        }
7938        trimApplications();
7939    }
7940
7941    @Override
7942    public int getProcessLimit() {
7943        synchronized (this) {
7944            return mConstants.getOverrideMaxCachedProcesses();
7945        }
7946    }
7947
7948    void importanceTokenDied(ImportanceToken token) {
7949        synchronized (ActivityManagerService.this) {
7950            synchronized (mPidsSelfLocked) {
7951                ImportanceToken cur
7952                    = mImportantProcesses.get(token.pid);
7953                if (cur != token) {
7954                    return;
7955                }
7956                mImportantProcesses.remove(token.pid);
7957                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7958                if (pr == null) {
7959                    return;
7960                }
7961                pr.forcingToImportant = null;
7962                updateProcessForegroundLocked(pr, false, false);
7963            }
7964            updateOomAdjLocked();
7965        }
7966    }
7967
7968    @Override
7969    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7970        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7971                "setProcessImportant()");
7972        synchronized(this) {
7973            boolean changed = false;
7974
7975            synchronized (mPidsSelfLocked) {
7976                ProcessRecord pr = mPidsSelfLocked.get(pid);
7977                if (pr == null && isForeground) {
7978                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7979                    return;
7980                }
7981                ImportanceToken oldToken = mImportantProcesses.get(pid);
7982                if (oldToken != null) {
7983                    oldToken.token.unlinkToDeath(oldToken, 0);
7984                    mImportantProcesses.remove(pid);
7985                    if (pr != null) {
7986                        pr.forcingToImportant = null;
7987                    }
7988                    changed = true;
7989                }
7990                if (isForeground && token != null) {
7991                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7992                        @Override
7993                        public void binderDied() {
7994                            importanceTokenDied(this);
7995                        }
7996                    };
7997                    try {
7998                        token.linkToDeath(newToken, 0);
7999                        mImportantProcesses.put(pid, newToken);
8000                        pr.forcingToImportant = newToken;
8001                        changed = true;
8002                    } catch (RemoteException e) {
8003                        // If the process died while doing this, we will later
8004                        // do the cleanup with the process death link.
8005                    }
8006                }
8007            }
8008
8009            if (changed) {
8010                updateOomAdjLocked();
8011            }
8012        }
8013    }
8014
8015    @Override
8016    public boolean isAppForeground(int uid) throws RemoteException {
8017        synchronized (this) {
8018            UidRecord uidRec = mActiveUids.get(uid);
8019            if (uidRec == null || uidRec.idle) {
8020                return false;
8021            }
8022            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8023        }
8024    }
8025
8026    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8027    // be guarded by permission checking.
8028    int getUidState(int uid) {
8029        synchronized (this) {
8030            return getUidStateLocked(uid);
8031        }
8032    }
8033
8034    int getUidStateLocked(int uid) {
8035        UidRecord uidRec = mActiveUids.get(uid);
8036        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8037    }
8038
8039    @Override
8040    public boolean isInMultiWindowMode(IBinder token) {
8041        final long origId = Binder.clearCallingIdentity();
8042        try {
8043            synchronized(this) {
8044                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8045                if (r == null) {
8046                    return false;
8047                }
8048                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8049                return !r.getTask().mFullscreen;
8050            }
8051        } finally {
8052            Binder.restoreCallingIdentity(origId);
8053        }
8054    }
8055
8056    @Override
8057    public boolean isInPictureInPictureMode(IBinder token) {
8058        final long origId = Binder.clearCallingIdentity();
8059        try {
8060            synchronized(this) {
8061                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8062            }
8063        } finally {
8064            Binder.restoreCallingIdentity(origId);
8065        }
8066    }
8067
8068    private boolean isInPictureInPictureMode(ActivityRecord r) {
8069        if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8070                r.getStack().isInStackLocked(r) == null) {
8071            return false;
8072        }
8073
8074        // If we are animating to fullscreen then we have already dispatched the PIP mode
8075        // changed, so we should reflect that check here as well.
8076        final PinnedActivityStack stack = r.getStack();
8077        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8078        return !windowController.isAnimatingBoundsToFullscreen();
8079    }
8080
8081    @Override
8082    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8083        final long origId = Binder.clearCallingIdentity();
8084        try {
8085            synchronized(this) {
8086                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8087                        "enterPictureInPictureMode", token, params);
8088
8089                // If the activity is already in picture in picture mode, then just return early
8090                if (isInPictureInPictureMode(r)) {
8091                    return true;
8092                }
8093
8094                // Activity supports picture-in-picture, now check that we can enter PiP at this
8095                // point, if it is
8096                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8097                        false /* beforeStopping */)) {
8098                    return false;
8099                }
8100
8101                final Runnable enterPipRunnable = () -> {
8102                    // Only update the saved args from the args that are set
8103                    r.pictureInPictureArgs.copyOnlySet(params);
8104                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8105                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8106                    // Adjust the source bounds by the insets for the transition down
8107                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8108                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8109                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8110                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8111                    stack.setPictureInPictureAspectRatio(aspectRatio);
8112                    stack.setPictureInPictureActions(actions);
8113
8114                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8115                            r.supportsEnterPipOnTaskSwitch);
8116                    logPictureInPictureArgs(params);
8117                };
8118
8119                if (isKeyguardLocked()) {
8120                    // If the keyguard is showing or occluded, then try and dismiss it before
8121                    // entering picture-in-picture (this will prompt the user to authenticate if the
8122                    // device is currently locked).
8123                    try {
8124                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8125                            @Override
8126                            public void onDismissError() throws RemoteException {
8127                                // Do nothing
8128                            }
8129
8130                            @Override
8131                            public void onDismissSucceeded() throws RemoteException {
8132                                mHandler.post(enterPipRunnable);
8133                            }
8134
8135                            @Override
8136                            public void onDismissCancelled() throws RemoteException {
8137                                // Do nothing
8138                            }
8139                        });
8140                    } catch (RemoteException e) {
8141                        // Local call
8142                    }
8143                } else {
8144                    // Enter picture in picture immediately otherwise
8145                    enterPipRunnable.run();
8146                }
8147                return true;
8148            }
8149        } finally {
8150            Binder.restoreCallingIdentity(origId);
8151        }
8152    }
8153
8154    @Override
8155    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8156        final long origId = Binder.clearCallingIdentity();
8157        try {
8158            synchronized(this) {
8159                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8160                        "setPictureInPictureParams", token, params);
8161
8162                // Only update the saved args from the args that are set
8163                r.pictureInPictureArgs.copyOnlySet(params);
8164                if (r.getStack().getStackId() == PINNED_STACK_ID) {
8165                    // If the activity is already in picture-in-picture, update the pinned stack now
8166                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8167                    // be used the next time the activity enters PiP
8168                    final PinnedActivityStack stack = r.getStack();
8169                    if (!stack.isAnimatingBoundsToFullscreen()) {
8170                        stack.setPictureInPictureAspectRatio(
8171                                r.pictureInPictureArgs.getAspectRatio());
8172                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8173                    }
8174                }
8175                logPictureInPictureArgs(params);
8176            }
8177        } finally {
8178            Binder.restoreCallingIdentity(origId);
8179        }
8180    }
8181
8182    @Override
8183    public int getMaxNumPictureInPictureActions(IBinder token) {
8184        // Currently, this is a static constant, but later, we may change this to be dependent on
8185        // the context of the activity
8186        return 3;
8187    }
8188
8189    private void logPictureInPictureArgs(PictureInPictureParams params) {
8190        if (params.hasSetActions()) {
8191            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8192                    params.getActions().size());
8193        }
8194        if (params.hasSetAspectRatio()) {
8195            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8196            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8197            MetricsLogger.action(lm);
8198        }
8199    }
8200
8201    /**
8202     * Checks the state of the system and the activity associated with the given {@param token} to
8203     * verify that picture-in-picture is supported for that activity.
8204     *
8205     * @return the activity record for the given {@param token} if all the checks pass.
8206     */
8207    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8208            IBinder token, PictureInPictureParams params) {
8209        if (!mSupportsPictureInPicture) {
8210            throw new IllegalStateException(caller
8211                    + ": Device doesn't support picture-in-picture mode.");
8212        }
8213
8214        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8215        if (r == null) {
8216            throw new IllegalStateException(caller
8217                    + ": Can't find activity for token=" + token);
8218        }
8219
8220        if (!r.supportsPictureInPicture()) {
8221            throw new IllegalStateException(caller
8222                    + ": Current activity does not support picture-in-picture.");
8223        }
8224
8225        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8226            throw new IllegalStateException(caller
8227                    + ": Activities on the home, assistant, or recents stack not supported");
8228        }
8229
8230        if (params.hasSetAspectRatio()
8231                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8232                        params.getAspectRatio())) {
8233            final float minAspectRatio = mContext.getResources().getFloat(
8234                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8235            final float maxAspectRatio = mContext.getResources().getFloat(
8236                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8237            throw new IllegalArgumentException(String.format(caller
8238                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8239                            minAspectRatio, maxAspectRatio));
8240        }
8241
8242        // Truncate the number of actions if necessary
8243        params.truncateActions(getMaxNumPictureInPictureActions(token));
8244
8245        return r;
8246    }
8247
8248    // =========================================================
8249    // PROCESS INFO
8250    // =========================================================
8251
8252    static class ProcessInfoService extends IProcessInfoService.Stub {
8253        final ActivityManagerService mActivityManagerService;
8254        ProcessInfoService(ActivityManagerService activityManagerService) {
8255            mActivityManagerService = activityManagerService;
8256        }
8257
8258        @Override
8259        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8260            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8261                    /*in*/ pids, /*out*/ states, null);
8262        }
8263
8264        @Override
8265        public void getProcessStatesAndOomScoresFromPids(
8266                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8267            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8268                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8269        }
8270    }
8271
8272    /**
8273     * For each PID in the given input array, write the current process state
8274     * for that process into the states array, or -1 to indicate that no
8275     * process with the given PID exists. If scores array is provided, write
8276     * the oom score for the process into the scores array, with INVALID_ADJ
8277     * indicating the PID doesn't exist.
8278     */
8279    public void getProcessStatesAndOomScoresForPIDs(
8280            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8281        if (scores != null) {
8282            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8283                    "getProcessStatesAndOomScoresForPIDs()");
8284        }
8285
8286        if (pids == null) {
8287            throw new NullPointerException("pids");
8288        } else if (states == null) {
8289            throw new NullPointerException("states");
8290        } else if (pids.length != states.length) {
8291            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8292        } else if (scores != null && pids.length != scores.length) {
8293            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8294        }
8295
8296        synchronized (mPidsSelfLocked) {
8297            for (int i = 0; i < pids.length; i++) {
8298                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8299                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8300                        pr.curProcState;
8301                if (scores != null) {
8302                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8303                }
8304            }
8305        }
8306    }
8307
8308    // =========================================================
8309    // PERMISSIONS
8310    // =========================================================
8311
8312    static class PermissionController extends IPermissionController.Stub {
8313        ActivityManagerService mActivityManagerService;
8314        PermissionController(ActivityManagerService activityManagerService) {
8315            mActivityManagerService = activityManagerService;
8316        }
8317
8318        @Override
8319        public boolean checkPermission(String permission, int pid, int uid) {
8320            return mActivityManagerService.checkPermission(permission, pid,
8321                    uid) == PackageManager.PERMISSION_GRANTED;
8322        }
8323
8324        @Override
8325        public String[] getPackagesForUid(int uid) {
8326            return mActivityManagerService.mContext.getPackageManager()
8327                    .getPackagesForUid(uid);
8328        }
8329
8330        @Override
8331        public boolean isRuntimePermission(String permission) {
8332            try {
8333                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8334                        .getPermissionInfo(permission, 0);
8335                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8336                        == PermissionInfo.PROTECTION_DANGEROUS;
8337            } catch (NameNotFoundException nnfe) {
8338                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8339            }
8340            return false;
8341        }
8342    }
8343
8344    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8345        @Override
8346        public int checkComponentPermission(String permission, int pid, int uid,
8347                int owningUid, boolean exported) {
8348            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8349                    owningUid, exported);
8350        }
8351
8352        @Override
8353        public Object getAMSLock() {
8354            return ActivityManagerService.this;
8355        }
8356    }
8357
8358    /**
8359     * This can be called with or without the global lock held.
8360     */
8361    int checkComponentPermission(String permission, int pid, int uid,
8362            int owningUid, boolean exported) {
8363        if (pid == MY_PID) {
8364            return PackageManager.PERMISSION_GRANTED;
8365        }
8366        return ActivityManager.checkComponentPermission(permission, uid,
8367                owningUid, exported);
8368    }
8369
8370    /**
8371     * As the only public entry point for permissions checking, this method
8372     * can enforce the semantic that requesting a check on a null global
8373     * permission is automatically denied.  (Internally a null permission
8374     * string is used when calling {@link #checkComponentPermission} in cases
8375     * when only uid-based security is needed.)
8376     *
8377     * This can be called with or without the global lock held.
8378     */
8379    @Override
8380    public int checkPermission(String permission, int pid, int uid) {
8381        if (permission == null) {
8382            return PackageManager.PERMISSION_DENIED;
8383        }
8384        return checkComponentPermission(permission, pid, uid, -1, true);
8385    }
8386
8387    @Override
8388    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8389        if (permission == null) {
8390            return PackageManager.PERMISSION_DENIED;
8391        }
8392
8393        // We might be performing an operation on behalf of an indirect binder
8394        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8395        // client identity accordingly before proceeding.
8396        Identity tlsIdentity = sCallerIdentity.get();
8397        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8398            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8399                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8400            uid = tlsIdentity.uid;
8401            pid = tlsIdentity.pid;
8402        }
8403
8404        return checkComponentPermission(permission, pid, uid, -1, true);
8405    }
8406
8407    /**
8408     * Binder IPC calls go through the public entry point.
8409     * This can be called with or without the global lock held.
8410     */
8411    int checkCallingPermission(String permission) {
8412        return checkPermission(permission,
8413                Binder.getCallingPid(),
8414                UserHandle.getAppId(Binder.getCallingUid()));
8415    }
8416
8417    /**
8418     * This can be called with or without the global lock held.
8419     */
8420    void enforceCallingPermission(String permission, String func) {
8421        if (checkCallingPermission(permission)
8422                == PackageManager.PERMISSION_GRANTED) {
8423            return;
8424        }
8425
8426        String msg = "Permission Denial: " + func + " from pid="
8427                + Binder.getCallingPid()
8428                + ", uid=" + Binder.getCallingUid()
8429                + " requires " + permission;
8430        Slog.w(TAG, msg);
8431        throw new SecurityException(msg);
8432    }
8433
8434    /**
8435     * Determine if UID is holding permissions required to access {@link Uri} in
8436     * the given {@link ProviderInfo}. Final permission checking is always done
8437     * in {@link ContentProvider}.
8438     */
8439    private final boolean checkHoldingPermissionsLocked(
8440            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8441        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8442                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8443        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8444            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8445                    != PERMISSION_GRANTED) {
8446                return false;
8447            }
8448        }
8449        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8450    }
8451
8452    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8453            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8454        if (pi.applicationInfo.uid == uid) {
8455            return true;
8456        } else if (!pi.exported) {
8457            return false;
8458        }
8459
8460        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8461        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8462        try {
8463            // check if target holds top-level <provider> permissions
8464            if (!readMet && pi.readPermission != null && considerUidPermissions
8465                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8466                readMet = true;
8467            }
8468            if (!writeMet && pi.writePermission != null && considerUidPermissions
8469                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8470                writeMet = true;
8471            }
8472
8473            // track if unprotected read/write is allowed; any denied
8474            // <path-permission> below removes this ability
8475            boolean allowDefaultRead = pi.readPermission == null;
8476            boolean allowDefaultWrite = pi.writePermission == null;
8477
8478            // check if target holds any <path-permission> that match uri
8479            final PathPermission[] pps = pi.pathPermissions;
8480            if (pps != null) {
8481                final String path = grantUri.uri.getPath();
8482                int i = pps.length;
8483                while (i > 0 && (!readMet || !writeMet)) {
8484                    i--;
8485                    PathPermission pp = pps[i];
8486                    if (pp.match(path)) {
8487                        if (!readMet) {
8488                            final String pprperm = pp.getReadPermission();
8489                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8490                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8491                                    + ": match=" + pp.match(path)
8492                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8493                            if (pprperm != null) {
8494                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8495                                        == PERMISSION_GRANTED) {
8496                                    readMet = true;
8497                                } else {
8498                                    allowDefaultRead = false;
8499                                }
8500                            }
8501                        }
8502                        if (!writeMet) {
8503                            final String ppwperm = pp.getWritePermission();
8504                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8505                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8506                                    + ": match=" + pp.match(path)
8507                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8508                            if (ppwperm != null) {
8509                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8510                                        == PERMISSION_GRANTED) {
8511                                    writeMet = true;
8512                                } else {
8513                                    allowDefaultWrite = false;
8514                                }
8515                            }
8516                        }
8517                    }
8518                }
8519            }
8520
8521            // grant unprotected <provider> read/write, if not blocked by
8522            // <path-permission> above
8523            if (allowDefaultRead) readMet = true;
8524            if (allowDefaultWrite) writeMet = true;
8525
8526        } catch (RemoteException e) {
8527            return false;
8528        }
8529
8530        return readMet && writeMet;
8531    }
8532
8533    public boolean isAppStartModeDisabled(int uid, String packageName) {
8534        synchronized (this) {
8535            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8536                    == ActivityManager.APP_START_MODE_DISABLED;
8537        }
8538    }
8539
8540    // Unified app-op and target sdk check
8541    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8542        // Apps that target O+ are always subject to background check
8543        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8544            if (DEBUG_BACKGROUND_CHECK) {
8545                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8546            }
8547            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8548        }
8549        // ...and legacy apps get an AppOp check
8550        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8551                uid, packageName);
8552        if (DEBUG_BACKGROUND_CHECK) {
8553            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8554        }
8555        switch (appop) {
8556            case AppOpsManager.MODE_ALLOWED:
8557                return ActivityManager.APP_START_MODE_NORMAL;
8558            case AppOpsManager.MODE_IGNORED:
8559                return ActivityManager.APP_START_MODE_DELAYED;
8560            default:
8561                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8562        }
8563    }
8564
8565    // Service launch is available to apps with run-in-background exemptions but
8566    // some other background operations are not.  If we're doing a check
8567    // of service-launch policy, allow those callers to proceed unrestricted.
8568    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8569        // Persistent app?
8570        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8571            if (DEBUG_BACKGROUND_CHECK) {
8572                Slog.i(TAG, "App " + uid + "/" + packageName
8573                        + " is persistent; not restricted in background");
8574            }
8575            return ActivityManager.APP_START_MODE_NORMAL;
8576        }
8577
8578        // Non-persistent but background whitelisted?
8579        if (uidOnBackgroundWhitelist(uid)) {
8580            if (DEBUG_BACKGROUND_CHECK) {
8581                Slog.i(TAG, "App " + uid + "/" + packageName
8582                        + " on background whitelist; not restricted in background");
8583            }
8584            return ActivityManager.APP_START_MODE_NORMAL;
8585        }
8586
8587        // Is this app on the battery whitelist?
8588        if (isOnDeviceIdleWhitelistLocked(uid)) {
8589            if (DEBUG_BACKGROUND_CHECK) {
8590                Slog.i(TAG, "App " + uid + "/" + packageName
8591                        + " on idle whitelist; not restricted in background");
8592            }
8593            return ActivityManager.APP_START_MODE_NORMAL;
8594        }
8595
8596        // None of the service-policy criteria apply, so we apply the common criteria
8597        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8598    }
8599
8600    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8601            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8602        UidRecord uidRec = mActiveUids.get(uid);
8603        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8604                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8605                + (uidRec != null ? uidRec.idle : false));
8606        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8607            boolean ephemeral;
8608            if (uidRec == null) {
8609                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8610                        UserHandle.getUserId(uid), packageName);
8611            } else {
8612                ephemeral = uidRec.ephemeral;
8613            }
8614
8615            if (ephemeral) {
8616                // We are hard-core about ephemeral apps not running in the background.
8617                return ActivityManager.APP_START_MODE_DISABLED;
8618            } else {
8619                if (disabledOnly) {
8620                    // The caller is only interested in whether app starts are completely
8621                    // disabled for the given package (that is, it is an instant app).  So
8622                    // we don't need to go further, which is all just seeing if we should
8623                    // apply a "delayed" mode for a regular app.
8624                    return ActivityManager.APP_START_MODE_NORMAL;
8625                }
8626                final int startMode = (alwaysRestrict)
8627                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8628                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8629                                packageTargetSdk);
8630                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8631                        + " pkg=" + packageName + " startMode=" + startMode
8632                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8633                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8634                    // This is an old app that has been forced into a "compatible as possible"
8635                    // mode of background check.  To increase compatibility, we will allow other
8636                    // foreground apps to cause its services to start.
8637                    if (callingPid >= 0) {
8638                        ProcessRecord proc;
8639                        synchronized (mPidsSelfLocked) {
8640                            proc = mPidsSelfLocked.get(callingPid);
8641                        }
8642                        if (proc != null &&
8643                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
8644                            // Whoever is instigating this is in the foreground, so we will allow it
8645                            // to go through.
8646                            return ActivityManager.APP_START_MODE_NORMAL;
8647                        }
8648                    }
8649                }
8650                return startMode;
8651            }
8652        }
8653        return ActivityManager.APP_START_MODE_NORMAL;
8654    }
8655
8656    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8657        final int appId = UserHandle.getAppId(uid);
8658        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8659                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8660                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8661    }
8662
8663    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8664        ProviderInfo pi = null;
8665        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8666        if (cpr != null) {
8667            pi = cpr.info;
8668        } else {
8669            try {
8670                pi = AppGlobals.getPackageManager().resolveContentProvider(
8671                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8672                        userHandle);
8673            } catch (RemoteException ex) {
8674            }
8675        }
8676        return pi;
8677    }
8678
8679    void grantEphemeralAccessLocked(int userId, Intent intent,
8680            int targetAppId, int ephemeralAppId) {
8681        getPackageManagerInternalLocked().
8682                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8683    }
8684
8685    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8686        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8687        if (targetUris != null) {
8688            return targetUris.get(grantUri);
8689        }
8690        return null;
8691    }
8692
8693    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8694            String targetPkg, int targetUid, GrantUri grantUri) {
8695        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8696        if (targetUris == null) {
8697            targetUris = Maps.newArrayMap();
8698            mGrantedUriPermissions.put(targetUid, targetUris);
8699        }
8700
8701        UriPermission perm = targetUris.get(grantUri);
8702        if (perm == null) {
8703            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8704            targetUris.put(grantUri, perm);
8705        }
8706
8707        return perm;
8708    }
8709
8710    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8711            final int modeFlags) {
8712        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8713        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8714                : UriPermission.STRENGTH_OWNED;
8715
8716        // Root gets to do everything.
8717        if (uid == 0) {
8718            return true;
8719        }
8720
8721        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8722        if (perms == null) return false;
8723
8724        // First look for exact match
8725        final UriPermission exactPerm = perms.get(grantUri);
8726        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8727            return true;
8728        }
8729
8730        // No exact match, look for prefixes
8731        final int N = perms.size();
8732        for (int i = 0; i < N; i++) {
8733            final UriPermission perm = perms.valueAt(i);
8734            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8735                    && perm.getStrength(modeFlags) >= minStrength) {
8736                return true;
8737            }
8738        }
8739
8740        return false;
8741    }
8742
8743    /**
8744     * @param uri This uri must NOT contain an embedded userId.
8745     * @param userId The userId in which the uri is to be resolved.
8746     */
8747    @Override
8748    public int checkUriPermission(Uri uri, int pid, int uid,
8749            final int modeFlags, int userId, IBinder callerToken) {
8750        enforceNotIsolatedCaller("checkUriPermission");
8751
8752        // Another redirected-binder-call permissions check as in
8753        // {@link checkPermissionWithToken}.
8754        Identity tlsIdentity = sCallerIdentity.get();
8755        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8756            uid = tlsIdentity.uid;
8757            pid = tlsIdentity.pid;
8758        }
8759
8760        // Our own process gets to do everything.
8761        if (pid == MY_PID) {
8762            return PackageManager.PERMISSION_GRANTED;
8763        }
8764        synchronized (this) {
8765            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8766                    ? PackageManager.PERMISSION_GRANTED
8767                    : PackageManager.PERMISSION_DENIED;
8768        }
8769    }
8770
8771    /**
8772     * Check if the targetPkg can be granted permission to access uri by
8773     * the callingUid using the given modeFlags.  Throws a security exception
8774     * if callingUid is not allowed to do this.  Returns the uid of the target
8775     * if the URI permission grant should be performed; returns -1 if it is not
8776     * needed (for example targetPkg already has permission to access the URI).
8777     * If you already know the uid of the target, you can supply it in
8778     * lastTargetUid else set that to -1.
8779     */
8780    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8781            final int modeFlags, int lastTargetUid) {
8782        if (!Intent.isAccessUriMode(modeFlags)) {
8783            return -1;
8784        }
8785
8786        if (targetPkg != null) {
8787            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8788                    "Checking grant " + targetPkg + " permission to " + grantUri);
8789        }
8790
8791        final IPackageManager pm = AppGlobals.getPackageManager();
8792
8793        // If this is not a content: uri, we can't do anything with it.
8794        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8795            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8796                    "Can't grant URI permission for non-content URI: " + grantUri);
8797            return -1;
8798        }
8799
8800        // Bail early if system is trying to hand out permissions directly; it
8801        // must always grant permissions on behalf of someone explicit.
8802        final int callingAppId = UserHandle.getAppId(callingUid);
8803        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8804            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8805                // Exempted authority for cropping user photos in Settings app
8806            } else {
8807                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8808                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8809                return -1;
8810            }
8811        }
8812
8813        final String authority = grantUri.uri.getAuthority();
8814        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8815                MATCH_DEBUG_TRIAGED_MISSING);
8816        if (pi == null) {
8817            Slog.w(TAG, "No content provider found for permission check: " +
8818                    grantUri.uri.toSafeString());
8819            return -1;
8820        }
8821
8822        int targetUid = lastTargetUid;
8823        if (targetUid < 0 && targetPkg != null) {
8824            try {
8825                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8826                        UserHandle.getUserId(callingUid));
8827                if (targetUid < 0) {
8828                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8829                            "Can't grant URI permission no uid for: " + targetPkg);
8830                    return -1;
8831                }
8832            } catch (RemoteException ex) {
8833                return -1;
8834            }
8835        }
8836
8837        // If we're extending a persistable grant, then we always need to create
8838        // the grant data structure so that take/release APIs work
8839        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8840            return targetUid;
8841        }
8842
8843        if (targetUid >= 0) {
8844            // First...  does the target actually need this permission?
8845            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8846                // No need to grant the target this permission.
8847                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8848                        "Target " + targetPkg + " already has full permission to " + grantUri);
8849                return -1;
8850            }
8851        } else {
8852            // First...  there is no target package, so can anyone access it?
8853            boolean allowed = pi.exported;
8854            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8855                if (pi.readPermission != null) {
8856                    allowed = false;
8857                }
8858            }
8859            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8860                if (pi.writePermission != null) {
8861                    allowed = false;
8862                }
8863            }
8864            if (allowed) {
8865                return -1;
8866            }
8867        }
8868
8869        /* There is a special cross user grant if:
8870         * - The target is on another user.
8871         * - Apps on the current user can access the uri without any uid permissions.
8872         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8873         * grant uri permissions.
8874         */
8875        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8876                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8877                modeFlags, false /*without considering the uid permissions*/);
8878
8879        // Second...  is the provider allowing granting of URI permissions?
8880        if (!specialCrossUserGrant) {
8881            if (!pi.grantUriPermissions) {
8882                throw new SecurityException("Provider " + pi.packageName
8883                        + "/" + pi.name
8884                        + " does not allow granting of Uri permissions (uri "
8885                        + grantUri + ")");
8886            }
8887            if (pi.uriPermissionPatterns != null) {
8888                final int N = pi.uriPermissionPatterns.length;
8889                boolean allowed = false;
8890                for (int i=0; i<N; i++) {
8891                    if (pi.uriPermissionPatterns[i] != null
8892                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8893                        allowed = true;
8894                        break;
8895                    }
8896                }
8897                if (!allowed) {
8898                    throw new SecurityException("Provider " + pi.packageName
8899                            + "/" + pi.name
8900                            + " does not allow granting of permission to path of Uri "
8901                            + grantUri);
8902                }
8903            }
8904        }
8905
8906        // Third...  does the caller itself have permission to access
8907        // this uri?
8908        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8909            // Require they hold a strong enough Uri permission
8910            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8911                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8912                    throw new SecurityException(
8913                            "UID " + callingUid + " does not have permission to " + grantUri
8914                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8915                                    + "or related APIs");
8916                } else {
8917                    throw new SecurityException(
8918                            "UID " + callingUid + " does not have permission to " + grantUri);
8919                }
8920            }
8921        }
8922        return targetUid;
8923    }
8924
8925    /**
8926     * @param uri This uri must NOT contain an embedded userId.
8927     * @param userId The userId in which the uri is to be resolved.
8928     */
8929    @Override
8930    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8931            final int modeFlags, int userId) {
8932        enforceNotIsolatedCaller("checkGrantUriPermission");
8933        synchronized(this) {
8934            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8935                    new GrantUri(userId, uri, false), modeFlags, -1);
8936        }
8937    }
8938
8939    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8940            final int modeFlags, UriPermissionOwner owner) {
8941        if (!Intent.isAccessUriMode(modeFlags)) {
8942            return;
8943        }
8944
8945        // So here we are: the caller has the assumed permission
8946        // to the uri, and the target doesn't.  Let's now give this to
8947        // the target.
8948
8949        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8950                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8951
8952        final String authority = grantUri.uri.getAuthority();
8953        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8954                MATCH_DEBUG_TRIAGED_MISSING);
8955        if (pi == null) {
8956            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8957            return;
8958        }
8959
8960        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8961            grantUri.prefix = true;
8962        }
8963        final UriPermission perm = findOrCreateUriPermissionLocked(
8964                pi.packageName, targetPkg, targetUid, grantUri);
8965        perm.grantModes(modeFlags, owner);
8966    }
8967
8968    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8969            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8970        if (targetPkg == null) {
8971            throw new NullPointerException("targetPkg");
8972        }
8973        int targetUid;
8974        final IPackageManager pm = AppGlobals.getPackageManager();
8975        try {
8976            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8977        } catch (RemoteException ex) {
8978            return;
8979        }
8980
8981        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8982                targetUid);
8983        if (targetUid < 0) {
8984            return;
8985        }
8986
8987        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8988                owner);
8989    }
8990
8991    static class NeededUriGrants extends ArrayList<GrantUri> {
8992        final String targetPkg;
8993        final int targetUid;
8994        final int flags;
8995
8996        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8997            this.targetPkg = targetPkg;
8998            this.targetUid = targetUid;
8999            this.flags = flags;
9000        }
9001    }
9002
9003    /**
9004     * Like checkGrantUriPermissionLocked, but takes an Intent.
9005     */
9006    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9007            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9008        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9009                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9010                + " clip=" + (intent != null ? intent.getClipData() : null)
9011                + " from " + intent + "; flags=0x"
9012                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9013
9014        if (targetPkg == null) {
9015            throw new NullPointerException("targetPkg");
9016        }
9017
9018        if (intent == null) {
9019            return null;
9020        }
9021        Uri data = intent.getData();
9022        ClipData clip = intent.getClipData();
9023        if (data == null && clip == null) {
9024            return null;
9025        }
9026        // Default userId for uris in the intent (if they don't specify it themselves)
9027        int contentUserHint = intent.getContentUserHint();
9028        if (contentUserHint == UserHandle.USER_CURRENT) {
9029            contentUserHint = UserHandle.getUserId(callingUid);
9030        }
9031        final IPackageManager pm = AppGlobals.getPackageManager();
9032        int targetUid;
9033        if (needed != null) {
9034            targetUid = needed.targetUid;
9035        } else {
9036            try {
9037                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9038                        targetUserId);
9039            } catch (RemoteException ex) {
9040                return null;
9041            }
9042            if (targetUid < 0) {
9043                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9044                        "Can't grant URI permission no uid for: " + targetPkg
9045                        + " on user " + targetUserId);
9046                return null;
9047            }
9048        }
9049        if (data != null) {
9050            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9051            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9052                    targetUid);
9053            if (targetUid > 0) {
9054                if (needed == null) {
9055                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9056                }
9057                needed.add(grantUri);
9058            }
9059        }
9060        if (clip != null) {
9061            for (int i=0; i<clip.getItemCount(); i++) {
9062                Uri uri = clip.getItemAt(i).getUri();
9063                if (uri != null) {
9064                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9065                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9066                            targetUid);
9067                    if (targetUid > 0) {
9068                        if (needed == null) {
9069                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9070                        }
9071                        needed.add(grantUri);
9072                    }
9073                } else {
9074                    Intent clipIntent = clip.getItemAt(i).getIntent();
9075                    if (clipIntent != null) {
9076                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9077                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9078                        if (newNeeded != null) {
9079                            needed = newNeeded;
9080                        }
9081                    }
9082                }
9083            }
9084        }
9085
9086        return needed;
9087    }
9088
9089    /**
9090     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9091     */
9092    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9093            UriPermissionOwner owner) {
9094        if (needed != null) {
9095            for (int i=0; i<needed.size(); i++) {
9096                GrantUri grantUri = needed.get(i);
9097                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9098                        grantUri, needed.flags, owner);
9099            }
9100        }
9101    }
9102
9103    void grantUriPermissionFromIntentLocked(int callingUid,
9104            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9105        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9106                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9107        if (needed == null) {
9108            return;
9109        }
9110
9111        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9112    }
9113
9114    /**
9115     * @param uri This uri must NOT contain an embedded userId.
9116     * @param userId The userId in which the uri is to be resolved.
9117     */
9118    @Override
9119    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9120            final int modeFlags, int userId) {
9121        enforceNotIsolatedCaller("grantUriPermission");
9122        GrantUri grantUri = new GrantUri(userId, uri, false);
9123        synchronized(this) {
9124            final ProcessRecord r = getRecordForAppLocked(caller);
9125            if (r == null) {
9126                throw new SecurityException("Unable to find app for caller "
9127                        + caller
9128                        + " when granting permission to uri " + grantUri);
9129            }
9130            if (targetPkg == null) {
9131                throw new IllegalArgumentException("null target");
9132            }
9133            if (grantUri == null) {
9134                throw new IllegalArgumentException("null uri");
9135            }
9136
9137            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9138                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9139                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9140                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9141
9142            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9143                    UserHandle.getUserId(r.uid));
9144        }
9145    }
9146
9147    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9148        if (perm.modeFlags == 0) {
9149            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9150                    perm.targetUid);
9151            if (perms != null) {
9152                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9153                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9154
9155                perms.remove(perm.uri);
9156                if (perms.isEmpty()) {
9157                    mGrantedUriPermissions.remove(perm.targetUid);
9158                }
9159            }
9160        }
9161    }
9162
9163    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9164            final int modeFlags) {
9165        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9166                "Revoking all granted permissions to " + grantUri);
9167
9168        final IPackageManager pm = AppGlobals.getPackageManager();
9169        final String authority = grantUri.uri.getAuthority();
9170        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9171                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9172        if (pi == null) {
9173            Slog.w(TAG, "No content provider found for permission revoke: "
9174                    + grantUri.toSafeString());
9175            return;
9176        }
9177
9178        // Does the caller have this permission on the URI?
9179        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9180            // If they don't have direct access to the URI, then revoke any
9181            // ownerless URI permissions that have been granted to them.
9182            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9183            if (perms != null) {
9184                boolean persistChanged = false;
9185                for (int i = perms.size()-1; i >= 0; i--) {
9186                    final UriPermission perm = perms.valueAt(i);
9187                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9188                        continue;
9189                    }
9190                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9191                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9192                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9193                                "Revoking non-owned " + perm.targetUid
9194                                + " permission to " + perm.uri);
9195                        persistChanged |= perm.revokeModes(
9196                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9197                        if (perm.modeFlags == 0) {
9198                            perms.removeAt(i);
9199                        }
9200                    }
9201                }
9202                if (perms.isEmpty()) {
9203                    mGrantedUriPermissions.remove(callingUid);
9204                }
9205                if (persistChanged) {
9206                    schedulePersistUriGrants();
9207                }
9208            }
9209            return;
9210        }
9211
9212        boolean persistChanged = false;
9213
9214        // Go through all of the permissions and remove any that match.
9215        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9216            final int targetUid = mGrantedUriPermissions.keyAt(i);
9217            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9218
9219            for (int j = perms.size()-1; j >= 0; j--) {
9220                final UriPermission perm = perms.valueAt(j);
9221                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9222                    continue;
9223                }
9224                if (perm.uri.sourceUserId == grantUri.sourceUserId
9225                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9226                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9227                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9228                    persistChanged |= perm.revokeModes(
9229                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9230                            targetPackage == null);
9231                    if (perm.modeFlags == 0) {
9232                        perms.removeAt(j);
9233                    }
9234                }
9235            }
9236
9237            if (perms.isEmpty()) {
9238                mGrantedUriPermissions.removeAt(i);
9239            }
9240        }
9241
9242        if (persistChanged) {
9243            schedulePersistUriGrants();
9244        }
9245    }
9246
9247    /**
9248     * @param uri This uri must NOT contain an embedded userId.
9249     * @param userId The userId in which the uri is to be resolved.
9250     */
9251    @Override
9252    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9253            final int modeFlags, int userId) {
9254        enforceNotIsolatedCaller("revokeUriPermission");
9255        synchronized(this) {
9256            final ProcessRecord r = getRecordForAppLocked(caller);
9257            if (r == null) {
9258                throw new SecurityException("Unable to find app for caller "
9259                        + caller
9260                        + " when revoking permission to uri " + uri);
9261            }
9262            if (uri == null) {
9263                Slog.w(TAG, "revokeUriPermission: null uri");
9264                return;
9265            }
9266
9267            if (!Intent.isAccessUriMode(modeFlags)) {
9268                return;
9269            }
9270
9271            final String authority = uri.getAuthority();
9272            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9273                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9274            if (pi == null) {
9275                Slog.w(TAG, "No content provider found for permission revoke: "
9276                        + uri.toSafeString());
9277                return;
9278            }
9279
9280            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9281                    modeFlags);
9282        }
9283    }
9284
9285    /**
9286     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9287     * given package.
9288     *
9289     * @param packageName Package name to match, or {@code null} to apply to all
9290     *            packages.
9291     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9292     *            to all users.
9293     * @param persistable If persistable grants should be removed.
9294     */
9295    private void removeUriPermissionsForPackageLocked(
9296            String packageName, int userHandle, boolean persistable) {
9297        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9298            throw new IllegalArgumentException("Must narrow by either package or user");
9299        }
9300
9301        boolean persistChanged = false;
9302
9303        int N = mGrantedUriPermissions.size();
9304        for (int i = 0; i < N; i++) {
9305            final int targetUid = mGrantedUriPermissions.keyAt(i);
9306            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9307
9308            // Only inspect grants matching user
9309            if (userHandle == UserHandle.USER_ALL
9310                    || userHandle == UserHandle.getUserId(targetUid)) {
9311                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9312                    final UriPermission perm = it.next();
9313
9314                    // Only inspect grants matching package
9315                    if (packageName == null || perm.sourcePkg.equals(packageName)
9316                            || perm.targetPkg.equals(packageName)) {
9317                        // Hacky solution as part of fixing a security bug; ignore
9318                        // grants associated with DownloadManager so we don't have
9319                        // to immediately launch it to regrant the permissions
9320                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9321                                && !persistable) continue;
9322
9323                        persistChanged |= perm.revokeModes(persistable
9324                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9325
9326                        // Only remove when no modes remain; any persisted grants
9327                        // will keep this alive.
9328                        if (perm.modeFlags == 0) {
9329                            it.remove();
9330                        }
9331                    }
9332                }
9333
9334                if (perms.isEmpty()) {
9335                    mGrantedUriPermissions.remove(targetUid);
9336                    N--;
9337                    i--;
9338                }
9339            }
9340        }
9341
9342        if (persistChanged) {
9343            schedulePersistUriGrants();
9344        }
9345    }
9346
9347    @Override
9348    public IBinder newUriPermissionOwner(String name) {
9349        enforceNotIsolatedCaller("newUriPermissionOwner");
9350        synchronized(this) {
9351            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9352            return owner.getExternalTokenLocked();
9353        }
9354    }
9355
9356    @Override
9357    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9358        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9359        synchronized(this) {
9360            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9361            if (r == null) {
9362                throw new IllegalArgumentException("Activity does not exist; token="
9363                        + activityToken);
9364            }
9365            return r.getUriPermissionsLocked().getExternalTokenLocked();
9366        }
9367    }
9368    /**
9369     * @param uri This uri must NOT contain an embedded userId.
9370     * @param sourceUserId The userId in which the uri is to be resolved.
9371     * @param targetUserId The userId of the app that receives the grant.
9372     */
9373    @Override
9374    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9375            final int modeFlags, int sourceUserId, int targetUserId) {
9376        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9377                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9378                "grantUriPermissionFromOwner", null);
9379        synchronized(this) {
9380            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9381            if (owner == null) {
9382                throw new IllegalArgumentException("Unknown owner: " + token);
9383            }
9384            if (fromUid != Binder.getCallingUid()) {
9385                if (Binder.getCallingUid() != myUid()) {
9386                    // Only system code can grant URI permissions on behalf
9387                    // of other users.
9388                    throw new SecurityException("nice try");
9389                }
9390            }
9391            if (targetPkg == null) {
9392                throw new IllegalArgumentException("null target");
9393            }
9394            if (uri == null) {
9395                throw new IllegalArgumentException("null uri");
9396            }
9397
9398            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9399                    modeFlags, owner, targetUserId);
9400        }
9401    }
9402
9403    /**
9404     * @param uri This uri must NOT contain an embedded userId.
9405     * @param userId The userId in which the uri is to be resolved.
9406     */
9407    @Override
9408    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9409        synchronized(this) {
9410            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9411            if (owner == null) {
9412                throw new IllegalArgumentException("Unknown owner: " + token);
9413            }
9414
9415            if (uri == null) {
9416                owner.removeUriPermissionsLocked(mode);
9417            } else {
9418                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9419                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9420            }
9421        }
9422    }
9423
9424    private void schedulePersistUriGrants() {
9425        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9426            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9427                    10 * DateUtils.SECOND_IN_MILLIS);
9428        }
9429    }
9430
9431    private void writeGrantedUriPermissions() {
9432        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9433
9434        // Snapshot permissions so we can persist without lock
9435        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9436        synchronized (this) {
9437            final int size = mGrantedUriPermissions.size();
9438            for (int i = 0; i < size; i++) {
9439                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9440                for (UriPermission perm : perms.values()) {
9441                    if (perm.persistedModeFlags != 0) {
9442                        persist.add(perm.snapshot());
9443                    }
9444                }
9445            }
9446        }
9447
9448        FileOutputStream fos = null;
9449        try {
9450            fos = mGrantFile.startWrite();
9451
9452            XmlSerializer out = new FastXmlSerializer();
9453            out.setOutput(fos, StandardCharsets.UTF_8.name());
9454            out.startDocument(null, true);
9455            out.startTag(null, TAG_URI_GRANTS);
9456            for (UriPermission.Snapshot perm : persist) {
9457                out.startTag(null, TAG_URI_GRANT);
9458                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9459                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9460                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9461                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9462                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9463                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9464                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9465                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9466                out.endTag(null, TAG_URI_GRANT);
9467            }
9468            out.endTag(null, TAG_URI_GRANTS);
9469            out.endDocument();
9470
9471            mGrantFile.finishWrite(fos);
9472        } catch (IOException e) {
9473            if (fos != null) {
9474                mGrantFile.failWrite(fos);
9475            }
9476        }
9477    }
9478
9479    private void readGrantedUriPermissionsLocked() {
9480        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9481
9482        final long now = System.currentTimeMillis();
9483
9484        FileInputStream fis = null;
9485        try {
9486            fis = mGrantFile.openRead();
9487            final XmlPullParser in = Xml.newPullParser();
9488            in.setInput(fis, StandardCharsets.UTF_8.name());
9489
9490            int type;
9491            while ((type = in.next()) != END_DOCUMENT) {
9492                final String tag = in.getName();
9493                if (type == START_TAG) {
9494                    if (TAG_URI_GRANT.equals(tag)) {
9495                        final int sourceUserId;
9496                        final int targetUserId;
9497                        final int userHandle = readIntAttribute(in,
9498                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9499                        if (userHandle != UserHandle.USER_NULL) {
9500                            // For backwards compatibility.
9501                            sourceUserId = userHandle;
9502                            targetUserId = userHandle;
9503                        } else {
9504                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9505                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9506                        }
9507                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9508                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9509                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9510                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9511                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9512                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9513
9514                        // Sanity check that provider still belongs to source package
9515                        // Both direct boot aware and unaware packages are fine as we
9516                        // will do filtering at query time to avoid multiple parsing.
9517                        final ProviderInfo pi = getProviderInfoLocked(
9518                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9519                                        | MATCH_DIRECT_BOOT_UNAWARE);
9520                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9521                            int targetUid = -1;
9522                            try {
9523                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9524                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9525                            } catch (RemoteException e) {
9526                            }
9527                            if (targetUid != -1) {
9528                                final UriPermission perm = findOrCreateUriPermissionLocked(
9529                                        sourcePkg, targetPkg, targetUid,
9530                                        new GrantUri(sourceUserId, uri, prefix));
9531                                perm.initPersistedModes(modeFlags, createdTime);
9532                            }
9533                        } else {
9534                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9535                                    + " but instead found " + pi);
9536                        }
9537                    }
9538                }
9539            }
9540        } catch (FileNotFoundException e) {
9541            // Missing grants is okay
9542        } catch (IOException e) {
9543            Slog.wtf(TAG, "Failed reading Uri grants", e);
9544        } catch (XmlPullParserException e) {
9545            Slog.wtf(TAG, "Failed reading Uri grants", e);
9546        } finally {
9547            IoUtils.closeQuietly(fis);
9548        }
9549    }
9550
9551    /**
9552     * @param uri This uri must NOT contain an embedded userId.
9553     * @param userId The userId in which the uri is to be resolved.
9554     */
9555    @Override
9556    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9557        enforceNotIsolatedCaller("takePersistableUriPermission");
9558
9559        Preconditions.checkFlagsArgument(modeFlags,
9560                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9561
9562        synchronized (this) {
9563            final int callingUid = Binder.getCallingUid();
9564            boolean persistChanged = false;
9565            GrantUri grantUri = new GrantUri(userId, uri, false);
9566
9567            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9568                    new GrantUri(userId, uri, false));
9569            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9570                    new GrantUri(userId, uri, true));
9571
9572            final boolean exactValid = (exactPerm != null)
9573                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9574            final boolean prefixValid = (prefixPerm != null)
9575                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9576
9577            if (!(exactValid || prefixValid)) {
9578                throw new SecurityException("No persistable permission grants found for UID "
9579                        + callingUid + " and Uri " + grantUri.toSafeString());
9580            }
9581
9582            if (exactValid) {
9583                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9584            }
9585            if (prefixValid) {
9586                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9587            }
9588
9589            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9590
9591            if (persistChanged) {
9592                schedulePersistUriGrants();
9593            }
9594        }
9595    }
9596
9597    /**
9598     * @param uri This uri must NOT contain an embedded userId.
9599     * @param userId The userId in which the uri is to be resolved.
9600     */
9601    @Override
9602    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9603        enforceNotIsolatedCaller("releasePersistableUriPermission");
9604
9605        Preconditions.checkFlagsArgument(modeFlags,
9606                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9607
9608        synchronized (this) {
9609            final int callingUid = Binder.getCallingUid();
9610            boolean persistChanged = false;
9611
9612            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9613                    new GrantUri(userId, uri, false));
9614            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9615                    new GrantUri(userId, uri, true));
9616            if (exactPerm == null && prefixPerm == null) {
9617                throw new SecurityException("No permission grants found for UID " + callingUid
9618                        + " and Uri " + uri.toSafeString());
9619            }
9620
9621            if (exactPerm != null) {
9622                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9623                removeUriPermissionIfNeededLocked(exactPerm);
9624            }
9625            if (prefixPerm != null) {
9626                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9627                removeUriPermissionIfNeededLocked(prefixPerm);
9628            }
9629
9630            if (persistChanged) {
9631                schedulePersistUriGrants();
9632            }
9633        }
9634    }
9635
9636    /**
9637     * Prune any older {@link UriPermission} for the given UID until outstanding
9638     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9639     *
9640     * @return if any mutations occured that require persisting.
9641     */
9642    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9643        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9644        if (perms == null) return false;
9645        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9646
9647        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9648        for (UriPermission perm : perms.values()) {
9649            if (perm.persistedModeFlags != 0) {
9650                persisted.add(perm);
9651            }
9652        }
9653
9654        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9655        if (trimCount <= 0) return false;
9656
9657        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9658        for (int i = 0; i < trimCount; i++) {
9659            final UriPermission perm = persisted.get(i);
9660
9661            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9662                    "Trimming grant created at " + perm.persistedCreateTime);
9663
9664            perm.releasePersistableModes(~0);
9665            removeUriPermissionIfNeededLocked(perm);
9666        }
9667
9668        return true;
9669    }
9670
9671    @Override
9672    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9673            String packageName, boolean incoming) {
9674        enforceNotIsolatedCaller("getPersistedUriPermissions");
9675        Preconditions.checkNotNull(packageName, "packageName");
9676
9677        final int callingUid = Binder.getCallingUid();
9678        final int callingUserId = UserHandle.getUserId(callingUid);
9679        final IPackageManager pm = AppGlobals.getPackageManager();
9680        try {
9681            final int packageUid = pm.getPackageUid(packageName,
9682                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9683            if (packageUid != callingUid) {
9684                throw new SecurityException(
9685                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9686            }
9687        } catch (RemoteException e) {
9688            throw new SecurityException("Failed to verify package name ownership");
9689        }
9690
9691        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9692        synchronized (this) {
9693            if (incoming) {
9694                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9695                        callingUid);
9696                if (perms == null) {
9697                    Slog.w(TAG, "No permission grants found for " + packageName);
9698                } else {
9699                    for (UriPermission perm : perms.values()) {
9700                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9701                            result.add(perm.buildPersistedPublicApiObject());
9702                        }
9703                    }
9704                }
9705            } else {
9706                final int size = mGrantedUriPermissions.size();
9707                for (int i = 0; i < size; i++) {
9708                    final ArrayMap<GrantUri, UriPermission> perms =
9709                            mGrantedUriPermissions.valueAt(i);
9710                    for (UriPermission perm : perms.values()) {
9711                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9712                            result.add(perm.buildPersistedPublicApiObject());
9713                        }
9714                    }
9715                }
9716            }
9717        }
9718        return new ParceledListSlice<android.content.UriPermission>(result);
9719    }
9720
9721    @Override
9722    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9723            String packageName, int userId) {
9724        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9725                "getGrantedUriPermissions");
9726
9727        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9728        synchronized (this) {
9729            final int size = mGrantedUriPermissions.size();
9730            for (int i = 0; i < size; i++) {
9731                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9732                for (UriPermission perm : perms.values()) {
9733                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9734                            && perm.persistedModeFlags != 0) {
9735                        result.add(perm.buildPersistedPublicApiObject());
9736                    }
9737                }
9738            }
9739        }
9740        return new ParceledListSlice<android.content.UriPermission>(result);
9741    }
9742
9743    @Override
9744    public void clearGrantedUriPermissions(String packageName, int userId) {
9745        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9746                "clearGrantedUriPermissions");
9747        removeUriPermissionsForPackageLocked(packageName, userId, true);
9748    }
9749
9750    @Override
9751    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9752        synchronized (this) {
9753            ProcessRecord app =
9754                who != null ? getRecordForAppLocked(who) : null;
9755            if (app == null) return;
9756
9757            Message msg = Message.obtain();
9758            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9759            msg.obj = app;
9760            msg.arg1 = waiting ? 1 : 0;
9761            mUiHandler.sendMessage(msg);
9762        }
9763    }
9764
9765    @Override
9766    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9767        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9768        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9769        outInfo.availMem = getFreeMemory();
9770        outInfo.totalMem = getTotalMemory();
9771        outInfo.threshold = homeAppMem;
9772        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9773        outInfo.hiddenAppThreshold = cachedAppMem;
9774        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9775                ProcessList.SERVICE_ADJ);
9776        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9777                ProcessList.VISIBLE_APP_ADJ);
9778        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9779                ProcessList.FOREGROUND_APP_ADJ);
9780    }
9781
9782    // =========================================================
9783    // TASK MANAGEMENT
9784    // =========================================================
9785
9786    @Override
9787    public List<IBinder> getAppTasks(String callingPackage) {
9788        int callingUid = Binder.getCallingUid();
9789        long ident = Binder.clearCallingIdentity();
9790
9791        synchronized(this) {
9792            ArrayList<IBinder> list = new ArrayList<IBinder>();
9793            try {
9794                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9795
9796                final int N = mRecentTasks.size();
9797                for (int i = 0; i < N; i++) {
9798                    TaskRecord tr = mRecentTasks.get(i);
9799                    // Skip tasks that do not match the caller.  We don't need to verify
9800                    // callingPackage, because we are also limiting to callingUid and know
9801                    // that will limit to the correct security sandbox.
9802                    if (tr.effectiveUid != callingUid) {
9803                        continue;
9804                    }
9805                    Intent intent = tr.getBaseIntent();
9806                    if (intent == null ||
9807                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9808                        continue;
9809                    }
9810                    ActivityManager.RecentTaskInfo taskInfo =
9811                            createRecentTaskInfoFromTaskRecord(tr);
9812                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9813                    list.add(taskImpl.asBinder());
9814                }
9815            } finally {
9816                Binder.restoreCallingIdentity(ident);
9817            }
9818            return list;
9819        }
9820    }
9821
9822    @Override
9823    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9824        final int callingUid = Binder.getCallingUid();
9825        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9826
9827        synchronized(this) {
9828            if (DEBUG_ALL) Slog.v(
9829                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9830
9831            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9832                    callingUid);
9833
9834            // TODO: Improve with MRU list from all ActivityStacks.
9835            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9836        }
9837
9838        return list;
9839    }
9840
9841    /**
9842     * Creates a new RecentTaskInfo from a TaskRecord.
9843     */
9844    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9845        // Update the task description to reflect any changes in the task stack
9846        tr.updateTaskDescription();
9847
9848        // Compose the recent task info
9849        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9850        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9851        rti.persistentId = tr.taskId;
9852        rti.baseIntent = new Intent(tr.getBaseIntent());
9853        rti.origActivity = tr.origActivity;
9854        rti.realActivity = tr.realActivity;
9855        rti.description = tr.lastDescription;
9856        rti.stackId = tr.getStackId();
9857        rti.userId = tr.userId;
9858        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9859        rti.firstActiveTime = tr.firstActiveTime;
9860        rti.lastActiveTime = tr.lastActiveTime;
9861        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9862        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9863        rti.numActivities = 0;
9864        if (tr.mBounds != null) {
9865            rti.bounds = new Rect(tr.mBounds);
9866        }
9867        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9868        rti.resizeMode = tr.mResizeMode;
9869
9870        ActivityRecord base = null;
9871        ActivityRecord top = null;
9872        ActivityRecord tmp;
9873
9874        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9875            tmp = tr.mActivities.get(i);
9876            if (tmp.finishing) {
9877                continue;
9878            }
9879            base = tmp;
9880            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9881                top = base;
9882            }
9883            rti.numActivities++;
9884        }
9885
9886        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9887        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9888
9889        return rti;
9890    }
9891
9892    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9893        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9894                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9895        if (!allowed) {
9896            if (checkPermission(android.Manifest.permission.GET_TASKS,
9897                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9898                // Temporary compatibility: some existing apps on the system image may
9899                // still be requesting the old permission and not switched to the new
9900                // one; if so, we'll still allow them full access.  This means we need
9901                // to see if they are holding the old permission and are a system app.
9902                try {
9903                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9904                        allowed = true;
9905                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9906                                + " is using old GET_TASKS but privileged; allowing");
9907                    }
9908                } catch (RemoteException e) {
9909                }
9910            }
9911        }
9912        if (!allowed) {
9913            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9914                    + " does not hold REAL_GET_TASKS; limiting output");
9915        }
9916        return allowed;
9917    }
9918
9919    @Override
9920    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9921            int userId) {
9922        final int callingUid = Binder.getCallingUid();
9923        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9924                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9925
9926        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9927        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9928        synchronized (this) {
9929            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9930                    callingUid);
9931            final boolean detailed = checkCallingPermission(
9932                    android.Manifest.permission.GET_DETAILED_TASKS)
9933                    == PackageManager.PERMISSION_GRANTED;
9934
9935            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9936                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9937                return ParceledListSlice.emptyList();
9938            }
9939            mRecentTasks.loadUserRecentsLocked(userId);
9940
9941            final int recentsCount = mRecentTasks.size();
9942            ArrayList<ActivityManager.RecentTaskInfo> res =
9943                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9944
9945            final Set<Integer> includedUsers;
9946            if (includeProfiles) {
9947                includedUsers = mUserController.getProfileIds(userId);
9948            } else {
9949                includedUsers = new HashSet<>();
9950            }
9951            includedUsers.add(Integer.valueOf(userId));
9952
9953            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9954                TaskRecord tr = mRecentTasks.get(i);
9955                // Only add calling user or related users recent tasks
9956                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9957                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9958                    continue;
9959                }
9960
9961                if (tr.realActivitySuspended) {
9962                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9963                    continue;
9964                }
9965
9966                // Return the entry if desired by the caller.  We always return
9967                // the first entry, because callers always expect this to be the
9968                // foreground app.  We may filter others if the caller has
9969                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9970                // we should exclude the entry.
9971
9972                if (i == 0
9973                        || withExcluded
9974                        || (tr.intent == null)
9975                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9976                                == 0)) {
9977                    if (!allowed) {
9978                        // If the caller doesn't have the GET_TASKS permission, then only
9979                        // allow them to see a small subset of tasks -- their own and home.
9980                        if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) {
9981                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9982                            continue;
9983                        }
9984                    }
9985                    final ActivityStack stack = tr.getStack();
9986                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9987                        if (stack != null && stack.isHomeOrRecentsStack()) {
9988                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9989                                    "Skipping, home or recents stack task: " + tr);
9990                            continue;
9991                        }
9992                    }
9993                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9994                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9995                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9996                                    "Skipping, top task in docked stack: " + tr);
9997                            continue;
9998                        }
9999                    }
10000                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10001                        if (stack != null && stack.isPinnedStack()) {
10002                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10003                                    "Skipping, pinned stack task: " + tr);
10004                            continue;
10005                        }
10006                    }
10007                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10008                        // Don't include auto remove tasks that are finished or finishing.
10009                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10010                                "Skipping, auto-remove without activity: " + tr);
10011                        continue;
10012                    }
10013                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10014                            && !tr.isAvailable) {
10015                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10016                                "Skipping, unavail real act: " + tr);
10017                        continue;
10018                    }
10019
10020                    if (!tr.mUserSetupComplete) {
10021                        // Don't include task launched while user is not done setting-up.
10022                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10023                                "Skipping, user setup not complete: " + tr);
10024                        continue;
10025                    }
10026
10027                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10028                    if (!detailed) {
10029                        rti.baseIntent.replaceExtras((Bundle)null);
10030                    }
10031
10032                    res.add(rti);
10033                    maxNum--;
10034                }
10035            }
10036            return new ParceledListSlice<>(res);
10037        }
10038    }
10039
10040    @Override
10041    public ActivityManager.TaskDescription getTaskDescription(int id) {
10042        synchronized (this) {
10043            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10044                    "getTaskDescription()");
10045            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10046                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10047            if (tr != null) {
10048                return tr.lastTaskDescription;
10049            }
10050        }
10051        return null;
10052    }
10053
10054    @Override
10055    public int addAppTask(IBinder activityToken, Intent intent,
10056            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10057        final int callingUid = Binder.getCallingUid();
10058        final long callingIdent = Binder.clearCallingIdentity();
10059
10060        try {
10061            synchronized (this) {
10062                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10063                if (r == null) {
10064                    throw new IllegalArgumentException("Activity does not exist; token="
10065                            + activityToken);
10066                }
10067                ComponentName comp = intent.getComponent();
10068                if (comp == null) {
10069                    throw new IllegalArgumentException("Intent " + intent
10070                            + " must specify explicit component");
10071                }
10072                if (thumbnail.getWidth() != mThumbnailWidth
10073                        || thumbnail.getHeight() != mThumbnailHeight) {
10074                    throw new IllegalArgumentException("Bad thumbnail size: got "
10075                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10076                            + mThumbnailWidth + "x" + mThumbnailHeight);
10077                }
10078                if (intent.getSelector() != null) {
10079                    intent.setSelector(null);
10080                }
10081                if (intent.getSourceBounds() != null) {
10082                    intent.setSourceBounds(null);
10083                }
10084                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10085                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10086                        // The caller has added this as an auto-remove task...  that makes no
10087                        // sense, so turn off auto-remove.
10088                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10089                    }
10090                }
10091                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10092                    mLastAddedTaskActivity = null;
10093                }
10094                ActivityInfo ainfo = mLastAddedTaskActivity;
10095                if (ainfo == null) {
10096                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10097                            comp, 0, UserHandle.getUserId(callingUid));
10098                    if (ainfo.applicationInfo.uid != callingUid) {
10099                        throw new SecurityException(
10100                                "Can't add task for another application: target uid="
10101                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10102                    }
10103                }
10104
10105                TaskRecord task = new TaskRecord(this,
10106                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10107                        ainfo, intent, description);
10108
10109                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10110                if (trimIdx >= 0) {
10111                    // If this would have caused a trim, then we'll abort because that
10112                    // means it would be added at the end of the list but then just removed.
10113                    return INVALID_TASK_ID;
10114                }
10115
10116                final int N = mRecentTasks.size();
10117                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10118                    final TaskRecord tr = mRecentTasks.remove(N - 1);
10119                    tr.removedFromRecents();
10120                }
10121
10122                task.inRecents = true;
10123                mRecentTasks.add(task);
10124                r.getStack().addTask(task, false, "addAppTask");
10125
10126                // TODO: Send the thumbnail to WM to store it.
10127
10128                return task.taskId;
10129            }
10130        } finally {
10131            Binder.restoreCallingIdentity(callingIdent);
10132        }
10133    }
10134
10135    @Override
10136    public Point getAppTaskThumbnailSize() {
10137        synchronized (this) {
10138            return new Point(mThumbnailWidth,  mThumbnailHeight);
10139        }
10140    }
10141
10142    @Override
10143    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10144        synchronized (this) {
10145            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10146            if (r != null) {
10147                r.setTaskDescription(td);
10148                final TaskRecord task = r.getTask();
10149                task.updateTaskDescription();
10150                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10151            }
10152        }
10153    }
10154
10155    @Override
10156    public void setTaskResizeable(int taskId, int resizeableMode) {
10157        synchronized (this) {
10158            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10159                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10160            if (task == null) {
10161                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10162                return;
10163            }
10164            task.setResizeMode(resizeableMode);
10165        }
10166    }
10167
10168    @Override
10169    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10170        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10171        long ident = Binder.clearCallingIdentity();
10172        try {
10173            synchronized (this) {
10174                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10175                if (task == null) {
10176                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10177                    return;
10178                }
10179                // Place the task in the right stack if it isn't there already based on
10180                // the requested bounds.
10181                // The stack transition logic is:
10182                // - a null bounds on a freeform task moves that task to fullscreen
10183                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10184                //   that task to freeform
10185                // - otherwise the task is not moved
10186                int stackId = task.getStackId();
10187                if (!task.getWindowConfiguration().canResizeTask()) {
10188                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10189                }
10190                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10191                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10192                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10193                    stackId = FREEFORM_WORKSPACE_STACK_ID;
10194                }
10195
10196                // Reparent the task to the right stack if necessary
10197                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10198                if (stackId != task.getStackId()) {
10199                    // Defer resume until the task is resized below
10200                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10201                            DEFER_RESUME, "resizeTask");
10202                    preserveWindow = false;
10203                }
10204
10205                // After reparenting (which only resizes the task to the stack bounds), resize the
10206                // task to the actual bounds provided
10207                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10208            }
10209        } finally {
10210            Binder.restoreCallingIdentity(ident);
10211        }
10212    }
10213
10214    @Override
10215    public Rect getTaskBounds(int taskId) {
10216        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10217        long ident = Binder.clearCallingIdentity();
10218        Rect rect = new Rect();
10219        try {
10220            synchronized (this) {
10221                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10222                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10223                if (task == null) {
10224                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10225                    return rect;
10226                }
10227                if (task.getStack() != null) {
10228                    // Return the bounds from window manager since it will be adjusted for various
10229                    // things like the presense of a docked stack for tasks that aren't resizeable.
10230                    task.getWindowContainerBounds(rect);
10231                } else {
10232                    // Task isn't in window manager yet since it isn't associated with a stack.
10233                    // Return the persist value from activity manager
10234                    if (task.mBounds != null) {
10235                        rect.set(task.mBounds);
10236                    } else if (task.mLastNonFullscreenBounds != null) {
10237                        rect.set(task.mLastNonFullscreenBounds);
10238                    }
10239                }
10240            }
10241        } finally {
10242            Binder.restoreCallingIdentity(ident);
10243        }
10244        return rect;
10245    }
10246
10247    @Override
10248    public void cancelTaskWindowTransition(int taskId) {
10249        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10250        final long ident = Binder.clearCallingIdentity();
10251        try {
10252            synchronized (this) {
10253                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10254                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10255                if (task == null) {
10256                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10257                    return;
10258                }
10259                task.cancelWindowTransition();
10260            }
10261        } finally {
10262            Binder.restoreCallingIdentity(ident);
10263        }
10264    }
10265
10266    @Override
10267    public void cancelTaskThumbnailTransition(int taskId) {
10268        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10269        final long ident = Binder.clearCallingIdentity();
10270        try {
10271            synchronized (this) {
10272                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10273                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10274                if (task == null) {
10275                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10276                    return;
10277                }
10278                task.cancelThumbnailTransition();
10279            }
10280        } finally {
10281            Binder.restoreCallingIdentity(ident);
10282        }
10283    }
10284
10285    @Override
10286    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10287        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10288        final long ident = Binder.clearCallingIdentity();
10289        try {
10290            final TaskRecord task;
10291            synchronized (this) {
10292                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10293                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10294                if (task == null) {
10295                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10296                    return null;
10297                }
10298            }
10299            // Don't call this while holding the lock as this operation might hit the disk.
10300            return task.getSnapshot(reducedResolution);
10301        } finally {
10302            Binder.restoreCallingIdentity(ident);
10303        }
10304    }
10305
10306    @Override
10307    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10308        if (userId != UserHandle.getCallingUserId()) {
10309            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10310                    "getTaskDescriptionIcon");
10311        }
10312        final File passedIconFile = new File(filePath);
10313        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10314                passedIconFile.getName());
10315        if (!legitIconFile.getPath().equals(filePath)
10316                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10317            throw new IllegalArgumentException("Bad file path: " + filePath
10318                    + " passed for userId " + userId);
10319        }
10320        return mRecentTasks.getTaskDescriptionIcon(filePath);
10321    }
10322
10323    @Override
10324    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10325            throws RemoteException {
10326        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10327        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10328                activityOptions.getCustomInPlaceResId() == 0) {
10329            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10330                    "with valid animation");
10331        }
10332        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10333        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10334                activityOptions.getCustomInPlaceResId());
10335        mWindowManager.executeAppTransition();
10336    }
10337
10338    private void removeTasksByPackageNameLocked(String packageName, int userId) {
10339        // Remove all tasks with activities in the specified package from the list of recent tasks
10340        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10341            TaskRecord tr = mRecentTasks.get(i);
10342            if (tr.userId != userId) continue;
10343
10344            ComponentName cn = tr.intent.getComponent();
10345            if (cn != null && cn.getPackageName().equals(packageName)) {
10346                // If the package name matches, remove the task.
10347                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10348            }
10349        }
10350    }
10351
10352    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10353            int userId) {
10354
10355        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10356            TaskRecord tr = mRecentTasks.get(i);
10357            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10358                continue;
10359            }
10360
10361            ComponentName cn = tr.intent.getComponent();
10362            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10363                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10364            if (sameComponent) {
10365                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10366            }
10367        }
10368    }
10369
10370    @Override
10371    public void removeStack(int stackId) {
10372        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10373        if (StackId.isHomeOrRecentsStack(stackId)) {
10374            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10375        }
10376
10377        synchronized (this) {
10378            final long ident = Binder.clearCallingIdentity();
10379            try {
10380                mStackSupervisor.removeStackLocked(stackId);
10381            } finally {
10382                Binder.restoreCallingIdentity(ident);
10383            }
10384        }
10385    }
10386
10387    @Override
10388    public void moveStackToDisplay(int stackId, int displayId) {
10389        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10390
10391        synchronized (this) {
10392            final long ident = Binder.clearCallingIdentity();
10393            try {
10394                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10395                        + " to displayId=" + displayId);
10396                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10397            } finally {
10398                Binder.restoreCallingIdentity(ident);
10399            }
10400        }
10401    }
10402
10403    @Override
10404    public boolean removeTask(int taskId) {
10405        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10406        synchronized (this) {
10407            final long ident = Binder.clearCallingIdentity();
10408            try {
10409                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10410            } finally {
10411                Binder.restoreCallingIdentity(ident);
10412            }
10413        }
10414    }
10415
10416    /**
10417     * TODO: Add mController hook
10418     */
10419    @Override
10420    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10421        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10422
10423        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10424        synchronized(this) {
10425            moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10426        }
10427    }
10428
10429    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10430        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10431
10432        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10433                Binder.getCallingUid(), -1, -1, "Task to front")) {
10434            ActivityOptions.abort(options);
10435            return;
10436        }
10437        final long origId = Binder.clearCallingIdentity();
10438        try {
10439            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10440            if (task == null) {
10441                Slog.d(TAG, "Could not find task for id: "+ taskId);
10442                return;
10443            }
10444            if (mLockTaskController.isLockTaskModeViolation(task)) {
10445                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10446                return;
10447            }
10448            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10449            if (prev != null) {
10450                task.setTaskToReturnTo(prev);
10451            }
10452            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10453                    false /* forceNonResizable */);
10454
10455            final ActivityRecord topActivity = task.getTopActivity();
10456            if (topActivity != null) {
10457
10458                // We are reshowing a task, use a starting window to hide the initial draw delay
10459                // so the transition can start earlier.
10460                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10461                        true /* taskSwitch */, fromRecents);
10462            }
10463        } finally {
10464            Binder.restoreCallingIdentity(origId);
10465        }
10466        ActivityOptions.abort(options);
10467    }
10468
10469    /**
10470     * Attempts to move a task backwards in z-order (the order of activities within the task is
10471     * unchanged).
10472     *
10473     * There are several possible results of this call:
10474     * - if the task is locked, then we will show the lock toast
10475     * - if there is a task behind the provided task, then that task is made visible and resumed as
10476     *   this task is moved to the back
10477     * - otherwise, if there are no other tasks in the stack:
10478     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10479     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10480     *       (depending on whether it is visible)
10481     *     - otherwise, we simply return home and hide this task
10482     *
10483     * @param token A reference to the activity we wish to move
10484     * @param nonRoot If false then this only works if the activity is the root
10485     *                of a task; if true it will work for any activity in a task.
10486     * @return Returns true if the move completed, false if not.
10487     */
10488    @Override
10489    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10490        enforceNotIsolatedCaller("moveActivityTaskToBack");
10491        synchronized(this) {
10492            final long origId = Binder.clearCallingIdentity();
10493            try {
10494                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10495                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10496                if (task != null) {
10497                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10498                }
10499            } finally {
10500                Binder.restoreCallingIdentity(origId);
10501            }
10502        }
10503        return false;
10504    }
10505
10506    @Override
10507    public void moveTaskBackwards(int task) {
10508        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10509                "moveTaskBackwards()");
10510
10511        synchronized(this) {
10512            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10513                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10514                return;
10515            }
10516            final long origId = Binder.clearCallingIdentity();
10517            moveTaskBackwardsLocked(task);
10518            Binder.restoreCallingIdentity(origId);
10519        }
10520    }
10521
10522    private final void moveTaskBackwardsLocked(int task) {
10523        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10524    }
10525
10526    @Override
10527    public int createStackOnDisplay(int displayId) throws RemoteException {
10528        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10529        synchronized (this) {
10530            final int stackId = mStackSupervisor.getNextStackId();
10531            final ActivityStack stack =
10532                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10533            if (stack == null) {
10534                return INVALID_STACK_ID;
10535            }
10536            return stack.mStackId;
10537        }
10538    }
10539
10540    @Override
10541    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10542        synchronized (this) {
10543            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10544            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10545                return stack.mDisplayId;
10546            }
10547            return DEFAULT_DISPLAY;
10548        }
10549    }
10550
10551    @Override
10552    public void exitFreeformMode(IBinder token) throws RemoteException {
10553        synchronized (this) {
10554            long ident = Binder.clearCallingIdentity();
10555            try {
10556                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10557                if (r == null) {
10558                    throw new IllegalArgumentException(
10559                            "exitFreeformMode: No activity record matching token=" + token);
10560                }
10561
10562                final ActivityStack stack = r.getStack();
10563                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10564                    throw new IllegalStateException(
10565                            "exitFreeformMode: You can only go fullscreen from freeform.");
10566                }
10567
10568                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10569                r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10570                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10571            } finally {
10572                Binder.restoreCallingIdentity(ident);
10573            }
10574        }
10575    }
10576
10577    @Override
10578    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10579        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10580        if (StackId.isHomeOrRecentsStack(stackId)) {
10581            throw new IllegalArgumentException(
10582                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10583        }
10584        synchronized (this) {
10585            long ident = Binder.clearCallingIdentity();
10586            try {
10587                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10588                if (task == null) {
10589                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10590                    return;
10591                }
10592
10593                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10594                        + " to stackId=" + stackId + " toTop=" + toTop);
10595                if (stackId == DOCKED_STACK_ID) {
10596                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10597                            null /* initialBounds */);
10598                }
10599                task.reparent(stackId, toTop,
10600                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10601            } finally {
10602                Binder.restoreCallingIdentity(ident);
10603            }
10604        }
10605    }
10606
10607    @Override
10608    public void swapDockedAndFullscreenStack() throws RemoteException {
10609        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10610        synchronized (this) {
10611            long ident = Binder.clearCallingIdentity();
10612            try {
10613                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10614                        FULLSCREEN_WORKSPACE_STACK_ID);
10615                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10616                        : null;
10617                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10618                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10619                        : null;
10620                if (topTask == null || tasks == null || tasks.size() == 0) {
10621                    Slog.w(TAG,
10622                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10623                    return;
10624                }
10625
10626                // TODO: App transition
10627                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10628
10629                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10630                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10631                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10632                final int size = tasks.size();
10633                for (int i = 0; i < size; i++) {
10634                    final int id = tasks.get(i).taskId;
10635                    if (id == topTask.taskId) {
10636                        continue;
10637                    }
10638
10639                    // Defer the resume until after all the tasks have been moved
10640                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10641                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10642                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10643                }
10644
10645                // Because we deferred the resume to avoid conflicts with stack switches while
10646                // resuming, we need to do it after all the tasks are moved.
10647                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10648                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10649
10650                mWindowManager.executeAppTransition();
10651            } finally {
10652                Binder.restoreCallingIdentity(ident);
10653            }
10654        }
10655    }
10656
10657    /**
10658     * Moves the input task to the docked stack.
10659     *
10660     * @param taskId Id of task to move.
10661     * @param createMode The mode the docked stack should be created in if it doesn't exist
10662     *                   already. See
10663     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10664     *                   and
10665     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10666     * @param toTop If the task and stack should be moved to the top.
10667     * @param animate Whether we should play an animation for the moving the task
10668     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10669     *                      docked stack. Pass {@code null} to use default bounds.
10670     */
10671    @Override
10672    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10673            Rect initialBounds) {
10674        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10675        synchronized (this) {
10676            long ident = Binder.clearCallingIdentity();
10677            try {
10678                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10679                if (task == null) {
10680                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10681                    return false;
10682                }
10683
10684                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10685                        + " to createMode=" + createMode + " toTop=" + toTop);
10686                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10687
10688                // Defer resuming until we move the home stack to the front below
10689                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10690                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10691                        "moveTaskToDockedStack");
10692                if (moved) {
10693                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10694                }
10695                return moved;
10696            } finally {
10697                Binder.restoreCallingIdentity(ident);
10698            }
10699        }
10700    }
10701
10702    /**
10703     * Moves the top activity in the input stackId to the pinned stack.
10704     *
10705     * @param stackId Id of stack to move the top activity to pinned stack.
10706     * @param bounds Bounds to use for pinned stack.
10707     *
10708     * @return True if the top activity of the input stack was successfully moved to the pinned
10709     *          stack.
10710     */
10711    @Override
10712    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10713        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10714        synchronized (this) {
10715            if (!mSupportsPictureInPicture) {
10716                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10717                        + "Device doesn't support picture-in-picture mode");
10718            }
10719
10720            long ident = Binder.clearCallingIdentity();
10721            try {
10722                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10723            } finally {
10724                Binder.restoreCallingIdentity(ident);
10725            }
10726        }
10727    }
10728
10729    @Override
10730    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10731            boolean preserveWindows, boolean animate, int animationDuration) {
10732        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10733        long ident = Binder.clearCallingIdentity();
10734        try {
10735            synchronized (this) {
10736                if (animate) {
10737                    if (stackId == PINNED_STACK_ID) {
10738                        final PinnedActivityStack pinnedStack =
10739                                mStackSupervisor.getStack(PINNED_STACK_ID);
10740                        if (pinnedStack != null) {
10741                            pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10742                                    destBounds, animationDuration, false /* fromFullscreen */);
10743                        }
10744                    } else {
10745                        throw new IllegalArgumentException("Stack: " + stackId
10746                                + " doesn't support animated resize.");
10747                    }
10748                } else {
10749                    mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10750                            null /* tempTaskInsetBounds */, preserveWindows,
10751                            allowResizeInDockedMode, !DEFER_RESUME);
10752                }
10753            }
10754        } finally {
10755            Binder.restoreCallingIdentity(ident);
10756        }
10757    }
10758
10759    @Override
10760    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10761            Rect tempDockedTaskInsetBounds,
10762            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10763        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10764                "resizeDockedStack()");
10765        long ident = Binder.clearCallingIdentity();
10766        try {
10767            synchronized (this) {
10768                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10769                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10770                        PRESERVE_WINDOWS);
10771            }
10772        } finally {
10773            Binder.restoreCallingIdentity(ident);
10774        }
10775    }
10776
10777    @Override
10778    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10779        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10780                "resizePinnedStack()");
10781        final long ident = Binder.clearCallingIdentity();
10782        try {
10783            synchronized (this) {
10784                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10785            }
10786        } finally {
10787            Binder.restoreCallingIdentity(ident);
10788        }
10789    }
10790
10791    /**
10792     * Try to place task to provided position. The final position might be different depending on
10793     * current user and stacks state. The task will be moved to target stack if it's currently in
10794     * different stack.
10795     */
10796    @Override
10797    public void positionTaskInStack(int taskId, int stackId, int position) {
10798        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10799        if (StackId.isHomeOrRecentsStack(stackId)) {
10800            throw new IllegalArgumentException(
10801                    "positionTaskInStack: Attempt to change the position of task "
10802                    + taskId + " in/to home/recents stack");
10803        }
10804        synchronized (this) {
10805            long ident = Binder.clearCallingIdentity();
10806            try {
10807                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10808                        + taskId + " in stackId=" + stackId + " at position=" + position);
10809                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10810                if (task == null) {
10811                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10812                            + taskId);
10813                }
10814
10815                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10816                        !ON_TOP);
10817
10818                // TODO: Have the callers of this API call a separate reparent method if that is
10819                // what they intended to do vs. having this method also do reparenting.
10820                if (task.getStack() == stack) {
10821                    // Change position in current stack.
10822                    stack.positionChildAt(task, position);
10823                } else {
10824                    // Reparent to new stack.
10825                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10826                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10827                }
10828            } finally {
10829                Binder.restoreCallingIdentity(ident);
10830            }
10831        }
10832    }
10833
10834    @Override
10835    public List<StackInfo> getAllStackInfos() {
10836        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10837        long ident = Binder.clearCallingIdentity();
10838        try {
10839            synchronized (this) {
10840                return mStackSupervisor.getAllStackInfosLocked();
10841            }
10842        } finally {
10843            Binder.restoreCallingIdentity(ident);
10844        }
10845    }
10846
10847    @Override
10848    public StackInfo getStackInfo(int stackId) {
10849        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10850        long ident = Binder.clearCallingIdentity();
10851        try {
10852            synchronized (this) {
10853                return mStackSupervisor.getStackInfoLocked(stackId);
10854            }
10855        } finally {
10856            Binder.restoreCallingIdentity(ident);
10857        }
10858    }
10859
10860    @Override
10861    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10862        synchronized(this) {
10863            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10864        }
10865    }
10866
10867    @Override
10868    public void updateDeviceOwner(String packageName) {
10869        final int callingUid = Binder.getCallingUid();
10870        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10871            throw new SecurityException("updateDeviceOwner called from non-system process");
10872        }
10873        synchronized (this) {
10874            mDeviceOwnerName = packageName;
10875        }
10876    }
10877
10878    @Override
10879    public void updateLockTaskPackages(int userId, String[] packages) {
10880        final int callingUid = Binder.getCallingUid();
10881        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10882            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10883                    "updateLockTaskPackages()");
10884        }
10885        synchronized (this) {
10886            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10887                    Arrays.toString(packages));
10888            mLockTaskController.updateLockTaskPackages(userId, packages);
10889        }
10890    }
10891
10892    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isAppPinning) {
10893        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10894        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10895            return;
10896        }
10897
10898        final ActivityStack stack = mStackSupervisor.getFocusedStack();
10899        if (stack == null || task != stack.topTask()) {
10900            throw new IllegalArgumentException("Invalid task, not in foreground");
10901        }
10902
10903        // When a task is locked, dismiss the pinned stack if it exists
10904        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10905                PINNED_STACK_ID);
10906        if (pinnedStack != null) {
10907            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10908        }
10909
10910        // isAppPinning is used to distinguish between locked and pinned mode, as pinned mode
10911        // is initiated by system after the pinning request was shown and locked mode is initiated
10912        // by an authorized app directly
10913        final int callingUid = Binder.getCallingUid();
10914        long ident = Binder.clearCallingIdentity();
10915        try {
10916            mLockTaskController.startLockTaskMode(task, isAppPinning, callingUid);
10917        } finally {
10918            Binder.restoreCallingIdentity(ident);
10919        }
10920    }
10921
10922    @Override
10923    public void startLockTaskModeByToken(IBinder token) {
10924        synchronized (this) {
10925            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10926            if (r == null) {
10927                return;
10928            }
10929            startLockTaskModeLocked(r.getTask(), false /* not system initiated */);
10930        }
10931    }
10932
10933    @Override
10934    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10935        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10936        // This makes inner call to look as if it was initiated by system.
10937        long ident = Binder.clearCallingIdentity();
10938        try {
10939            synchronized (this) {
10940                startLockTaskModeLocked(mStackSupervisor.anyTaskForIdLocked(taskId),
10941                        true /* system initiated */);
10942            }
10943        } finally {
10944            Binder.restoreCallingIdentity(ident);
10945        }
10946    }
10947
10948    @Override
10949    public void stopLockTaskMode() {
10950        stopLockTaskModeInternal(false /* not system initiated */);
10951    }
10952
10953    /**
10954     * This API should be called by SystemUI only when user perform certain action to dismiss
10955     * lock task mode. We should only dismiss pinned lock task mode in this case.
10956     */
10957    @Override
10958    public void stopSystemLockTaskMode() throws RemoteException {
10959        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
10960        stopLockTaskModeInternal(true /* system initiated */);
10961    }
10962
10963    private void stopLockTaskModeInternal(boolean isSystemRequest) {
10964        final int callingUid = Binder.getCallingUid();
10965        long ident = Binder.clearCallingIdentity();
10966        try {
10967            synchronized (this) {
10968                mLockTaskController.stopLockTaskMode(isSystemRequest, callingUid);
10969            }
10970            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
10971            // task and jumping straight into a call in the case of emergency call back.
10972            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10973            if (tm != null) {
10974                tm.showInCallScreen(false);
10975            }
10976        } finally {
10977            Binder.restoreCallingIdentity(ident);
10978        }
10979    }
10980
10981    @Override
10982    public boolean isInLockTaskMode() {
10983        return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
10984    }
10985
10986    @Override
10987    public int getLockTaskModeState() {
10988        synchronized (this) {
10989            return mLockTaskController.getLockTaskModeState();
10990        }
10991    }
10992
10993    @Override
10994    public void showLockTaskEscapeMessage(IBinder token) {
10995        synchronized (this) {
10996            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10997            if (r == null) {
10998                return;
10999            }
11000            mLockTaskController.showLockTaskToast();
11001        }
11002    }
11003
11004    @Override
11005    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11006            throws RemoteException {
11007        synchronized (this) {
11008            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11009            if (r == null) {
11010                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11011                        + token);
11012                return;
11013            }
11014            final long origId = Binder.clearCallingIdentity();
11015            try {
11016                r.setDisablePreviewScreenshots(disable);
11017            } finally {
11018                Binder.restoreCallingIdentity(origId);
11019            }
11020        }
11021    }
11022
11023    // =========================================================
11024    // CONTENT PROVIDERS
11025    // =========================================================
11026
11027    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11028        List<ProviderInfo> providers = null;
11029        try {
11030            providers = AppGlobals.getPackageManager()
11031                    .queryContentProviders(app.processName, app.uid,
11032                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11033                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11034                    .getList();
11035        } catch (RemoteException ex) {
11036        }
11037        if (DEBUG_MU) Slog.v(TAG_MU,
11038                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11039        int userId = app.userId;
11040        if (providers != null) {
11041            int N = providers.size();
11042            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11043            for (int i=0; i<N; i++) {
11044                // TODO: keep logic in sync with installEncryptionUnawareProviders
11045                ProviderInfo cpi =
11046                    (ProviderInfo)providers.get(i);
11047                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11048                        cpi.name, cpi.flags);
11049                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11050                    // This is a singleton provider, but a user besides the
11051                    // default user is asking to initialize a process it runs
11052                    // in...  well, no, it doesn't actually run in this process,
11053                    // it runs in the process of the default user.  Get rid of it.
11054                    providers.remove(i);
11055                    N--;
11056                    i--;
11057                    continue;
11058                }
11059
11060                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11061                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11062                if (cpr == null) {
11063                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11064                    mProviderMap.putProviderByClass(comp, cpr);
11065                }
11066                if (DEBUG_MU) Slog.v(TAG_MU,
11067                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11068                app.pubProviders.put(cpi.name, cpr);
11069                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11070                    // Don't add this if it is a platform component that is marked
11071                    // to run in multiple processes, because this is actually
11072                    // part of the framework so doesn't make sense to track as a
11073                    // separate apk in the process.
11074                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11075                            mProcessStats);
11076                }
11077                notifyPackageUse(cpi.applicationInfo.packageName,
11078                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11079            }
11080        }
11081        return providers;
11082    }
11083
11084    /**
11085     * Check if the calling UID has a possible chance at accessing the provider
11086     * at the given authority and user.
11087     */
11088    public String checkContentProviderAccess(String authority, int userId) {
11089        if (userId == UserHandle.USER_ALL) {
11090            mContext.enforceCallingOrSelfPermission(
11091                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11092            userId = UserHandle.getCallingUserId();
11093        }
11094
11095        ProviderInfo cpi = null;
11096        try {
11097            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11098                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11099                            | PackageManager.MATCH_DISABLED_COMPONENTS
11100                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11101                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11102                    userId);
11103        } catch (RemoteException ignored) {
11104        }
11105        if (cpi == null) {
11106            return "Failed to find provider " + authority + " for user " + userId
11107                    + "; expected to find a valid ContentProvider for this authority";
11108        }
11109
11110        ProcessRecord r = null;
11111        synchronized (mPidsSelfLocked) {
11112            r = mPidsSelfLocked.get(Binder.getCallingPid());
11113        }
11114        if (r == null) {
11115            return "Failed to find PID " + Binder.getCallingPid();
11116        }
11117
11118        synchronized (this) {
11119            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11120        }
11121    }
11122
11123    /**
11124     * Check if {@link ProcessRecord} has a possible chance at accessing the
11125     * given {@link ProviderInfo}. Final permission checking is always done
11126     * in {@link ContentProvider}.
11127     */
11128    private final String checkContentProviderPermissionLocked(
11129            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11130        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11131        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11132        boolean checkedGrants = false;
11133        if (checkUser) {
11134            // Looking for cross-user grants before enforcing the typical cross-users permissions
11135            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11136            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11137                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11138                    return null;
11139                }
11140                checkedGrants = true;
11141            }
11142            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11143                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11144            if (userId != tmpTargetUserId) {
11145                // When we actually went to determine the final targer user ID, this ended
11146                // up different than our initial check for the authority.  This is because
11147                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11148                // SELF.  So we need to re-check the grants again.
11149                checkedGrants = false;
11150            }
11151        }
11152        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11153                cpi.applicationInfo.uid, cpi.exported)
11154                == PackageManager.PERMISSION_GRANTED) {
11155            return null;
11156        }
11157        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11158                cpi.applicationInfo.uid, cpi.exported)
11159                == PackageManager.PERMISSION_GRANTED) {
11160            return null;
11161        }
11162
11163        PathPermission[] pps = cpi.pathPermissions;
11164        if (pps != null) {
11165            int i = pps.length;
11166            while (i > 0) {
11167                i--;
11168                PathPermission pp = pps[i];
11169                String pprperm = pp.getReadPermission();
11170                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11171                        cpi.applicationInfo.uid, cpi.exported)
11172                        == PackageManager.PERMISSION_GRANTED) {
11173                    return null;
11174                }
11175                String ppwperm = pp.getWritePermission();
11176                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11177                        cpi.applicationInfo.uid, cpi.exported)
11178                        == PackageManager.PERMISSION_GRANTED) {
11179                    return null;
11180                }
11181            }
11182        }
11183        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11184            return null;
11185        }
11186
11187        final String suffix;
11188        if (!cpi.exported) {
11189            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11190        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11191            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11192        } else {
11193            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11194        }
11195        final String msg = "Permission Denial: opening provider " + cpi.name
11196                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11197                + ", uid=" + callingUid + ")" + suffix;
11198        Slog.w(TAG, msg);
11199        return msg;
11200    }
11201
11202    /**
11203     * Returns if the ContentProvider has granted a uri to callingUid
11204     */
11205    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11206        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11207        if (perms != null) {
11208            for (int i=perms.size()-1; i>=0; i--) {
11209                GrantUri grantUri = perms.keyAt(i);
11210                if (grantUri.sourceUserId == userId || !checkUser) {
11211                    if (matchesProvider(grantUri.uri, cpi)) {
11212                        return true;
11213                    }
11214                }
11215            }
11216        }
11217        return false;
11218    }
11219
11220    /**
11221     * Returns true if the uri authority is one of the authorities specified in the provider.
11222     */
11223    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11224        String uriAuth = uri.getAuthority();
11225        String cpiAuth = cpi.authority;
11226        if (cpiAuth.indexOf(';') == -1) {
11227            return cpiAuth.equals(uriAuth);
11228        }
11229        String[] cpiAuths = cpiAuth.split(";");
11230        int length = cpiAuths.length;
11231        for (int i = 0; i < length; i++) {
11232            if (cpiAuths[i].equals(uriAuth)) return true;
11233        }
11234        return false;
11235    }
11236
11237    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11238            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11239        if (r != null) {
11240            for (int i=0; i<r.conProviders.size(); i++) {
11241                ContentProviderConnection conn = r.conProviders.get(i);
11242                if (conn.provider == cpr) {
11243                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11244                            "Adding provider requested by "
11245                            + r.processName + " from process "
11246                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11247                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11248                    if (stable) {
11249                        conn.stableCount++;
11250                        conn.numStableIncs++;
11251                    } else {
11252                        conn.unstableCount++;
11253                        conn.numUnstableIncs++;
11254                    }
11255                    return conn;
11256                }
11257            }
11258            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11259            if (stable) {
11260                conn.stableCount = 1;
11261                conn.numStableIncs = 1;
11262            } else {
11263                conn.unstableCount = 1;
11264                conn.numUnstableIncs = 1;
11265            }
11266            cpr.connections.add(conn);
11267            r.conProviders.add(conn);
11268            startAssociationLocked(r.uid, r.processName, r.curProcState,
11269                    cpr.uid, cpr.name, cpr.info.processName);
11270            return conn;
11271        }
11272        cpr.addExternalProcessHandleLocked(externalProcessToken);
11273        return null;
11274    }
11275
11276    boolean decProviderCountLocked(ContentProviderConnection conn,
11277            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11278        if (conn != null) {
11279            cpr = conn.provider;
11280            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11281                    "Removing provider requested by "
11282                    + conn.client.processName + " from process "
11283                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11284                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11285            if (stable) {
11286                conn.stableCount--;
11287            } else {
11288                conn.unstableCount--;
11289            }
11290            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11291                cpr.connections.remove(conn);
11292                conn.client.conProviders.remove(conn);
11293                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11294                    // The client is more important than last activity -- note the time this
11295                    // is happening, so we keep the old provider process around a bit as last
11296                    // activity to avoid thrashing it.
11297                    if (cpr.proc != null) {
11298                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11299                    }
11300                }
11301                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11302                return true;
11303            }
11304            return false;
11305        }
11306        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11307        return false;
11308    }
11309
11310    private void checkTime(long startTime, String where) {
11311        long now = SystemClock.uptimeMillis();
11312        if ((now-startTime) > 50) {
11313            // If we are taking more than 50ms, log about it.
11314            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11315        }
11316    }
11317
11318    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11319            PROC_SPACE_TERM,
11320            PROC_SPACE_TERM|PROC_PARENS,
11321            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11322    };
11323
11324    private final long[] mProcessStateStatsLongs = new long[1];
11325
11326    boolean isProcessAliveLocked(ProcessRecord proc) {
11327        if (proc.procStatFile == null) {
11328            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11329        }
11330        mProcessStateStatsLongs[0] = 0;
11331        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11332                mProcessStateStatsLongs, null)) {
11333            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11334            return false;
11335        }
11336        final long state = mProcessStateStatsLongs[0];
11337        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11338                + (char)state);
11339        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11340    }
11341
11342    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11343            String name, IBinder token, boolean stable, int userId) {
11344        ContentProviderRecord cpr;
11345        ContentProviderConnection conn = null;
11346        ProviderInfo cpi = null;
11347
11348        synchronized(this) {
11349            long startTime = SystemClock.uptimeMillis();
11350
11351            ProcessRecord r = null;
11352            if (caller != null) {
11353                r = getRecordForAppLocked(caller);
11354                if (r == null) {
11355                    throw new SecurityException(
11356                            "Unable to find app for caller " + caller
11357                          + " (pid=" + Binder.getCallingPid()
11358                          + ") when getting content provider " + name);
11359                }
11360            }
11361
11362            boolean checkCrossUser = true;
11363
11364            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11365
11366            // First check if this content provider has been published...
11367            cpr = mProviderMap.getProviderByName(name, userId);
11368            // If that didn't work, check if it exists for user 0 and then
11369            // verify that it's a singleton provider before using it.
11370            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11371                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11372                if (cpr != null) {
11373                    cpi = cpr.info;
11374                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11375                            cpi.name, cpi.flags)
11376                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11377                        userId = UserHandle.USER_SYSTEM;
11378                        checkCrossUser = false;
11379                    } else {
11380                        cpr = null;
11381                        cpi = null;
11382                    }
11383                }
11384            }
11385
11386            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11387            if (providerRunning) {
11388                cpi = cpr.info;
11389                String msg;
11390                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11391                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11392                        != null) {
11393                    throw new SecurityException(msg);
11394                }
11395                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11396
11397                if (r != null && cpr.canRunHere(r)) {
11398                    // This provider has been published or is in the process
11399                    // of being published...  but it is also allowed to run
11400                    // in the caller's process, so don't make a connection
11401                    // and just let the caller instantiate its own instance.
11402                    ContentProviderHolder holder = cpr.newHolder(null);
11403                    // don't give caller the provider object, it needs
11404                    // to make its own.
11405                    holder.provider = null;
11406                    return holder;
11407                }
11408                // Don't expose providers between normal apps and instant apps
11409                try {
11410                    if (AppGlobals.getPackageManager()
11411                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11412                        return null;
11413                    }
11414                } catch (RemoteException e) {
11415                }
11416
11417                final long origId = Binder.clearCallingIdentity();
11418
11419                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11420
11421                // In this case the provider instance already exists, so we can
11422                // return it right away.
11423                conn = incProviderCountLocked(r, cpr, token, stable);
11424                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11425                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11426                        // If this is a perceptible app accessing the provider,
11427                        // make sure to count it as being accessed and thus
11428                        // back up on the LRU list.  This is good because
11429                        // content providers are often expensive to start.
11430                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11431                        updateLruProcessLocked(cpr.proc, false, null);
11432                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11433                    }
11434                }
11435
11436                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11437                final int verifiedAdj = cpr.proc.verifiedAdj;
11438                boolean success = updateOomAdjLocked(cpr.proc, true);
11439                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11440                // if the process has been successfully adjusted.  So to reduce races with
11441                // it, we will check whether the process still exists.  Note that this doesn't
11442                // completely get rid of races with LMK killing the process, but should make
11443                // them much smaller.
11444                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11445                    success = false;
11446                }
11447                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11448                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11449                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11450                // NOTE: there is still a race here where a signal could be
11451                // pending on the process even though we managed to update its
11452                // adj level.  Not sure what to do about this, but at least
11453                // the race is now smaller.
11454                if (!success) {
11455                    // Uh oh...  it looks like the provider's process
11456                    // has been killed on us.  We need to wait for a new
11457                    // process to be started, and make sure its death
11458                    // doesn't kill our process.
11459                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11460                            + " is crashing; detaching " + r);
11461                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11462                    checkTime(startTime, "getContentProviderImpl: before appDied");
11463                    appDiedLocked(cpr.proc);
11464                    checkTime(startTime, "getContentProviderImpl: after appDied");
11465                    if (!lastRef) {
11466                        // This wasn't the last ref our process had on
11467                        // the provider...  we have now been killed, bail.
11468                        return null;
11469                    }
11470                    providerRunning = false;
11471                    conn = null;
11472                } else {
11473                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11474                }
11475
11476                Binder.restoreCallingIdentity(origId);
11477            }
11478
11479            if (!providerRunning) {
11480                try {
11481                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11482                    cpi = AppGlobals.getPackageManager().
11483                        resolveContentProvider(name,
11484                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11485                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11486                } catch (RemoteException ex) {
11487                }
11488                if (cpi == null) {
11489                    return null;
11490                }
11491                // If the provider is a singleton AND
11492                // (it's a call within the same user || the provider is a
11493                // privileged app)
11494                // Then allow connecting to the singleton provider
11495                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11496                        cpi.name, cpi.flags)
11497                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11498                if (singleton) {
11499                    userId = UserHandle.USER_SYSTEM;
11500                }
11501                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11502                checkTime(startTime, "getContentProviderImpl: got app info for user");
11503
11504                String msg;
11505                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11506                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11507                        != null) {
11508                    throw new SecurityException(msg);
11509                }
11510                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11511
11512                if (!mProcessesReady
11513                        && !cpi.processName.equals("system")) {
11514                    // If this content provider does not run in the system
11515                    // process, and the system is not yet ready to run other
11516                    // processes, then fail fast instead of hanging.
11517                    throw new IllegalArgumentException(
11518                            "Attempt to launch content provider before system ready");
11519                }
11520
11521                // Make sure that the user who owns this provider is running.  If not,
11522                // we don't want to allow it to run.
11523                if (!mUserController.isUserRunningLocked(userId, 0)) {
11524                    Slog.w(TAG, "Unable to launch app "
11525                            + cpi.applicationInfo.packageName + "/"
11526                            + cpi.applicationInfo.uid + " for provider "
11527                            + name + ": user " + userId + " is stopped");
11528                    return null;
11529                }
11530
11531                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11532                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11533                cpr = mProviderMap.getProviderByClass(comp, userId);
11534                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11535                final boolean firstClass = cpr == null;
11536                if (firstClass) {
11537                    final long ident = Binder.clearCallingIdentity();
11538
11539                    // If permissions need a review before any of the app components can run,
11540                    // we return no provider and launch a review activity if the calling app
11541                    // is in the foreground.
11542                    if (mPermissionReviewRequired) {
11543                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11544                            return null;
11545                        }
11546                    }
11547
11548                    try {
11549                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11550                        ApplicationInfo ai =
11551                            AppGlobals.getPackageManager().
11552                                getApplicationInfo(
11553                                        cpi.applicationInfo.packageName,
11554                                        STOCK_PM_FLAGS, userId);
11555                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11556                        if (ai == null) {
11557                            Slog.w(TAG, "No package info for content provider "
11558                                    + cpi.name);
11559                            return null;
11560                        }
11561                        ai = getAppInfoForUser(ai, userId);
11562                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11563                    } catch (RemoteException ex) {
11564                        // pm is in same process, this will never happen.
11565                    } finally {
11566                        Binder.restoreCallingIdentity(ident);
11567                    }
11568                }
11569
11570                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11571
11572                if (r != null && cpr.canRunHere(r)) {
11573                    // If this is a multiprocess provider, then just return its
11574                    // info and allow the caller to instantiate it.  Only do
11575                    // this if the provider is the same user as the caller's
11576                    // process, or can run as root (so can be in any process).
11577                    return cpr.newHolder(null);
11578                }
11579
11580                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11581                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11582                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11583
11584                // This is single process, and our app is now connecting to it.
11585                // See if we are already in the process of launching this
11586                // provider.
11587                final int N = mLaunchingProviders.size();
11588                int i;
11589                for (i = 0; i < N; i++) {
11590                    if (mLaunchingProviders.get(i) == cpr) {
11591                        break;
11592                    }
11593                }
11594
11595                // If the provider is not already being launched, then get it
11596                // started.
11597                if (i >= N) {
11598                    final long origId = Binder.clearCallingIdentity();
11599
11600                    try {
11601                        // Content provider is now in use, its package can't be stopped.
11602                        try {
11603                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11604                            AppGlobals.getPackageManager().setPackageStoppedState(
11605                                    cpr.appInfo.packageName, false, userId);
11606                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11607                        } catch (RemoteException e) {
11608                        } catch (IllegalArgumentException e) {
11609                            Slog.w(TAG, "Failed trying to unstop package "
11610                                    + cpr.appInfo.packageName + ": " + e);
11611                        }
11612
11613                        // Use existing process if already started
11614                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11615                        ProcessRecord proc = getProcessRecordLocked(
11616                                cpi.processName, cpr.appInfo.uid, false);
11617                        if (proc != null && proc.thread != null && !proc.killed) {
11618                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11619                                    "Installing in existing process " + proc);
11620                            if (!proc.pubProviders.containsKey(cpi.name)) {
11621                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11622                                proc.pubProviders.put(cpi.name, cpr);
11623                                try {
11624                                    proc.thread.scheduleInstallProvider(cpi);
11625                                } catch (RemoteException e) {
11626                                }
11627                            }
11628                        } else {
11629                            checkTime(startTime, "getContentProviderImpl: before start process");
11630                            proc = startProcessLocked(cpi.processName,
11631                                    cpr.appInfo, false, 0, "content provider",
11632                                    new ComponentName(cpi.applicationInfo.packageName,
11633                                            cpi.name), false, false, false);
11634                            checkTime(startTime, "getContentProviderImpl: after start process");
11635                            if (proc == null) {
11636                                Slog.w(TAG, "Unable to launch app "
11637                                        + cpi.applicationInfo.packageName + "/"
11638                                        + cpi.applicationInfo.uid + " for provider "
11639                                        + name + ": process is bad");
11640                                return null;
11641                            }
11642                        }
11643                        cpr.launchingApp = proc;
11644                        mLaunchingProviders.add(cpr);
11645                    } finally {
11646                        Binder.restoreCallingIdentity(origId);
11647                    }
11648                }
11649
11650                checkTime(startTime, "getContentProviderImpl: updating data structures");
11651
11652                // Make sure the provider is published (the same provider class
11653                // may be published under multiple names).
11654                if (firstClass) {
11655                    mProviderMap.putProviderByClass(comp, cpr);
11656                }
11657
11658                mProviderMap.putProviderByName(name, cpr);
11659                conn = incProviderCountLocked(r, cpr, token, stable);
11660                if (conn != null) {
11661                    conn.waiting = true;
11662                }
11663            }
11664            checkTime(startTime, "getContentProviderImpl: done!");
11665
11666            grantEphemeralAccessLocked(userId, null /*intent*/,
11667                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11668        }
11669
11670        // Wait for the provider to be published...
11671        synchronized (cpr) {
11672            while (cpr.provider == null) {
11673                if (cpr.launchingApp == null) {
11674                    Slog.w(TAG, "Unable to launch app "
11675                            + cpi.applicationInfo.packageName + "/"
11676                            + cpi.applicationInfo.uid + " for provider "
11677                            + name + ": launching app became null");
11678                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11679                            UserHandle.getUserId(cpi.applicationInfo.uid),
11680                            cpi.applicationInfo.packageName,
11681                            cpi.applicationInfo.uid, name);
11682                    return null;
11683                }
11684                try {
11685                    if (DEBUG_MU) Slog.v(TAG_MU,
11686                            "Waiting to start provider " + cpr
11687                            + " launchingApp=" + cpr.launchingApp);
11688                    if (conn != null) {
11689                        conn.waiting = true;
11690                    }
11691                    cpr.wait();
11692                } catch (InterruptedException ex) {
11693                } finally {
11694                    if (conn != null) {
11695                        conn.waiting = false;
11696                    }
11697                }
11698            }
11699        }
11700        return cpr != null ? cpr.newHolder(conn) : null;
11701    }
11702
11703    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11704            ProcessRecord r, final int userId) {
11705        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11706                cpi.packageName, userId)) {
11707
11708            final boolean callerForeground = r == null || r.setSchedGroup
11709                    != ProcessList.SCHED_GROUP_BACKGROUND;
11710
11711            // Show a permission review UI only for starting from a foreground app
11712            if (!callerForeground) {
11713                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11714                        + cpi.packageName + " requires a permissions review");
11715                return false;
11716            }
11717
11718            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11719            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11720                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11721            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11722
11723            if (DEBUG_PERMISSIONS_REVIEW) {
11724                Slog.i(TAG, "u" + userId + " Launching permission review "
11725                        + "for package " + cpi.packageName);
11726            }
11727
11728            final UserHandle userHandle = new UserHandle(userId);
11729            mHandler.post(new Runnable() {
11730                @Override
11731                public void run() {
11732                    mContext.startActivityAsUser(intent, userHandle);
11733                }
11734            });
11735
11736            return false;
11737        }
11738
11739        return true;
11740    }
11741
11742    PackageManagerInternal getPackageManagerInternalLocked() {
11743        if (mPackageManagerInt == null) {
11744            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11745        }
11746        return mPackageManagerInt;
11747    }
11748
11749    @Override
11750    public final ContentProviderHolder getContentProvider(
11751            IApplicationThread caller, String name, int userId, boolean stable) {
11752        enforceNotIsolatedCaller("getContentProvider");
11753        if (caller == null) {
11754            String msg = "null IApplicationThread when getting content provider "
11755                    + name;
11756            Slog.w(TAG, msg);
11757            throw new SecurityException(msg);
11758        }
11759        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11760        // with cross-user grant.
11761        return getContentProviderImpl(caller, name, null, stable, userId);
11762    }
11763
11764    public ContentProviderHolder getContentProviderExternal(
11765            String name, int userId, IBinder token) {
11766        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11767            "Do not have permission in call getContentProviderExternal()");
11768        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11769                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11770        return getContentProviderExternalUnchecked(name, token, userId);
11771    }
11772
11773    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11774            IBinder token, int userId) {
11775        return getContentProviderImpl(null, name, token, true, userId);
11776    }
11777
11778    /**
11779     * Drop a content provider from a ProcessRecord's bookkeeping
11780     */
11781    public void removeContentProvider(IBinder connection, boolean stable) {
11782        enforceNotIsolatedCaller("removeContentProvider");
11783        long ident = Binder.clearCallingIdentity();
11784        try {
11785            synchronized (this) {
11786                ContentProviderConnection conn;
11787                try {
11788                    conn = (ContentProviderConnection)connection;
11789                } catch (ClassCastException e) {
11790                    String msg ="removeContentProvider: " + connection
11791                            + " not a ContentProviderConnection";
11792                    Slog.w(TAG, msg);
11793                    throw new IllegalArgumentException(msg);
11794                }
11795                if (conn == null) {
11796                    throw new NullPointerException("connection is null");
11797                }
11798                if (decProviderCountLocked(conn, null, null, stable)) {
11799                    updateOomAdjLocked();
11800                }
11801            }
11802        } finally {
11803            Binder.restoreCallingIdentity(ident);
11804        }
11805    }
11806
11807    public void removeContentProviderExternal(String name, IBinder token) {
11808        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11809            "Do not have permission in call removeContentProviderExternal()");
11810        int userId = UserHandle.getCallingUserId();
11811        long ident = Binder.clearCallingIdentity();
11812        try {
11813            removeContentProviderExternalUnchecked(name, token, userId);
11814        } finally {
11815            Binder.restoreCallingIdentity(ident);
11816        }
11817    }
11818
11819    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11820        synchronized (this) {
11821            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11822            if(cpr == null) {
11823                //remove from mProvidersByClass
11824                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11825                return;
11826            }
11827
11828            //update content provider record entry info
11829            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11830            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11831            if (localCpr.hasExternalProcessHandles()) {
11832                if (localCpr.removeExternalProcessHandleLocked(token)) {
11833                    updateOomAdjLocked();
11834                } else {
11835                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11836                            + " with no external reference for token: "
11837                            + token + ".");
11838                }
11839            } else {
11840                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11841                        + " with no external references.");
11842            }
11843        }
11844    }
11845
11846    public final void publishContentProviders(IApplicationThread caller,
11847            List<ContentProviderHolder> providers) {
11848        if (providers == null) {
11849            return;
11850        }
11851
11852        enforceNotIsolatedCaller("publishContentProviders");
11853        synchronized (this) {
11854            final ProcessRecord r = getRecordForAppLocked(caller);
11855            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11856            if (r == null) {
11857                throw new SecurityException(
11858                        "Unable to find app for caller " + caller
11859                      + " (pid=" + Binder.getCallingPid()
11860                      + ") when publishing content providers");
11861            }
11862
11863            final long origId = Binder.clearCallingIdentity();
11864
11865            final int N = providers.size();
11866            for (int i = 0; i < N; i++) {
11867                ContentProviderHolder src = providers.get(i);
11868                if (src == null || src.info == null || src.provider == null) {
11869                    continue;
11870                }
11871                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11872                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11873                if (dst != null) {
11874                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11875                    mProviderMap.putProviderByClass(comp, dst);
11876                    String names[] = dst.info.authority.split(";");
11877                    for (int j = 0; j < names.length; j++) {
11878                        mProviderMap.putProviderByName(names[j], dst);
11879                    }
11880
11881                    int launchingCount = mLaunchingProviders.size();
11882                    int j;
11883                    boolean wasInLaunchingProviders = false;
11884                    for (j = 0; j < launchingCount; j++) {
11885                        if (mLaunchingProviders.get(j) == dst) {
11886                            mLaunchingProviders.remove(j);
11887                            wasInLaunchingProviders = true;
11888                            j--;
11889                            launchingCount--;
11890                        }
11891                    }
11892                    if (wasInLaunchingProviders) {
11893                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11894                    }
11895                    synchronized (dst) {
11896                        dst.provider = src.provider;
11897                        dst.proc = r;
11898                        dst.notifyAll();
11899                    }
11900                    updateOomAdjLocked(r, true);
11901                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11902                            src.info.authority);
11903                }
11904            }
11905
11906            Binder.restoreCallingIdentity(origId);
11907        }
11908    }
11909
11910    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11911        ContentProviderConnection conn;
11912        try {
11913            conn = (ContentProviderConnection)connection;
11914        } catch (ClassCastException e) {
11915            String msg ="refContentProvider: " + connection
11916                    + " not a ContentProviderConnection";
11917            Slog.w(TAG, msg);
11918            throw new IllegalArgumentException(msg);
11919        }
11920        if (conn == null) {
11921            throw new NullPointerException("connection is null");
11922        }
11923
11924        synchronized (this) {
11925            if (stable > 0) {
11926                conn.numStableIncs += stable;
11927            }
11928            stable = conn.stableCount + stable;
11929            if (stable < 0) {
11930                throw new IllegalStateException("stableCount < 0: " + stable);
11931            }
11932
11933            if (unstable > 0) {
11934                conn.numUnstableIncs += unstable;
11935            }
11936            unstable = conn.unstableCount + unstable;
11937            if (unstable < 0) {
11938                throw new IllegalStateException("unstableCount < 0: " + unstable);
11939            }
11940
11941            if ((stable+unstable) <= 0) {
11942                throw new IllegalStateException("ref counts can't go to zero here: stable="
11943                        + stable + " unstable=" + unstable);
11944            }
11945            conn.stableCount = stable;
11946            conn.unstableCount = unstable;
11947            return !conn.dead;
11948        }
11949    }
11950
11951    public void unstableProviderDied(IBinder connection) {
11952        ContentProviderConnection conn;
11953        try {
11954            conn = (ContentProviderConnection)connection;
11955        } catch (ClassCastException e) {
11956            String msg ="refContentProvider: " + connection
11957                    + " not a ContentProviderConnection";
11958            Slog.w(TAG, msg);
11959            throw new IllegalArgumentException(msg);
11960        }
11961        if (conn == null) {
11962            throw new NullPointerException("connection is null");
11963        }
11964
11965        // Safely retrieve the content provider associated with the connection.
11966        IContentProvider provider;
11967        synchronized (this) {
11968            provider = conn.provider.provider;
11969        }
11970
11971        if (provider == null) {
11972            // Um, yeah, we're way ahead of you.
11973            return;
11974        }
11975
11976        // Make sure the caller is being honest with us.
11977        if (provider.asBinder().pingBinder()) {
11978            // Er, no, still looks good to us.
11979            synchronized (this) {
11980                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11981                        + " says " + conn + " died, but we don't agree");
11982                return;
11983            }
11984        }
11985
11986        // Well look at that!  It's dead!
11987        synchronized (this) {
11988            if (conn.provider.provider != provider) {
11989                // But something changed...  good enough.
11990                return;
11991            }
11992
11993            ProcessRecord proc = conn.provider.proc;
11994            if (proc == null || proc.thread == null) {
11995                // Seems like the process is already cleaned up.
11996                return;
11997            }
11998
11999            // As far as we're concerned, this is just like receiving a
12000            // death notification...  just a bit prematurely.
12001            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12002                    + ") early provider death");
12003            final long ident = Binder.clearCallingIdentity();
12004            try {
12005                appDiedLocked(proc);
12006            } finally {
12007                Binder.restoreCallingIdentity(ident);
12008            }
12009        }
12010    }
12011
12012    @Override
12013    public void appNotRespondingViaProvider(IBinder connection) {
12014        enforceCallingPermission(
12015                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12016
12017        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12018        if (conn == null) {
12019            Slog.w(TAG, "ContentProviderConnection is null");
12020            return;
12021        }
12022
12023        final ProcessRecord host = conn.provider.proc;
12024        if (host == null) {
12025            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12026            return;
12027        }
12028
12029        mHandler.post(new Runnable() {
12030            @Override
12031            public void run() {
12032                mAppErrors.appNotResponding(host, null, null, false,
12033                        "ContentProvider not responding");
12034            }
12035        });
12036    }
12037
12038    public final void installSystemProviders() {
12039        List<ProviderInfo> providers;
12040        synchronized (this) {
12041            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12042            providers = generateApplicationProvidersLocked(app);
12043            if (providers != null) {
12044                for (int i=providers.size()-1; i>=0; i--) {
12045                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12046                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12047                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12048                                + ": not system .apk");
12049                        providers.remove(i);
12050                    }
12051                }
12052            }
12053        }
12054        if (providers != null) {
12055            mSystemThread.installSystemProviders(providers);
12056        }
12057
12058        mConstants.start(mContext.getContentResolver());
12059        mCoreSettingsObserver = new CoreSettingsObserver(this);
12060        mFontScaleSettingObserver = new FontScaleSettingObserver();
12061
12062        // Now that the settings provider is published we can consider sending
12063        // in a rescue party.
12064        RescueParty.onSettingsProviderPublished(mContext);
12065
12066        //mUsageStatsService.monitorPackages();
12067    }
12068
12069    private void startPersistentApps(int matchFlags) {
12070        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12071
12072        synchronized (this) {
12073            try {
12074                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12075                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12076                for (ApplicationInfo app : apps) {
12077                    if (!"android".equals(app.packageName)) {
12078                        addAppLocked(app, null, false, null /* ABI override */);
12079                    }
12080                }
12081            } catch (RemoteException ex) {
12082            }
12083        }
12084    }
12085
12086    /**
12087     * When a user is unlocked, we need to install encryption-unaware providers
12088     * belonging to any running apps.
12089     */
12090    private void installEncryptionUnawareProviders(int userId) {
12091        // We're only interested in providers that are encryption unaware, and
12092        // we don't care about uninstalled apps, since there's no way they're
12093        // running at this point.
12094        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12095
12096        synchronized (this) {
12097            final int NP = mProcessNames.getMap().size();
12098            for (int ip = 0; ip < NP; ip++) {
12099                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12100                final int NA = apps.size();
12101                for (int ia = 0; ia < NA; ia++) {
12102                    final ProcessRecord app = apps.valueAt(ia);
12103                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12104
12105                    final int NG = app.pkgList.size();
12106                    for (int ig = 0; ig < NG; ig++) {
12107                        try {
12108                            final String pkgName = app.pkgList.keyAt(ig);
12109                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12110                                    .getPackageInfo(pkgName, matchFlags, userId);
12111                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12112                                for (ProviderInfo pi : pkgInfo.providers) {
12113                                    // TODO: keep in sync with generateApplicationProvidersLocked
12114                                    final boolean processMatch = Objects.equals(pi.processName,
12115                                            app.processName) || pi.multiprocess;
12116                                    final boolean userMatch = isSingleton(pi.processName,
12117                                            pi.applicationInfo, pi.name, pi.flags)
12118                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12119                                    if (processMatch && userMatch) {
12120                                        Log.v(TAG, "Installing " + pi);
12121                                        app.thread.scheduleInstallProvider(pi);
12122                                    } else {
12123                                        Log.v(TAG, "Skipping " + pi);
12124                                    }
12125                                }
12126                            }
12127                        } catch (RemoteException ignored) {
12128                        }
12129                    }
12130                }
12131            }
12132        }
12133    }
12134
12135    /**
12136     * Allows apps to retrieve the MIME type of a URI.
12137     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12138     * users, then it does not need permission to access the ContentProvider.
12139     * Either, it needs cross-user uri grants.
12140     *
12141     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12142     *
12143     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12144     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12145     */
12146    public String getProviderMimeType(Uri uri, int userId) {
12147        enforceNotIsolatedCaller("getProviderMimeType");
12148        final String name = uri.getAuthority();
12149        int callingUid = Binder.getCallingUid();
12150        int callingPid = Binder.getCallingPid();
12151        long ident = 0;
12152        boolean clearedIdentity = false;
12153        synchronized (this) {
12154            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12155        }
12156        if (canClearIdentity(callingPid, callingUid, userId)) {
12157            clearedIdentity = true;
12158            ident = Binder.clearCallingIdentity();
12159        }
12160        ContentProviderHolder holder = null;
12161        try {
12162            holder = getContentProviderExternalUnchecked(name, null, userId);
12163            if (holder != null) {
12164                return holder.provider.getType(uri);
12165            }
12166        } catch (RemoteException e) {
12167            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12168            return null;
12169        } catch (Exception e) {
12170            Log.w(TAG, "Exception while determining type of " + uri, e);
12171            return null;
12172        } finally {
12173            // We need to clear the identity to call removeContentProviderExternalUnchecked
12174            if (!clearedIdentity) {
12175                ident = Binder.clearCallingIdentity();
12176            }
12177            try {
12178                if (holder != null) {
12179                    removeContentProviderExternalUnchecked(name, null, userId);
12180                }
12181            } finally {
12182                Binder.restoreCallingIdentity(ident);
12183            }
12184        }
12185
12186        return null;
12187    }
12188
12189    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12190        if (UserHandle.getUserId(callingUid) == userId) {
12191            return true;
12192        }
12193        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12194                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12195                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12196                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12197                return true;
12198        }
12199        return false;
12200    }
12201
12202    // =========================================================
12203    // GLOBAL MANAGEMENT
12204    // =========================================================
12205
12206    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12207            boolean isolated, int isolatedUid) {
12208        String proc = customProcess != null ? customProcess : info.processName;
12209        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12210        final int userId = UserHandle.getUserId(info.uid);
12211        int uid = info.uid;
12212        if (isolated) {
12213            if (isolatedUid == 0) {
12214                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12215                while (true) {
12216                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12217                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12218                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12219                    }
12220                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12221                    mNextIsolatedProcessUid++;
12222                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12223                        // No process for this uid, use it.
12224                        break;
12225                    }
12226                    stepsLeft--;
12227                    if (stepsLeft <= 0) {
12228                        return null;
12229                    }
12230                }
12231            } else {
12232                // Special case for startIsolatedProcess (internal only), where
12233                // the uid of the isolated process is specified by the caller.
12234                uid = isolatedUid;
12235            }
12236            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12237
12238            // Register the isolated UID with this application so BatteryStats knows to
12239            // attribute resource usage to the application.
12240            //
12241            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12242            // about the process state of the isolated UID *before* it is registered with the
12243            // owning application.
12244            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12245        }
12246        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12247        if (!mBooted && !mBooting
12248                && userId == UserHandle.USER_SYSTEM
12249                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12250            r.persistent = true;
12251            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12252        }
12253        if (isolated && isolatedUid != 0) {
12254            // Special case for startIsolatedProcess (internal only) - assume the process
12255            // is required by the system server to prevent it being killed.
12256            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
12257        }
12258        addProcessNameLocked(r);
12259        return r;
12260    }
12261
12262    private boolean uidOnBackgroundWhitelist(final int uid) {
12263        final int appId = UserHandle.getAppId(uid);
12264        final int[] whitelist = mBackgroundAppIdWhitelist;
12265        final int N = whitelist.length;
12266        for (int i = 0; i < N; i++) {
12267            if (appId == whitelist[i]) {
12268                return true;
12269            }
12270        }
12271        return false;
12272    }
12273
12274    @Override
12275    public void backgroundWhitelistUid(final int uid) {
12276        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12277            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12278        }
12279
12280        if (DEBUG_BACKGROUND_CHECK) {
12281            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12282        }
12283        synchronized (this) {
12284            final int N = mBackgroundAppIdWhitelist.length;
12285            int[] newList = new int[N+1];
12286            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12287            newList[N] = UserHandle.getAppId(uid);
12288            mBackgroundAppIdWhitelist = newList;
12289        }
12290    }
12291
12292    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12293            String abiOverride) {
12294        ProcessRecord app;
12295        if (!isolated) {
12296            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12297                    info.uid, true);
12298        } else {
12299            app = null;
12300        }
12301
12302        if (app == null) {
12303            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12304            updateLruProcessLocked(app, false, null);
12305            updateOomAdjLocked();
12306        }
12307
12308        // This package really, really can not be stopped.
12309        try {
12310            AppGlobals.getPackageManager().setPackageStoppedState(
12311                    info.packageName, false, UserHandle.getUserId(app.uid));
12312        } catch (RemoteException e) {
12313        } catch (IllegalArgumentException e) {
12314            Slog.w(TAG, "Failed trying to unstop package "
12315                    + info.packageName + ": " + e);
12316        }
12317
12318        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12319            app.persistent = true;
12320            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12321        }
12322        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12323            mPersistentStartingProcesses.add(app);
12324            startProcessLocked(app, "added application",
12325                    customProcess != null ? customProcess : app.processName, abiOverride);
12326        }
12327
12328        return app;
12329    }
12330
12331    public void unhandledBack() {
12332        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12333                "unhandledBack()");
12334
12335        synchronized(this) {
12336            final long origId = Binder.clearCallingIdentity();
12337            try {
12338                getFocusedStack().unhandledBackLocked();
12339            } finally {
12340                Binder.restoreCallingIdentity(origId);
12341            }
12342        }
12343    }
12344
12345    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12346        enforceNotIsolatedCaller("openContentUri");
12347        final int userId = UserHandle.getCallingUserId();
12348        final Uri uri = Uri.parse(uriString);
12349        String name = uri.getAuthority();
12350        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12351        ParcelFileDescriptor pfd = null;
12352        if (cph != null) {
12353            // We record the binder invoker's uid in thread-local storage before
12354            // going to the content provider to open the file.  Later, in the code
12355            // that handles all permissions checks, we look for this uid and use
12356            // that rather than the Activity Manager's own uid.  The effect is that
12357            // we do the check against the caller's permissions even though it looks
12358            // to the content provider like the Activity Manager itself is making
12359            // the request.
12360            Binder token = new Binder();
12361            sCallerIdentity.set(new Identity(
12362                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12363            try {
12364                pfd = cph.provider.openFile(null, uri, "r", null, token);
12365            } catch (FileNotFoundException e) {
12366                // do nothing; pfd will be returned null
12367            } finally {
12368                // Ensure that whatever happens, we clean up the identity state
12369                sCallerIdentity.remove();
12370                // Ensure we're done with the provider.
12371                removeContentProviderExternalUnchecked(name, null, userId);
12372            }
12373        } else {
12374            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12375        }
12376        return pfd;
12377    }
12378
12379    // Actually is sleeping or shutting down or whatever else in the future
12380    // is an inactive state.
12381    boolean isSleepingOrShuttingDownLocked() {
12382        return isSleepingLocked() || mShuttingDown;
12383    }
12384
12385    boolean isShuttingDownLocked() {
12386        return mShuttingDown;
12387    }
12388
12389    boolean isSleepingLocked() {
12390        return mSleeping;
12391    }
12392
12393    void onWakefulnessChanged(int wakefulness) {
12394        synchronized(this) {
12395            mWakefulness = wakefulness;
12396
12397            // Also update state in a special way for running foreground services UI.
12398            switch (mWakefulness) {
12399                case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12400                case PowerManagerInternal.WAKEFULNESS_DREAMING:
12401                case PowerManagerInternal.WAKEFULNESS_DOZING:
12402                    mServices.updateScreenStateLocked(false /* screenOn */);
12403                    break;
12404                case PowerManagerInternal.WAKEFULNESS_AWAKE:
12405                default:
12406                    mServices.updateScreenStateLocked(true /* screenOn */);
12407                    break;
12408            }
12409        }
12410    }
12411
12412    void finishRunningVoiceLocked() {
12413        if (mRunningVoice != null) {
12414            mRunningVoice = null;
12415            mVoiceWakeLock.release();
12416            updateSleepIfNeededLocked();
12417        }
12418    }
12419
12420    void startTimeTrackingFocusedActivityLocked() {
12421        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12422        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12423            mCurAppTimeTracker.start(resumedActivity.packageName);
12424        }
12425    }
12426
12427    void updateSleepIfNeededLocked() {
12428        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12429        final boolean wasSleeping = mSleeping;
12430
12431        if (!shouldSleep) {
12432            // If wasSleeping is true, we need to wake up activity manager state from when
12433            // we started sleeping. In either case, we need to apply the sleep tokens, which
12434            // will wake up stacks or put them to sleep as appropriate.
12435            if (wasSleeping) {
12436                mSleeping = false;
12437                startTimeTrackingFocusedActivityLocked();
12438                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12439                mStackSupervisor.comeOutOfSleepIfNeededLocked();
12440            }
12441            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12442            if (wasSleeping) {
12443                sendNotifyVrManagerOfSleepState(false);
12444                updateOomAdjLocked();
12445            }
12446        } else if (!mSleeping && shouldSleep) {
12447            mSleeping = true;
12448            if (mCurAppTimeTracker != null) {
12449                mCurAppTimeTracker.stop();
12450            }
12451            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12452            mStackSupervisor.goingToSleepLocked();
12453            sendNotifyVrManagerOfSleepState(true);
12454            updateOomAdjLocked();
12455        }
12456    }
12457
12458    /** Pokes the task persister. */
12459    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12460        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12461    }
12462
12463    /**
12464     * Notifies all listeners when the pinned stack animation starts.
12465     */
12466    @Override
12467    public void notifyPinnedStackAnimationStarted() {
12468        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12469    }
12470
12471    /**
12472     * Notifies all listeners when the pinned stack animation ends.
12473     */
12474    @Override
12475    public void notifyPinnedStackAnimationEnded() {
12476        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12477    }
12478
12479    @Override
12480    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12481        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12482    }
12483
12484    @Override
12485    public boolean shutdown(int timeout) {
12486        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12487                != PackageManager.PERMISSION_GRANTED) {
12488            throw new SecurityException("Requires permission "
12489                    + android.Manifest.permission.SHUTDOWN);
12490        }
12491
12492        boolean timedout = false;
12493
12494        synchronized(this) {
12495            mShuttingDown = true;
12496            mStackSupervisor.prepareForShutdownLocked();
12497            updateEventDispatchingLocked();
12498            timedout = mStackSupervisor.shutdownLocked(timeout);
12499        }
12500
12501        mAppOpsService.shutdown();
12502        if (mUsageStatsService != null) {
12503            mUsageStatsService.prepareShutdown();
12504        }
12505        mBatteryStatsService.shutdown();
12506        synchronized (this) {
12507            mProcessStats.shutdownLocked();
12508            notifyTaskPersisterLocked(null, true);
12509        }
12510
12511        return timedout;
12512    }
12513
12514    public final void activitySlept(IBinder token) {
12515        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12516
12517        final long origId = Binder.clearCallingIdentity();
12518
12519        synchronized (this) {
12520            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12521            if (r != null) {
12522                mStackSupervisor.activitySleptLocked(r);
12523            }
12524        }
12525
12526        Binder.restoreCallingIdentity(origId);
12527    }
12528
12529    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12530        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12531        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12532        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12533            boolean wasRunningVoice = mRunningVoice != null;
12534            mRunningVoice = session;
12535            if (!wasRunningVoice) {
12536                mVoiceWakeLock.acquire();
12537                updateSleepIfNeededLocked();
12538            }
12539        }
12540    }
12541
12542    private void updateEventDispatchingLocked() {
12543        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12544    }
12545
12546    @Override
12547    public void setLockScreenShown(boolean showing) {
12548        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12549                != PackageManager.PERMISSION_GRANTED) {
12550            throw new SecurityException("Requires permission "
12551                    + android.Manifest.permission.DEVICE_POWER);
12552        }
12553
12554        synchronized(this) {
12555            long ident = Binder.clearCallingIdentity();
12556            try {
12557                mKeyguardController.setKeyguardShown(showing);
12558            } finally {
12559                Binder.restoreCallingIdentity(ident);
12560            }
12561        }
12562    }
12563
12564    @Override
12565    public void notifyLockedProfile(@UserIdInt int userId) {
12566        try {
12567            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12568                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12569            }
12570        } catch (RemoteException ex) {
12571            throw new SecurityException("Fail to check is caller a privileged app", ex);
12572        }
12573
12574        synchronized (this) {
12575            final long ident = Binder.clearCallingIdentity();
12576            try {
12577                if (mUserController.shouldConfirmCredentials(userId)) {
12578                    if (mKeyguardController.isKeyguardLocked()) {
12579                        // Showing launcher to avoid user entering credential twice.
12580                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12581                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12582                    }
12583                    mStackSupervisor.lockAllProfileTasks(userId);
12584                }
12585            } finally {
12586                Binder.restoreCallingIdentity(ident);
12587            }
12588        }
12589    }
12590
12591    @Override
12592    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12593        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12594        synchronized (this) {
12595            final long ident = Binder.clearCallingIdentity();
12596            try {
12597                mActivityStarter.startConfirmCredentialIntent(intent, options);
12598            } finally {
12599                Binder.restoreCallingIdentity(ident);
12600            }
12601        }
12602    }
12603
12604    @Override
12605    public void stopAppSwitches() {
12606        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12607                != PackageManager.PERMISSION_GRANTED) {
12608            throw new SecurityException("viewquires permission "
12609                    + android.Manifest.permission.STOP_APP_SWITCHES);
12610        }
12611
12612        synchronized(this) {
12613            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12614                    + APP_SWITCH_DELAY_TIME;
12615            mDidAppSwitch = false;
12616            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12617            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12618            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12619        }
12620    }
12621
12622    public void resumeAppSwitches() {
12623        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12624                != PackageManager.PERMISSION_GRANTED) {
12625            throw new SecurityException("Requires permission "
12626                    + android.Manifest.permission.STOP_APP_SWITCHES);
12627        }
12628
12629        synchronized(this) {
12630            // Note that we don't execute any pending app switches... we will
12631            // let those wait until either the timeout, or the next start
12632            // activity request.
12633            mAppSwitchesAllowedTime = 0;
12634        }
12635    }
12636
12637    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12638            int callingPid, int callingUid, String name) {
12639        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12640            return true;
12641        }
12642
12643        int perm = checkComponentPermission(
12644                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12645                sourceUid, -1, true);
12646        if (perm == PackageManager.PERMISSION_GRANTED) {
12647            return true;
12648        }
12649
12650        // If the actual IPC caller is different from the logical source, then
12651        // also see if they are allowed to control app switches.
12652        if (callingUid != -1 && callingUid != sourceUid) {
12653            perm = checkComponentPermission(
12654                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12655                    callingUid, -1, true);
12656            if (perm == PackageManager.PERMISSION_GRANTED) {
12657                return true;
12658            }
12659        }
12660
12661        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12662        return false;
12663    }
12664
12665    public void setDebugApp(String packageName, boolean waitForDebugger,
12666            boolean persistent) {
12667        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12668                "setDebugApp()");
12669
12670        long ident = Binder.clearCallingIdentity();
12671        try {
12672            // Note that this is not really thread safe if there are multiple
12673            // callers into it at the same time, but that's not a situation we
12674            // care about.
12675            if (persistent) {
12676                final ContentResolver resolver = mContext.getContentResolver();
12677                Settings.Global.putString(
12678                    resolver, Settings.Global.DEBUG_APP,
12679                    packageName);
12680                Settings.Global.putInt(
12681                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12682                    waitForDebugger ? 1 : 0);
12683            }
12684
12685            synchronized (this) {
12686                if (!persistent) {
12687                    mOrigDebugApp = mDebugApp;
12688                    mOrigWaitForDebugger = mWaitForDebugger;
12689                }
12690                mDebugApp = packageName;
12691                mWaitForDebugger = waitForDebugger;
12692                mDebugTransient = !persistent;
12693                if (packageName != null) {
12694                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12695                            false, UserHandle.USER_ALL, "set debug app");
12696                }
12697            }
12698        } finally {
12699            Binder.restoreCallingIdentity(ident);
12700        }
12701    }
12702
12703    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12704        synchronized (this) {
12705            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12706            if (!isDebuggable) {
12707                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12708                    throw new SecurityException("Process not debuggable: " + app.packageName);
12709                }
12710            }
12711
12712            mTrackAllocationApp = processName;
12713        }
12714    }
12715
12716    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12717        synchronized (this) {
12718            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12719            if (!isDebuggable) {
12720                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12721                    throw new SecurityException("Process not debuggable: " + app.packageName);
12722                }
12723            }
12724            mProfileApp = processName;
12725
12726            if (mProfilerInfo != null) {
12727                if (mProfilerInfo.profileFd != null) {
12728                    try {
12729                        mProfilerInfo.profileFd.close();
12730                    } catch (IOException e) {
12731                    }
12732                }
12733            }
12734            mProfilerInfo = new ProfilerInfo(profilerInfo);
12735            mProfileType = 0;
12736        }
12737    }
12738
12739    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12740        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12741        if (!isDebuggable) {
12742            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12743                throw new SecurityException("Process not debuggable: " + app.packageName);
12744            }
12745        }
12746        mNativeDebuggingApp = processName;
12747    }
12748
12749    @Override
12750    public void setAlwaysFinish(boolean enabled) {
12751        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12752                "setAlwaysFinish()");
12753
12754        long ident = Binder.clearCallingIdentity();
12755        try {
12756            Settings.Global.putInt(
12757                    mContext.getContentResolver(),
12758                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12759
12760            synchronized (this) {
12761                mAlwaysFinishActivities = enabled;
12762            }
12763        } finally {
12764            Binder.restoreCallingIdentity(ident);
12765        }
12766    }
12767
12768    @Override
12769    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12770        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12771                "setActivityController()");
12772        synchronized (this) {
12773            mController = controller;
12774            mControllerIsAMonkey = imAMonkey;
12775            Watchdog.getInstance().setActivityController(controller);
12776        }
12777    }
12778
12779    @Override
12780    public void setUserIsMonkey(boolean userIsMonkey) {
12781        synchronized (this) {
12782            synchronized (mPidsSelfLocked) {
12783                final int callingPid = Binder.getCallingPid();
12784                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12785                if (proc == null) {
12786                    throw new SecurityException("Unknown process: " + callingPid);
12787                }
12788                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12789                    throw new SecurityException("Only an instrumentation process "
12790                            + "with a UiAutomation can call setUserIsMonkey");
12791                }
12792            }
12793            mUserIsMonkey = userIsMonkey;
12794        }
12795    }
12796
12797    @Override
12798    public boolean isUserAMonkey() {
12799        synchronized (this) {
12800            // If there is a controller also implies the user is a monkey.
12801            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12802        }
12803    }
12804
12805    /**
12806     * @deprecated This method is only used by a few internal components and it will soon be
12807     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12808     * No new code should be calling it.
12809     */
12810    @Deprecated
12811    @Override
12812    public void requestBugReport(int bugreportType) {
12813        String extraOptions = null;
12814        switch (bugreportType) {
12815            case ActivityManager.BUGREPORT_OPTION_FULL:
12816                // Default options.
12817                break;
12818            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12819                extraOptions = "bugreportplus";
12820                break;
12821            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12822                extraOptions = "bugreportremote";
12823                break;
12824            case ActivityManager.BUGREPORT_OPTION_WEAR:
12825                extraOptions = "bugreportwear";
12826                break;
12827            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12828                extraOptions = "bugreporttelephony";
12829                break;
12830            default:
12831                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12832                        + bugreportType);
12833        }
12834        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12835        if (extraOptions != null) {
12836            SystemProperties.set("dumpstate.options", extraOptions);
12837        }
12838        SystemProperties.set("ctl.start", "bugreport");
12839    }
12840
12841    /**
12842     * @deprecated This method is only used by a few internal components and it will soon be
12843     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12844     * No new code should be calling it.
12845     */
12846    @Deprecated
12847    @Override
12848    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12849
12850        if (!TextUtils.isEmpty(shareTitle)) {
12851            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12852                String errorStr = "shareTitle should be less than " +
12853                        MAX_BUGREPORT_TITLE_SIZE + " characters";
12854                throw new IllegalArgumentException(errorStr);
12855            } else {
12856                if (!TextUtils.isEmpty(shareDescription)) {
12857                    int length;
12858                    try {
12859                        length = shareDescription.getBytes("UTF-8").length;
12860                    } catch (UnsupportedEncodingException e) {
12861                        String errorStr = "shareDescription: UnsupportedEncodingException";
12862                        throw new IllegalArgumentException(errorStr);
12863                    }
12864                    if (length > SystemProperties.PROP_VALUE_MAX) {
12865                        String errorStr = "shareTitle should be less than " +
12866                                SystemProperties.PROP_VALUE_MAX + " bytes";
12867                        throw new IllegalArgumentException(errorStr);
12868                    } else {
12869                        SystemProperties.set("dumpstate.options.description", shareDescription);
12870                    }
12871                }
12872                SystemProperties.set("dumpstate.options.title", shareTitle);
12873            }
12874        }
12875
12876        Slog.d(TAG, "Bugreport notification title " + shareTitle
12877                + " description " + shareDescription);
12878        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12879    }
12880
12881    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12882        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12883    }
12884
12885    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12886        if (r != null && (r.instr != null || r.usingWrapper)) {
12887            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12888        }
12889        return KEY_DISPATCHING_TIMEOUT;
12890    }
12891
12892    @Override
12893    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12894        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12895                != PackageManager.PERMISSION_GRANTED) {
12896            throw new SecurityException("Requires permission "
12897                    + android.Manifest.permission.FILTER_EVENTS);
12898        }
12899        ProcessRecord proc;
12900        long timeout;
12901        synchronized (this) {
12902            synchronized (mPidsSelfLocked) {
12903                proc = mPidsSelfLocked.get(pid);
12904            }
12905            timeout = getInputDispatchingTimeoutLocked(proc);
12906        }
12907
12908        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12909            return -1;
12910        }
12911
12912        return timeout;
12913    }
12914
12915    /**
12916     * Handle input dispatching timeouts.
12917     * Returns whether input dispatching should be aborted or not.
12918     */
12919    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12920            final ActivityRecord activity, final ActivityRecord parent,
12921            final boolean aboveSystem, String reason) {
12922        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12923                != PackageManager.PERMISSION_GRANTED) {
12924            throw new SecurityException("Requires permission "
12925                    + android.Manifest.permission.FILTER_EVENTS);
12926        }
12927
12928        final String annotation;
12929        if (reason == null) {
12930            annotation = "Input dispatching timed out";
12931        } else {
12932            annotation = "Input dispatching timed out (" + reason + ")";
12933        }
12934
12935        if (proc != null) {
12936            synchronized (this) {
12937                if (proc.debugging) {
12938                    return false;
12939                }
12940
12941                if (proc.instr != null) {
12942                    Bundle info = new Bundle();
12943                    info.putString("shortMsg", "keyDispatchingTimedOut");
12944                    info.putString("longMsg", annotation);
12945                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12946                    return true;
12947                }
12948            }
12949            mHandler.post(new Runnable() {
12950                @Override
12951                public void run() {
12952                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12953                }
12954            });
12955        }
12956
12957        return true;
12958    }
12959
12960    @Override
12961    public Bundle getAssistContextExtras(int requestType) {
12962        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12963                null, null, true /* focused */, true /* newSessionId */,
12964                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12965        if (pae == null) {
12966            return null;
12967        }
12968        synchronized (pae) {
12969            while (!pae.haveResult) {
12970                try {
12971                    pae.wait();
12972                } catch (InterruptedException e) {
12973                }
12974            }
12975        }
12976        synchronized (this) {
12977            buildAssistBundleLocked(pae, pae.result);
12978            mPendingAssistExtras.remove(pae);
12979            mUiHandler.removeCallbacks(pae);
12980        }
12981        return pae.extras;
12982    }
12983
12984    @Override
12985    public boolean isAssistDataAllowedOnCurrentActivity() {
12986        int userId;
12987        synchronized (this) {
12988            final ActivityStack focusedStack = getFocusedStack();
12989            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
12990                return false;
12991            }
12992
12993            final ActivityRecord activity = focusedStack.topActivity();
12994            if (activity == null) {
12995                return false;
12996            }
12997            userId = activity.userId;
12998        }
12999        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13000                Context.DEVICE_POLICY_SERVICE);
13001        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13002    }
13003
13004    @Override
13005    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13006        long ident = Binder.clearCallingIdentity();
13007        try {
13008            synchronized (this) {
13009                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13010                ActivityRecord top = getFocusedStack().topActivity();
13011                if (top != caller) {
13012                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13013                            + " is not current top " + top);
13014                    return false;
13015                }
13016                if (!top.nowVisible) {
13017                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13018                            + " is not visible");
13019                    return false;
13020                }
13021            }
13022            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13023                    token);
13024        } finally {
13025            Binder.restoreCallingIdentity(ident);
13026        }
13027    }
13028
13029    @Override
13030    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13031            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13032        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13033                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13034                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13035    }
13036
13037    @Override
13038    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13039            IBinder activityToken, int flags) {
13040        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13041                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13042                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13043    }
13044
13045    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13046            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13047            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13048            int flags) {
13049        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13050                "enqueueAssistContext()");
13051
13052        synchronized (this) {
13053            ActivityRecord activity = getFocusedStack().topActivity();
13054            if (activity == null) {
13055                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13056                return null;
13057            }
13058            if (activity.app == null || activity.app.thread == null) {
13059                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13060                return null;
13061            }
13062            if (focused) {
13063                if (activityToken != null) {
13064                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13065                    if (activity != caller) {
13066                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13067                                + " is not current top " + activity);
13068                        return null;
13069                    }
13070                }
13071            } else {
13072                activity = ActivityRecord.forTokenLocked(activityToken);
13073                if (activity == null) {
13074                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13075                            + " couldn't be found");
13076                    return null;
13077                }
13078                if (activity.app == null || activity.app.thread == null) {
13079                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13080                    return null;
13081                }
13082            }
13083
13084            PendingAssistExtras pae;
13085            Bundle extras = new Bundle();
13086            if (args != null) {
13087                extras.putAll(args);
13088            }
13089            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13090            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13091
13092            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13093                    userHandle);
13094            pae.isHome = activity.isActivityTypeHome();
13095
13096            // Increment the sessionId if necessary
13097            if (newSessionId) {
13098                mViSessionId++;
13099            }
13100            try {
13101                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13102                        mViSessionId, flags);
13103                mPendingAssistExtras.add(pae);
13104                mUiHandler.postDelayed(pae, timeout);
13105            } catch (RemoteException e) {
13106                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13107                return null;
13108            }
13109            return pae;
13110        }
13111    }
13112
13113    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13114        IResultReceiver receiver;
13115        synchronized (this) {
13116            mPendingAssistExtras.remove(pae);
13117            receiver = pae.receiver;
13118        }
13119        if (receiver != null) {
13120            // Caller wants result sent back to them.
13121            Bundle sendBundle = new Bundle();
13122            // At least return the receiver extras
13123            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13124                    pae.receiverExtras);
13125            try {
13126                pae.receiver.send(0, sendBundle);
13127            } catch (RemoteException e) {
13128            }
13129        }
13130    }
13131
13132    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13133        if (result != null) {
13134            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13135        }
13136        if (pae.hint != null) {
13137            pae.extras.putBoolean(pae.hint, true);
13138        }
13139    }
13140
13141    /** Called from an app when assist data is ready. */
13142    @Override
13143    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13144            AssistContent content, Uri referrer) {
13145        PendingAssistExtras pae = (PendingAssistExtras)token;
13146        synchronized (pae) {
13147            pae.result = extras;
13148            pae.structure = structure;
13149            pae.content = content;
13150            if (referrer != null) {
13151                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13152            }
13153            if (structure != null) {
13154                structure.setHomeActivity(pae.isHome);
13155            }
13156            pae.haveResult = true;
13157            pae.notifyAll();
13158            if (pae.intent == null && pae.receiver == null) {
13159                // Caller is just waiting for the result.
13160                return;
13161            }
13162        }
13163        // We are now ready to launch the assist activity.
13164        IResultReceiver sendReceiver = null;
13165        Bundle sendBundle = null;
13166        synchronized (this) {
13167            buildAssistBundleLocked(pae, extras);
13168            boolean exists = mPendingAssistExtras.remove(pae);
13169            mUiHandler.removeCallbacks(pae);
13170            if (!exists) {
13171                // Timed out.
13172                return;
13173            }
13174            if ((sendReceiver=pae.receiver) != null) {
13175                // Caller wants result sent back to them.
13176                sendBundle = new Bundle();
13177                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13178                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13179                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13180                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13181                        pae.receiverExtras);
13182            }
13183        }
13184        if (sendReceiver != null) {
13185            try {
13186                sendReceiver.send(0, sendBundle);
13187            } catch (RemoteException e) {
13188            }
13189            return;
13190        }
13191
13192        final long ident = Binder.clearCallingIdentity();
13193        try {
13194            if (TextUtils.equals(pae.intent.getAction(),
13195                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13196                pae.intent.putExtras(pae.extras);
13197                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13198            } else {
13199                pae.intent.replaceExtras(pae.extras);
13200                pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13201                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
13202                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13203                closeSystemDialogs("assist");
13204
13205                try {
13206                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13207                } catch (ActivityNotFoundException e) {
13208                    Slog.w(TAG, "No activity to handle assist action.", e);
13209                }
13210            }
13211        } finally {
13212            Binder.restoreCallingIdentity(ident);
13213        }
13214    }
13215
13216    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13217            Bundle args) {
13218        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13219                true /* focused */, true /* newSessionId */, userHandle, args,
13220                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13221    }
13222
13223    public void registerProcessObserver(IProcessObserver observer) {
13224        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13225                "registerProcessObserver()");
13226        synchronized (this) {
13227            mProcessObservers.register(observer);
13228        }
13229    }
13230
13231    @Override
13232    public void unregisterProcessObserver(IProcessObserver observer) {
13233        synchronized (this) {
13234            mProcessObservers.unregister(observer);
13235        }
13236    }
13237
13238    @Override
13239    public int getUidProcessState(int uid, String callingPackage) {
13240        if (!hasUsageStatsPermission(callingPackage)) {
13241            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13242                    "getUidProcessState");
13243        }
13244
13245        synchronized (this) {
13246            UidRecord uidRec = mActiveUids.get(uid);
13247            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13248        }
13249    }
13250
13251    @Override
13252    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13253            String callingPackage) {
13254        if (!hasUsageStatsPermission(callingPackage)) {
13255            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13256                    "registerUidObserver");
13257        }
13258        synchronized (this) {
13259            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13260                    callingPackage, which, cutpoint));
13261        }
13262    }
13263
13264    @Override
13265    public void unregisterUidObserver(IUidObserver observer) {
13266        synchronized (this) {
13267            mUidObservers.unregister(observer);
13268        }
13269    }
13270
13271    @Override
13272    public boolean convertFromTranslucent(IBinder token) {
13273        final long origId = Binder.clearCallingIdentity();
13274        try {
13275            synchronized (this) {
13276                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13277                if (r == null) {
13278                    return false;
13279                }
13280                final boolean translucentChanged = r.changeWindowTranslucency(true);
13281                if (translucentChanged) {
13282                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13283                }
13284                mWindowManager.setAppFullscreen(token, true);
13285                return translucentChanged;
13286            }
13287        } finally {
13288            Binder.restoreCallingIdentity(origId);
13289        }
13290    }
13291
13292    @Override
13293    public boolean convertToTranslucent(IBinder token, Bundle options) {
13294        final long origId = Binder.clearCallingIdentity();
13295        try {
13296            synchronized (this) {
13297                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13298                if (r == null) {
13299                    return false;
13300                }
13301                final TaskRecord task = r.getTask();
13302                int index = task.mActivities.lastIndexOf(r);
13303                if (index > 0) {
13304                    ActivityRecord under = task.mActivities.get(index - 1);
13305                    under.returningOptions = ActivityOptions.fromBundle(options);
13306                }
13307                final boolean translucentChanged = r.changeWindowTranslucency(false);
13308                if (translucentChanged) {
13309                    r.getStack().convertActivityToTranslucent(r);
13310                }
13311                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13312                mWindowManager.setAppFullscreen(token, false);
13313                return translucentChanged;
13314            }
13315        } finally {
13316            Binder.restoreCallingIdentity(origId);
13317        }
13318    }
13319
13320    @Override
13321    public Bundle getActivityOptions(IBinder token) {
13322        final long origId = Binder.clearCallingIdentity();
13323        try {
13324            synchronized (this) {
13325                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13326                if (r != null) {
13327                    final ActivityOptions activityOptions = r.takeOptionsLocked();
13328                    return activityOptions == null ? null : activityOptions.toBundle();
13329                }
13330                return null;
13331            }
13332        } finally {
13333            Binder.restoreCallingIdentity(origId);
13334        }
13335    }
13336
13337    @Override
13338    public void setImmersive(IBinder token, boolean immersive) {
13339        synchronized(this) {
13340            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13341            if (r == null) {
13342                throw new IllegalArgumentException();
13343            }
13344            r.immersive = immersive;
13345
13346            // update associated state if we're frontmost
13347            if (r == mStackSupervisor.getResumedActivityLocked()) {
13348                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13349                applyUpdateLockStateLocked(r);
13350            }
13351        }
13352    }
13353
13354    @Override
13355    public boolean isImmersive(IBinder token) {
13356        synchronized (this) {
13357            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13358            if (r == null) {
13359                throw new IllegalArgumentException();
13360            }
13361            return r.immersive;
13362        }
13363    }
13364
13365    @Override
13366    public void setVrThread(int tid) {
13367        enforceSystemHasVrFeature();
13368        synchronized (this) {
13369            synchronized (mPidsSelfLocked) {
13370                final int pid = Binder.getCallingPid();
13371                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13372                mVrController.setVrThreadLocked(tid, pid, proc);
13373            }
13374        }
13375    }
13376
13377    @Override
13378    public void setPersistentVrThread(int tid) {
13379        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13380            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13381                    + Binder.getCallingPid()
13382                    + ", uid=" + Binder.getCallingUid()
13383                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13384            Slog.w(TAG, msg);
13385            throw new SecurityException(msg);
13386        }
13387        enforceSystemHasVrFeature();
13388        synchronized (this) {
13389            synchronized (mPidsSelfLocked) {
13390                final int pid = Binder.getCallingPid();
13391                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13392                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13393            }
13394        }
13395    }
13396
13397    /**
13398     * Schedule the given thread a normal scheduling priority.
13399     *
13400     * @param tid the tid of the thread to adjust the scheduling of.
13401     * @param suppressLogs {@code true} if any error logging should be disabled.
13402     *
13403     * @return {@code true} if this succeeded.
13404     */
13405    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13406        try {
13407            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13408            return true;
13409        } catch (IllegalArgumentException e) {
13410            if (!suppressLogs) {
13411                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13412            }
13413        } catch (SecurityException e) {
13414            if (!suppressLogs) {
13415                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13416            }
13417        }
13418        return false;
13419    }
13420
13421    /**
13422     * Schedule the given thread an FIFO scheduling priority.
13423     *
13424     * @param tid the tid of the thread to adjust the scheduling of.
13425     * @param suppressLogs {@code true} if any error logging should be disabled.
13426     *
13427     * @return {@code true} if this succeeded.
13428     */
13429    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13430        try {
13431            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13432            return true;
13433        } catch (IllegalArgumentException e) {
13434            if (!suppressLogs) {
13435                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13436            }
13437        } catch (SecurityException e) {
13438            if (!suppressLogs) {
13439                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13440            }
13441        }
13442        return false;
13443    }
13444
13445    /**
13446     * Check that we have the features required for VR-related API calls, and throw an exception if
13447     * not.
13448     */
13449    private void enforceSystemHasVrFeature() {
13450        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13451            throw new UnsupportedOperationException("VR mode not supported on this device!");
13452        }
13453    }
13454
13455    @Override
13456    public void setRenderThread(int tid) {
13457        synchronized (this) {
13458            ProcessRecord proc;
13459            int pid = Binder.getCallingPid();
13460            if (pid == Process.myPid()) {
13461                demoteSystemServerRenderThread(tid);
13462                return;
13463            }
13464            synchronized (mPidsSelfLocked) {
13465                proc = mPidsSelfLocked.get(pid);
13466                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13467                    // ensure the tid belongs to the process
13468                    if (!isThreadInProcess(pid, tid)) {
13469                        throw new IllegalArgumentException(
13470                            "Render thread does not belong to process");
13471                    }
13472                    proc.renderThreadTid = tid;
13473                    if (DEBUG_OOM_ADJ) {
13474                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13475                    }
13476                    // promote to FIFO now
13477                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13478                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13479                        if (mUseFifoUiScheduling) {
13480                            setThreadScheduler(proc.renderThreadTid,
13481                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13482                        } else {
13483                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13484                        }
13485                    }
13486                } else {
13487                    if (DEBUG_OOM_ADJ) {
13488                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13489                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13490                               mUseFifoUiScheduling);
13491                    }
13492                }
13493            }
13494        }
13495    }
13496
13497    /**
13498     * We only use RenderThread in system_server to store task snapshots to the disk, which should
13499     * happen in the background. Thus, demote render thread from system_server to a lower priority.
13500     *
13501     * @param tid the tid of the RenderThread
13502     */
13503    private void demoteSystemServerRenderThread(int tid) {
13504        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13505    }
13506
13507    @Override
13508    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13509        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13510            throw new UnsupportedOperationException("VR mode not supported on this device!");
13511        }
13512
13513        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13514
13515        ActivityRecord r;
13516        synchronized (this) {
13517            r = ActivityRecord.isInStackLocked(token);
13518        }
13519
13520        if (r == null) {
13521            throw new IllegalArgumentException();
13522        }
13523
13524        int err;
13525        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13526                VrManagerInternal.NO_ERROR) {
13527            return err;
13528        }
13529
13530        synchronized(this) {
13531            r.requestedVrComponent = (enabled) ? packageName : null;
13532
13533            // Update associated state if this activity is currently focused
13534            if (r == mStackSupervisor.getResumedActivityLocked()) {
13535                applyUpdateVrModeLocked(r);
13536            }
13537            return 0;
13538        }
13539    }
13540
13541    @Override
13542    public boolean isVrModePackageEnabled(ComponentName packageName) {
13543        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13544            throw new UnsupportedOperationException("VR mode not supported on this device!");
13545        }
13546
13547        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13548
13549        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13550                VrManagerInternal.NO_ERROR;
13551    }
13552
13553    public boolean isTopActivityImmersive() {
13554        enforceNotIsolatedCaller("startActivity");
13555        synchronized (this) {
13556            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13557            return (r != null) ? r.immersive : false;
13558        }
13559    }
13560
13561    /**
13562     * @return whether the system should disable UI modes incompatible with VR mode.
13563     */
13564    boolean shouldDisableNonVrUiLocked() {
13565        return mVrController.shouldDisableNonVrUiLocked();
13566    }
13567
13568    @Override
13569    public boolean isTopOfTask(IBinder token) {
13570        synchronized (this) {
13571            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13572            if (r == null) {
13573                throw new IllegalArgumentException();
13574            }
13575            return r.getTask().getTopActivity() == r;
13576        }
13577    }
13578
13579    @Override
13580    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13581        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13582            String msg = "Permission Denial: setHasTopUi() from pid="
13583                    + Binder.getCallingPid()
13584                    + ", uid=" + Binder.getCallingUid()
13585                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13586            Slog.w(TAG, msg);
13587            throw new SecurityException(msg);
13588        }
13589        final int pid = Binder.getCallingPid();
13590        final long origId = Binder.clearCallingIdentity();
13591        try {
13592            synchronized (this) {
13593                boolean changed = false;
13594                ProcessRecord pr;
13595                synchronized (mPidsSelfLocked) {
13596                    pr = mPidsSelfLocked.get(pid);
13597                    if (pr == null) {
13598                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13599                        return;
13600                    }
13601                    if (pr.hasTopUi != hasTopUi) {
13602                        if (DEBUG_OOM_ADJ) {
13603                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13604                        }
13605                        pr.hasTopUi = hasTopUi;
13606                        changed = true;
13607                    }
13608                }
13609                if (changed) {
13610                    updateOomAdjLocked(pr, true);
13611                }
13612            }
13613        } finally {
13614            Binder.restoreCallingIdentity(origId);
13615        }
13616    }
13617
13618    public final void enterSafeMode() {
13619        synchronized(this) {
13620            // It only makes sense to do this before the system is ready
13621            // and started launching other packages.
13622            if (!mSystemReady) {
13623                try {
13624                    AppGlobals.getPackageManager().enterSafeMode();
13625                } catch (RemoteException e) {
13626                }
13627            }
13628
13629            mSafeMode = true;
13630        }
13631    }
13632
13633    public final void showSafeModeOverlay() {
13634        View v = LayoutInflater.from(mContext).inflate(
13635                com.android.internal.R.layout.safe_mode, null);
13636        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13637        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13638        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13639        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13640        lp.gravity = Gravity.BOTTOM | Gravity.START;
13641        lp.format = v.getBackground().getOpacity();
13642        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13643                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13644        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13645        ((WindowManager)mContext.getSystemService(
13646                Context.WINDOW_SERVICE)).addView(v, lp);
13647    }
13648
13649    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13650        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13651            return;
13652        }
13653        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13654        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13655        synchronized (stats) {
13656            if (mBatteryStatsService.isOnBattery()) {
13657                mBatteryStatsService.enforceCallingPermission();
13658                int MY_UID = Binder.getCallingUid();
13659                final int uid;
13660                if (sender == null) {
13661                    uid = sourceUid;
13662                } else {
13663                    uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13664                }
13665                BatteryStatsImpl.Uid.Pkg pkg =
13666                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13667                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13668                pkg.noteWakeupAlarmLocked(tag);
13669            }
13670        }
13671    }
13672
13673    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13674        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13675            return;
13676        }
13677        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13678        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13679        synchronized (stats) {
13680            mBatteryStatsService.enforceCallingPermission();
13681            int MY_UID = Binder.getCallingUid();
13682            final int uid;
13683            if (sender == null) {
13684                uid = sourceUid;
13685            } else {
13686                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13687            }
13688            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13689        }
13690    }
13691
13692    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13693        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13694            return;
13695        }
13696        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13697        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13698        synchronized (stats) {
13699            mBatteryStatsService.enforceCallingPermission();
13700            int MY_UID = Binder.getCallingUid();
13701            final int uid;
13702            if (sender == null) {
13703                uid = sourceUid;
13704            } else {
13705                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13706            }
13707            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13708        }
13709    }
13710
13711    public boolean killPids(int[] pids, String pReason, boolean secure) {
13712        if (Binder.getCallingUid() != SYSTEM_UID) {
13713            throw new SecurityException("killPids only available to the system");
13714        }
13715        String reason = (pReason == null) ? "Unknown" : pReason;
13716        // XXX Note: don't acquire main activity lock here, because the window
13717        // manager calls in with its locks held.
13718
13719        boolean killed = false;
13720        synchronized (mPidsSelfLocked) {
13721            int worstType = 0;
13722            for (int i=0; i<pids.length; i++) {
13723                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13724                if (proc != null) {
13725                    int type = proc.setAdj;
13726                    if (type > worstType) {
13727                        worstType = type;
13728                    }
13729                }
13730            }
13731
13732            // If the worst oom_adj is somewhere in the cached proc LRU range,
13733            // then constrain it so we will kill all cached procs.
13734            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13735                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13736                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13737            }
13738
13739            // If this is not a secure call, don't let it kill processes that
13740            // are important.
13741            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13742                worstType = ProcessList.SERVICE_ADJ;
13743            }
13744
13745            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13746            for (int i=0; i<pids.length; i++) {
13747                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13748                if (proc == null) {
13749                    continue;
13750                }
13751                int adj = proc.setAdj;
13752                if (adj >= worstType && !proc.killedByAm) {
13753                    proc.kill(reason, true);
13754                    killed = true;
13755                }
13756            }
13757        }
13758        return killed;
13759    }
13760
13761    @Override
13762    public void killUid(int appId, int userId, String reason) {
13763        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13764        synchronized (this) {
13765            final long identity = Binder.clearCallingIdentity();
13766            try {
13767                killPackageProcessesLocked(null, appId, userId,
13768                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13769                        reason != null ? reason : "kill uid");
13770            } finally {
13771                Binder.restoreCallingIdentity(identity);
13772            }
13773        }
13774    }
13775
13776    @Override
13777    public boolean killProcessesBelowForeground(String reason) {
13778        if (Binder.getCallingUid() != SYSTEM_UID) {
13779            throw new SecurityException("killProcessesBelowForeground() only available to system");
13780        }
13781
13782        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13783    }
13784
13785    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13786        if (Binder.getCallingUid() != SYSTEM_UID) {
13787            throw new SecurityException("killProcessesBelowAdj() only available to system");
13788        }
13789
13790        boolean killed = false;
13791        synchronized (mPidsSelfLocked) {
13792            final int size = mPidsSelfLocked.size();
13793            for (int i = 0; i < size; i++) {
13794                final int pid = mPidsSelfLocked.keyAt(i);
13795                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13796                if (proc == null) continue;
13797
13798                final int adj = proc.setAdj;
13799                if (adj > belowAdj && !proc.killedByAm) {
13800                    proc.kill(reason, true);
13801                    killed = true;
13802                }
13803            }
13804        }
13805        return killed;
13806    }
13807
13808    @Override
13809    public void hang(final IBinder who, boolean allowRestart) {
13810        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13811                != PackageManager.PERMISSION_GRANTED) {
13812            throw new SecurityException("Requires permission "
13813                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13814        }
13815
13816        final IBinder.DeathRecipient death = new DeathRecipient() {
13817            @Override
13818            public void binderDied() {
13819                synchronized (this) {
13820                    notifyAll();
13821                }
13822            }
13823        };
13824
13825        try {
13826            who.linkToDeath(death, 0);
13827        } catch (RemoteException e) {
13828            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13829            return;
13830        }
13831
13832        synchronized (this) {
13833            Watchdog.getInstance().setAllowRestart(allowRestart);
13834            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13835            synchronized (death) {
13836                while (who.isBinderAlive()) {
13837                    try {
13838                        death.wait();
13839                    } catch (InterruptedException e) {
13840                    }
13841                }
13842            }
13843            Watchdog.getInstance().setAllowRestart(true);
13844        }
13845    }
13846
13847    @Override
13848    public void restart() {
13849        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13850                != PackageManager.PERMISSION_GRANTED) {
13851            throw new SecurityException("Requires permission "
13852                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13853        }
13854
13855        Log.i(TAG, "Sending shutdown broadcast...");
13856
13857        BroadcastReceiver br = new BroadcastReceiver() {
13858            @Override public void onReceive(Context context, Intent intent) {
13859                // Now the broadcast is done, finish up the low-level shutdown.
13860                Log.i(TAG, "Shutting down activity manager...");
13861                shutdown(10000);
13862                Log.i(TAG, "Shutdown complete, restarting!");
13863                killProcess(myPid());
13864                System.exit(10);
13865            }
13866        };
13867
13868        // First send the high-level shut down broadcast.
13869        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13870        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13871        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13872        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13873        mContext.sendOrderedBroadcastAsUser(intent,
13874                UserHandle.ALL, null, br, mHandler, 0, null, null);
13875        */
13876        br.onReceive(mContext, intent);
13877    }
13878
13879    private long getLowRamTimeSinceIdle(long now) {
13880        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13881    }
13882
13883    @Override
13884    public void performIdleMaintenance() {
13885        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13886                != PackageManager.PERMISSION_GRANTED) {
13887            throw new SecurityException("Requires permission "
13888                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13889        }
13890
13891        synchronized (this) {
13892            final long now = SystemClock.uptimeMillis();
13893            final long timeSinceLastIdle = now - mLastIdleTime;
13894            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13895            mLastIdleTime = now;
13896            mLowRamTimeSinceLastIdle = 0;
13897            if (mLowRamStartTime != 0) {
13898                mLowRamStartTime = now;
13899            }
13900
13901            StringBuilder sb = new StringBuilder(128);
13902            sb.append("Idle maintenance over ");
13903            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13904            sb.append(" low RAM for ");
13905            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13906            Slog.i(TAG, sb.toString());
13907
13908            // If at least 1/3 of our time since the last idle period has been spent
13909            // with RAM low, then we want to kill processes.
13910            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13911
13912            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13913                ProcessRecord proc = mLruProcesses.get(i);
13914                if (proc.notCachedSinceIdle) {
13915                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13916                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13917                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13918                        if (doKilling && proc.initialIdlePss != 0
13919                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13920                            sb = new StringBuilder(128);
13921                            sb.append("Kill");
13922                            sb.append(proc.processName);
13923                            sb.append(" in idle maint: pss=");
13924                            sb.append(proc.lastPss);
13925                            sb.append(", swapPss=");
13926                            sb.append(proc.lastSwapPss);
13927                            sb.append(", initialPss=");
13928                            sb.append(proc.initialIdlePss);
13929                            sb.append(", period=");
13930                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13931                            sb.append(", lowRamPeriod=");
13932                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13933                            Slog.wtfQuiet(TAG, sb.toString());
13934                            proc.kill("idle maint (pss " + proc.lastPss
13935                                    + " from " + proc.initialIdlePss + ")", true);
13936                        }
13937                    }
13938                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13939                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13940                    proc.notCachedSinceIdle = true;
13941                    proc.initialIdlePss = 0;
13942                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13943                            mTestPssMode, isSleepingLocked(), now);
13944                }
13945            }
13946
13947            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13948            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13949        }
13950    }
13951
13952    @Override
13953    public void sendIdleJobTrigger() {
13954        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13955                != PackageManager.PERMISSION_GRANTED) {
13956            throw new SecurityException("Requires permission "
13957                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13958        }
13959
13960        final long ident = Binder.clearCallingIdentity();
13961        try {
13962            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13963                    .setPackage("android")
13964                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13965            broadcastIntent(null, intent, null, null, 0, null, null, null,
13966                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13967        } finally {
13968            Binder.restoreCallingIdentity(ident);
13969        }
13970    }
13971
13972    private void retrieveSettings() {
13973        final ContentResolver resolver = mContext.getContentResolver();
13974        final boolean freeformWindowManagement =
13975                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13976                        || Settings.Global.getInt(
13977                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13978        final boolean supportsPictureInPicture =
13979                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13980
13981        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
13982        final boolean supportsSplitScreenMultiWindow =
13983                ActivityManager.supportsSplitScreenMultiWindow(mContext);
13984        final boolean supportsMultiDisplay = mContext.getPackageManager()
13985                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
13986        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13987        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13988        final boolean alwaysFinishActivities =
13989                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13990        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13991        final boolean forceResizable = Settings.Global.getInt(
13992                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13993        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
13994                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
13995        final boolean supportsLeanbackOnly =
13996                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13997
13998        // Transfer any global setting for forcing RTL layout, into a System Property
13999        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14000
14001        final Configuration configuration = new Configuration();
14002        Settings.System.getConfiguration(resolver, configuration);
14003        if (forceRtl) {
14004            // This will take care of setting the correct layout direction flags
14005            configuration.setLayoutDirection(configuration.locale);
14006        }
14007
14008        synchronized (this) {
14009            mDebugApp = mOrigDebugApp = debugApp;
14010            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14011            mAlwaysFinishActivities = alwaysFinishActivities;
14012            mSupportsLeanbackOnly = supportsLeanbackOnly;
14013            mForceResizableActivities = forceResizable;
14014            final boolean multiWindowFormEnabled = freeformWindowManagement
14015                    || supportsSplitScreenMultiWindow
14016                    || supportsPictureInPicture
14017                    || supportsMultiDisplay;
14018            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14019                mSupportsMultiWindow = true;
14020                mSupportsFreeformWindowManagement = freeformWindowManagement;
14021                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14022                mSupportsPictureInPicture = supportsPictureInPicture;
14023                mSupportsMultiDisplay = supportsMultiDisplay;
14024            } else {
14025                mSupportsMultiWindow = false;
14026                mSupportsFreeformWindowManagement = false;
14027                mSupportsSplitScreenMultiWindow = false;
14028                mSupportsPictureInPicture = false;
14029                mSupportsMultiDisplay = false;
14030            }
14031            mWindowManager.setForceResizableTasks(mForceResizableActivities);
14032            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14033            // This happens before any activities are started, so we can change global configuration
14034            // in-place.
14035            updateConfigurationLocked(configuration, null, true);
14036            final Configuration globalConfig = getGlobalConfiguration();
14037            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14038
14039            // Load resources only after the current configuration has been set.
14040            final Resources res = mContext.getResources();
14041            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14042            mThumbnailWidth = res.getDimensionPixelSize(
14043                    com.android.internal.R.dimen.thumbnail_width);
14044            mThumbnailHeight = res.getDimensionPixelSize(
14045                    com.android.internal.R.dimen.thumbnail_height);
14046            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14047                    com.android.internal.R.string.config_appsNotReportingCrashes));
14048            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14049                    com.android.internal.R.bool.config_customUserSwitchUi);
14050            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14051                mFullscreenThumbnailScale = (float) res
14052                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14053                    (float) globalConfig.screenWidthDp;
14054            } else {
14055                mFullscreenThumbnailScale = res.getFraction(
14056                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14057            }
14058            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14059        }
14060    }
14061
14062    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14063        traceLog.traceBegin("PhaseActivityManagerReady");
14064        synchronized(this) {
14065            if (mSystemReady) {
14066                // If we're done calling all the receivers, run the next "boot phase" passed in
14067                // by the SystemServer
14068                if (goingCallback != null) {
14069                    goingCallback.run();
14070                }
14071                return;
14072            }
14073
14074            mLocalDeviceIdleController
14075                    = LocalServices.getService(DeviceIdleController.LocalService.class);
14076            mAssistUtils = new AssistUtils(mContext);
14077            mVrController.onSystemReady();
14078            // Make sure we have the current profile info, since it is needed for security checks.
14079            mUserController.onSystemReady();
14080            mRecentTasks.onSystemReadyLocked();
14081            mAppOpsService.systemReady();
14082            mSystemReady = true;
14083        }
14084
14085        try {
14086            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14087                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14088                    .getSerial();
14089        } catch (RemoteException e) {}
14090
14091        ArrayList<ProcessRecord> procsToKill = null;
14092        synchronized(mPidsSelfLocked) {
14093            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14094                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14095                if (!isAllowedWhileBooting(proc.info)){
14096                    if (procsToKill == null) {
14097                        procsToKill = new ArrayList<ProcessRecord>();
14098                    }
14099                    procsToKill.add(proc);
14100                }
14101            }
14102        }
14103
14104        synchronized(this) {
14105            if (procsToKill != null) {
14106                for (int i=procsToKill.size()-1; i>=0; i--) {
14107                    ProcessRecord proc = procsToKill.get(i);
14108                    Slog.i(TAG, "Removing system update proc: " + proc);
14109                    removeProcessLocked(proc, true, false, "system update done");
14110                }
14111            }
14112
14113            // Now that we have cleaned up any update processes, we
14114            // are ready to start launching real processes and know that
14115            // we won't trample on them any more.
14116            mProcessesReady = true;
14117        }
14118
14119        Slog.i(TAG, "System now ready");
14120        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14121            SystemClock.uptimeMillis());
14122
14123        synchronized(this) {
14124            // Make sure we have no pre-ready processes sitting around.
14125
14126            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14127                ResolveInfo ri = mContext.getPackageManager()
14128                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14129                                STOCK_PM_FLAGS);
14130                CharSequence errorMsg = null;
14131                if (ri != null) {
14132                    ActivityInfo ai = ri.activityInfo;
14133                    ApplicationInfo app = ai.applicationInfo;
14134                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14135                        mTopAction = Intent.ACTION_FACTORY_TEST;
14136                        mTopData = null;
14137                        mTopComponent = new ComponentName(app.packageName,
14138                                ai.name);
14139                    } else {
14140                        errorMsg = mContext.getResources().getText(
14141                                com.android.internal.R.string.factorytest_not_system);
14142                    }
14143                } else {
14144                    errorMsg = mContext.getResources().getText(
14145                            com.android.internal.R.string.factorytest_no_action);
14146                }
14147                if (errorMsg != null) {
14148                    mTopAction = null;
14149                    mTopData = null;
14150                    mTopComponent = null;
14151                    Message msg = Message.obtain();
14152                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14153                    msg.getData().putCharSequence("msg", errorMsg);
14154                    mUiHandler.sendMessage(msg);
14155                }
14156            }
14157        }
14158
14159        retrieveSettings();
14160        final int currentUserId;
14161        synchronized (this) {
14162            currentUserId = mUserController.getCurrentUserIdLocked();
14163            readGrantedUriPermissionsLocked();
14164        }
14165
14166        if (goingCallback != null) goingCallback.run();
14167        traceLog.traceBegin("ActivityManagerStartApps");
14168        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14169                Integer.toString(currentUserId), currentUserId);
14170        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14171                Integer.toString(currentUserId), currentUserId);
14172        mSystemServiceManager.startUser(currentUserId);
14173
14174        synchronized (this) {
14175            // Only start up encryption-aware persistent apps; once user is
14176            // unlocked we'll come back around and start unaware apps
14177            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14178
14179            // Start up initial activity.
14180            mBooting = true;
14181            // Enable home activity for system user, so that the system can always boot. We don't
14182            // do this when the system user is not setup since the setup wizard should be the one
14183            // to handle home activity in this case.
14184            if (UserManager.isSplitSystemUser() &&
14185                    Settings.Secure.getInt(mContext.getContentResolver(),
14186                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14187                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14188                try {
14189                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14190                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14191                            UserHandle.USER_SYSTEM);
14192                } catch (RemoteException e) {
14193                    throw e.rethrowAsRuntimeException();
14194                }
14195            }
14196            startHomeActivityLocked(currentUserId, "systemReady");
14197
14198            try {
14199                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14200                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14201                            + " data partition or your device will be unstable.");
14202                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14203                }
14204            } catch (RemoteException e) {
14205            }
14206
14207            if (!Build.isBuildConsistent()) {
14208                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14209                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14210            }
14211
14212            long ident = Binder.clearCallingIdentity();
14213            try {
14214                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14215                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14216                        | Intent.FLAG_RECEIVER_FOREGROUND);
14217                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14218                broadcastIntentLocked(null, null, intent,
14219                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14220                        null, false, false, MY_PID, SYSTEM_UID,
14221                        currentUserId);
14222                intent = new Intent(Intent.ACTION_USER_STARTING);
14223                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14224                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14225                broadcastIntentLocked(null, null, intent,
14226                        null, new IIntentReceiver.Stub() {
14227                            @Override
14228                            public void performReceive(Intent intent, int resultCode, String data,
14229                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14230                                    throws RemoteException {
14231                            }
14232                        }, 0, null, null,
14233                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14234                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14235            } catch (Throwable t) {
14236                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14237            } finally {
14238                Binder.restoreCallingIdentity(ident);
14239            }
14240            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14241            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14242            traceLog.traceEnd(); // ActivityManagerStartApps
14243            traceLog.traceEnd(); // PhaseActivityManagerReady
14244        }
14245    }
14246
14247    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14248        synchronized (this) {
14249            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14250        }
14251    }
14252
14253    void skipCurrentReceiverLocked(ProcessRecord app) {
14254        for (BroadcastQueue queue : mBroadcastQueues) {
14255            queue.skipCurrentReceiverLocked(app);
14256        }
14257    }
14258
14259    /**
14260     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14261     * The application process will exit immediately after this call returns.
14262     * @param app object of the crashing app, null for the system server
14263     * @param crashInfo describing the exception
14264     */
14265    public void handleApplicationCrash(IBinder app,
14266            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14267        ProcessRecord r = findAppProcess(app, "Crash");
14268        final String processName = app == null ? "system_server"
14269                : (r == null ? "unknown" : r.processName);
14270
14271        handleApplicationCrashInner("crash", r, processName, crashInfo);
14272    }
14273
14274    /* Native crash reporting uses this inner version because it needs to be somewhat
14275     * decoupled from the AM-managed cleanup lifecycle
14276     */
14277    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14278            ApplicationErrorReport.CrashInfo crashInfo) {
14279        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14280                UserHandle.getUserId(Binder.getCallingUid()), processName,
14281                r == null ? -1 : r.info.flags,
14282                crashInfo.exceptionClassName,
14283                crashInfo.exceptionMessage,
14284                crashInfo.throwFileName,
14285                crashInfo.throwLineNumber);
14286
14287        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14288
14289        mAppErrors.crashApplication(r, crashInfo);
14290    }
14291
14292    public void handleApplicationStrictModeViolation(
14293            IBinder app,
14294            int violationMask,
14295            StrictMode.ViolationInfo info) {
14296        ProcessRecord r = findAppProcess(app, "StrictMode");
14297        if (r == null) {
14298            return;
14299        }
14300
14301        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14302            Integer stackFingerprint = info.hashCode();
14303            boolean logIt = true;
14304            synchronized (mAlreadyLoggedViolatedStacks) {
14305                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14306                    logIt = false;
14307                    // TODO: sub-sample into EventLog for these, with
14308                    // the info.durationMillis?  Then we'd get
14309                    // the relative pain numbers, without logging all
14310                    // the stack traces repeatedly.  We'd want to do
14311                    // likewise in the client code, which also does
14312                    // dup suppression, before the Binder call.
14313                } else {
14314                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14315                        mAlreadyLoggedViolatedStacks.clear();
14316                    }
14317                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14318                }
14319            }
14320            if (logIt) {
14321                logStrictModeViolationToDropBox(r, info);
14322            }
14323        }
14324
14325        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14326            AppErrorResult result = new AppErrorResult();
14327            synchronized (this) {
14328                final long origId = Binder.clearCallingIdentity();
14329
14330                Message msg = Message.obtain();
14331                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14332                HashMap<String, Object> data = new HashMap<String, Object>();
14333                data.put("result", result);
14334                data.put("app", r);
14335                data.put("violationMask", violationMask);
14336                data.put("info", info);
14337                msg.obj = data;
14338                mUiHandler.sendMessage(msg);
14339
14340                Binder.restoreCallingIdentity(origId);
14341            }
14342            int res = result.get();
14343            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14344        }
14345    }
14346
14347    // Depending on the policy in effect, there could be a bunch of
14348    // these in quick succession so we try to batch these together to
14349    // minimize disk writes, number of dropbox entries, and maximize
14350    // compression, by having more fewer, larger records.
14351    private void logStrictModeViolationToDropBox(
14352            ProcessRecord process,
14353            StrictMode.ViolationInfo info) {
14354        if (info == null) {
14355            return;
14356        }
14357        final boolean isSystemApp = process == null ||
14358                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14359                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14360        final String processName = process == null ? "unknown" : process.processName;
14361        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14362        final DropBoxManager dbox = (DropBoxManager)
14363                mContext.getSystemService(Context.DROPBOX_SERVICE);
14364
14365        // Exit early if the dropbox isn't configured to accept this report type.
14366        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14367
14368        boolean bufferWasEmpty;
14369        boolean needsFlush;
14370        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14371        synchronized (sb) {
14372            bufferWasEmpty = sb.length() == 0;
14373            appendDropBoxProcessHeaders(process, processName, sb);
14374            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14375            sb.append("System-App: ").append(isSystemApp).append("\n");
14376            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14377            if (info.violationNumThisLoop != 0) {
14378                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14379            }
14380            if (info.numAnimationsRunning != 0) {
14381                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14382            }
14383            if (info.broadcastIntentAction != null) {
14384                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14385            }
14386            if (info.durationMillis != -1) {
14387                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14388            }
14389            if (info.numInstances != -1) {
14390                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14391            }
14392            if (info.tags != null) {
14393                for (String tag : info.tags) {
14394                    sb.append("Span-Tag: ").append(tag).append("\n");
14395                }
14396            }
14397            sb.append("\n");
14398            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14399                sb.append(info.crashInfo.stackTrace);
14400                sb.append("\n");
14401            }
14402            if (info.message != null) {
14403                sb.append(info.message);
14404                sb.append("\n");
14405            }
14406
14407            // Only buffer up to ~64k.  Various logging bits truncate
14408            // things at 128k.
14409            needsFlush = (sb.length() > 64 * 1024);
14410        }
14411
14412        // Flush immediately if the buffer's grown too large, or this
14413        // is a non-system app.  Non-system apps are isolated with a
14414        // different tag & policy and not batched.
14415        //
14416        // Batching is useful during internal testing with
14417        // StrictMode settings turned up high.  Without batching,
14418        // thousands of separate files could be created on boot.
14419        if (!isSystemApp || needsFlush) {
14420            new Thread("Error dump: " + dropboxTag) {
14421                @Override
14422                public void run() {
14423                    String report;
14424                    synchronized (sb) {
14425                        report = sb.toString();
14426                        sb.delete(0, sb.length());
14427                        sb.trimToSize();
14428                    }
14429                    if (report.length() != 0) {
14430                        dbox.addText(dropboxTag, report);
14431                    }
14432                }
14433            }.start();
14434            return;
14435        }
14436
14437        // System app batching:
14438        if (!bufferWasEmpty) {
14439            // An existing dropbox-writing thread is outstanding, so
14440            // we don't need to start it up.  The existing thread will
14441            // catch the buffer appends we just did.
14442            return;
14443        }
14444
14445        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14446        // (After this point, we shouldn't access AMS internal data structures.)
14447        new Thread("Error dump: " + dropboxTag) {
14448            @Override
14449            public void run() {
14450                // 5 second sleep to let stacks arrive and be batched together
14451                try {
14452                    Thread.sleep(5000);  // 5 seconds
14453                } catch (InterruptedException e) {}
14454
14455                String errorReport;
14456                synchronized (mStrictModeBuffer) {
14457                    errorReport = mStrictModeBuffer.toString();
14458                    if (errorReport.length() == 0) {
14459                        return;
14460                    }
14461                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14462                    mStrictModeBuffer.trimToSize();
14463                }
14464                dbox.addText(dropboxTag, errorReport);
14465            }
14466        }.start();
14467    }
14468
14469    /**
14470     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14471     * @param app object of the crashing app, null for the system server
14472     * @param tag reported by the caller
14473     * @param system whether this wtf is coming from the system
14474     * @param crashInfo describing the context of the error
14475     * @return true if the process should exit immediately (WTF is fatal)
14476     */
14477    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14478            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14479        final int callingUid = Binder.getCallingUid();
14480        final int callingPid = Binder.getCallingPid();
14481
14482        if (system) {
14483            // If this is coming from the system, we could very well have low-level
14484            // system locks held, so we want to do this all asynchronously.  And we
14485            // never want this to become fatal, so there is that too.
14486            mHandler.post(new Runnable() {
14487                @Override public void run() {
14488                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14489                }
14490            });
14491            return false;
14492        }
14493
14494        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14495                crashInfo);
14496
14497        final boolean isFatal = Build.IS_ENG || Settings.Global
14498                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14499        final boolean isSystem = (r == null) || r.persistent;
14500
14501        if (isFatal && !isSystem) {
14502            mAppErrors.crashApplication(r, crashInfo);
14503            return true;
14504        } else {
14505            return false;
14506        }
14507    }
14508
14509    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14510            final ApplicationErrorReport.CrashInfo crashInfo) {
14511        final ProcessRecord r = findAppProcess(app, "WTF");
14512        final String processName = app == null ? "system_server"
14513                : (r == null ? "unknown" : r.processName);
14514
14515        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14516                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14517
14518        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14519
14520        return r;
14521    }
14522
14523    /**
14524     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14525     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14526     */
14527    private ProcessRecord findAppProcess(IBinder app, String reason) {
14528        if (app == null) {
14529            return null;
14530        }
14531
14532        synchronized (this) {
14533            final int NP = mProcessNames.getMap().size();
14534            for (int ip=0; ip<NP; ip++) {
14535                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14536                final int NA = apps.size();
14537                for (int ia=0; ia<NA; ia++) {
14538                    ProcessRecord p = apps.valueAt(ia);
14539                    if (p.thread != null && p.thread.asBinder() == app) {
14540                        return p;
14541                    }
14542                }
14543            }
14544
14545            Slog.w(TAG, "Can't find mystery application for " + reason
14546                    + " from pid=" + Binder.getCallingPid()
14547                    + " uid=" + Binder.getCallingUid() + ": " + app);
14548            return null;
14549        }
14550    }
14551
14552    /**
14553     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14554     * to append various headers to the dropbox log text.
14555     */
14556    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14557            StringBuilder sb) {
14558        // Watchdog thread ends up invoking this function (with
14559        // a null ProcessRecord) to add the stack file to dropbox.
14560        // Do not acquire a lock on this (am) in such cases, as it
14561        // could cause a potential deadlock, if and when watchdog
14562        // is invoked due to unavailability of lock on am and it
14563        // would prevent watchdog from killing system_server.
14564        if (process == null) {
14565            sb.append("Process: ").append(processName).append("\n");
14566            return;
14567        }
14568        // Note: ProcessRecord 'process' is guarded by the service
14569        // instance.  (notably process.pkgList, which could otherwise change
14570        // concurrently during execution of this method)
14571        synchronized (this) {
14572            sb.append("Process: ").append(processName).append("\n");
14573            sb.append("PID: ").append(process.pid).append("\n");
14574            int flags = process.info.flags;
14575            IPackageManager pm = AppGlobals.getPackageManager();
14576            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14577            for (int ip=0; ip<process.pkgList.size(); ip++) {
14578                String pkg = process.pkgList.keyAt(ip);
14579                sb.append("Package: ").append(pkg);
14580                try {
14581                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14582                    if (pi != null) {
14583                        sb.append(" v").append(pi.versionCode);
14584                        if (pi.versionName != null) {
14585                            sb.append(" (").append(pi.versionName).append(")");
14586                        }
14587                    }
14588                } catch (RemoteException e) {
14589                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14590                }
14591                sb.append("\n");
14592            }
14593        }
14594    }
14595
14596    private static String processClass(ProcessRecord process) {
14597        if (process == null || process.pid == MY_PID) {
14598            return "system_server";
14599        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14600            return "system_app";
14601        } else {
14602            return "data_app";
14603        }
14604    }
14605
14606    private volatile long mWtfClusterStart;
14607    private volatile int mWtfClusterCount;
14608
14609    /**
14610     * Write a description of an error (crash, WTF, ANR) to the drop box.
14611     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14612     * @param process which caused the error, null means the system server
14613     * @param activity which triggered the error, null if unknown
14614     * @param parent activity related to the error, null if unknown
14615     * @param subject line related to the error, null if absent
14616     * @param report in long form describing the error, null if absent
14617     * @param dataFile text file to include in the report, null if none
14618     * @param crashInfo giving an application stack trace, null if absent
14619     */
14620    public void addErrorToDropBox(String eventType,
14621            ProcessRecord process, String processName, ActivityRecord activity,
14622            ActivityRecord parent, String subject,
14623            final String report, final File dataFile,
14624            final ApplicationErrorReport.CrashInfo crashInfo) {
14625        // NOTE -- this must never acquire the ActivityManagerService lock,
14626        // otherwise the watchdog may be prevented from resetting the system.
14627
14628        // Bail early if not published yet
14629        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14630        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14631
14632        // Exit early if the dropbox isn't configured to accept this report type.
14633        final String dropboxTag = processClass(process) + "_" + eventType;
14634        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14635
14636        // Rate-limit how often we're willing to do the heavy lifting below to
14637        // collect and record logs; currently 5 logs per 10 second period.
14638        final long now = SystemClock.elapsedRealtime();
14639        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14640            mWtfClusterStart = now;
14641            mWtfClusterCount = 1;
14642        } else {
14643            if (mWtfClusterCount++ >= 5) return;
14644        }
14645
14646        final StringBuilder sb = new StringBuilder(1024);
14647        appendDropBoxProcessHeaders(process, processName, sb);
14648        if (process != null) {
14649            sb.append("Foreground: ")
14650                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14651                    .append("\n");
14652        }
14653        if (activity != null) {
14654            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14655        }
14656        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14657            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14658        }
14659        if (parent != null && parent != activity) {
14660            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14661        }
14662        if (subject != null) {
14663            sb.append("Subject: ").append(subject).append("\n");
14664        }
14665        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14666        if (Debug.isDebuggerConnected()) {
14667            sb.append("Debugger: Connected\n");
14668        }
14669        sb.append("\n");
14670
14671        // Do the rest in a worker thread to avoid blocking the caller on I/O
14672        // (After this point, we shouldn't access AMS internal data structures.)
14673        Thread worker = new Thread("Error dump: " + dropboxTag) {
14674            @Override
14675            public void run() {
14676                if (report != null) {
14677                    sb.append(report);
14678                }
14679
14680                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14681                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14682                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14683                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14684
14685                if (dataFile != null && maxDataFileSize > 0) {
14686                    try {
14687                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14688                                    "\n\n[[TRUNCATED]]"));
14689                    } catch (IOException e) {
14690                        Slog.e(TAG, "Error reading " + dataFile, e);
14691                    }
14692                }
14693                if (crashInfo != null && crashInfo.stackTrace != null) {
14694                    sb.append(crashInfo.stackTrace);
14695                }
14696
14697                if (lines > 0) {
14698                    sb.append("\n");
14699
14700                    // Merge several logcat streams, and take the last N lines
14701                    InputStreamReader input = null;
14702                    try {
14703                        java.lang.Process logcat = new ProcessBuilder(
14704                                "/system/bin/timeout", "-k", "15s", "10s",
14705                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14706                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14707                                        .redirectErrorStream(true).start();
14708
14709                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14710                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14711                        input = new InputStreamReader(logcat.getInputStream());
14712
14713                        int num;
14714                        char[] buf = new char[8192];
14715                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14716                    } catch (IOException e) {
14717                        Slog.e(TAG, "Error running logcat", e);
14718                    } finally {
14719                        if (input != null) try { input.close(); } catch (IOException e) {}
14720                    }
14721                }
14722
14723                dbox.addText(dropboxTag, sb.toString());
14724            }
14725        };
14726
14727        if (process == null) {
14728            // If process is null, we are being called from some internal code
14729            // and may be about to die -- run this synchronously.
14730            worker.run();
14731        } else {
14732            worker.start();
14733        }
14734    }
14735
14736    @Override
14737    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14738        enforceNotIsolatedCaller("getProcessesInErrorState");
14739        // assume our apps are happy - lazy create the list
14740        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14741
14742        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14743                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14744        int userId = UserHandle.getUserId(Binder.getCallingUid());
14745
14746        synchronized (this) {
14747
14748            // iterate across all processes
14749            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14750                ProcessRecord app = mLruProcesses.get(i);
14751                if (!allUsers && app.userId != userId) {
14752                    continue;
14753                }
14754                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14755                    // This one's in trouble, so we'll generate a report for it
14756                    // crashes are higher priority (in case there's a crash *and* an anr)
14757                    ActivityManager.ProcessErrorStateInfo report = null;
14758                    if (app.crashing) {
14759                        report = app.crashingReport;
14760                    } else if (app.notResponding) {
14761                        report = app.notRespondingReport;
14762                    }
14763
14764                    if (report != null) {
14765                        if (errList == null) {
14766                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14767                        }
14768                        errList.add(report);
14769                    } else {
14770                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14771                                " crashing = " + app.crashing +
14772                                " notResponding = " + app.notResponding);
14773                    }
14774                }
14775            }
14776        }
14777
14778        return errList;
14779    }
14780
14781    static int procStateToImportance(int procState, int memAdj,
14782            ActivityManager.RunningAppProcessInfo currApp,
14783            int clientTargetSdk) {
14784        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14785                procState, clientTargetSdk);
14786        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14787            currApp.lru = memAdj;
14788        } else {
14789            currApp.lru = 0;
14790        }
14791        return imp;
14792    }
14793
14794    private void fillInProcMemInfo(ProcessRecord app,
14795            ActivityManager.RunningAppProcessInfo outInfo,
14796            int clientTargetSdk) {
14797        outInfo.pid = app.pid;
14798        outInfo.uid = app.info.uid;
14799        if (mHeavyWeightProcess == app) {
14800            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14801        }
14802        if (app.persistent) {
14803            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14804        }
14805        if (app.activities.size() > 0) {
14806            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14807        }
14808        outInfo.lastTrimLevel = app.trimMemoryLevel;
14809        int adj = app.curAdj;
14810        int procState = app.curProcState;
14811        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14812        outInfo.importanceReasonCode = app.adjTypeCode;
14813        outInfo.processState = app.curProcState;
14814    }
14815
14816    @Override
14817    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14818        enforceNotIsolatedCaller("getRunningAppProcesses");
14819
14820        final int callingUid = Binder.getCallingUid();
14821        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14822
14823        // Lazy instantiation of list
14824        List<ActivityManager.RunningAppProcessInfo> runList = null;
14825        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14826                callingUid) == PackageManager.PERMISSION_GRANTED;
14827        final int userId = UserHandle.getUserId(callingUid);
14828        final boolean allUids = isGetTasksAllowed(
14829                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14830
14831        synchronized (this) {
14832            // Iterate across all processes
14833            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14834                ProcessRecord app = mLruProcesses.get(i);
14835                if ((!allUsers && app.userId != userId)
14836                        || (!allUids && app.uid != callingUid)) {
14837                    continue;
14838                }
14839                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14840                    // Generate process state info for running application
14841                    ActivityManager.RunningAppProcessInfo currApp =
14842                        new ActivityManager.RunningAppProcessInfo(app.processName,
14843                                app.pid, app.getPackageList());
14844                    fillInProcMemInfo(app, currApp, clientTargetSdk);
14845                    if (app.adjSource instanceof ProcessRecord) {
14846                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14847                        currApp.importanceReasonImportance =
14848                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14849                                        app.adjSourceProcState);
14850                    } else if (app.adjSource instanceof ActivityRecord) {
14851                        ActivityRecord r = (ActivityRecord)app.adjSource;
14852                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14853                    }
14854                    if (app.adjTarget instanceof ComponentName) {
14855                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14856                    }
14857                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14858                    //        + " lru=" + currApp.lru);
14859                    if (runList == null) {
14860                        runList = new ArrayList<>();
14861                    }
14862                    runList.add(currApp);
14863                }
14864            }
14865        }
14866        return runList;
14867    }
14868
14869    @Override
14870    public List<ApplicationInfo> getRunningExternalApplications() {
14871        enforceNotIsolatedCaller("getRunningExternalApplications");
14872        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14873        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14874        if (runningApps != null && runningApps.size() > 0) {
14875            Set<String> extList = new HashSet<String>();
14876            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14877                if (app.pkgList != null) {
14878                    for (String pkg : app.pkgList) {
14879                        extList.add(pkg);
14880                    }
14881                }
14882            }
14883            IPackageManager pm = AppGlobals.getPackageManager();
14884            for (String pkg : extList) {
14885                try {
14886                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14887                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14888                        retList.add(info);
14889                    }
14890                } catch (RemoteException e) {
14891                }
14892            }
14893        }
14894        return retList;
14895    }
14896
14897    @Override
14898    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14899        enforceNotIsolatedCaller("getMyMemoryState");
14900
14901        final int callingUid = Binder.getCallingUid();
14902        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14903
14904        synchronized (this) {
14905            ProcessRecord proc;
14906            synchronized (mPidsSelfLocked) {
14907                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14908            }
14909            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14910        }
14911    }
14912
14913    @Override
14914    public int getMemoryTrimLevel() {
14915        enforceNotIsolatedCaller("getMyMemoryState");
14916        synchronized (this) {
14917            return mLastMemoryLevel;
14918        }
14919    }
14920
14921    @Override
14922    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14923            FileDescriptor err, String[] args, ShellCallback callback,
14924            ResultReceiver resultReceiver) {
14925        (new ActivityManagerShellCommand(this, false)).exec(
14926                this, in, out, err, args, callback, resultReceiver);
14927    }
14928
14929    SleepToken acquireSleepToken(String tag, int displayId) {
14930        synchronized (this) {
14931            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
14932            updateSleepIfNeededLocked();
14933            return token;
14934        }
14935    }
14936
14937    @Override
14938    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14939        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14940
14941        boolean dumpAll = false;
14942        boolean dumpClient = false;
14943        boolean dumpCheckin = false;
14944        boolean dumpCheckinFormat = false;
14945        boolean dumpVisibleStacksOnly = false;
14946        boolean dumpFocusedStackOnly = false;
14947        String dumpPackage = null;
14948
14949        int opti = 0;
14950        while (opti < args.length) {
14951            String opt = args[opti];
14952            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14953                break;
14954            }
14955            opti++;
14956            if ("-a".equals(opt)) {
14957                dumpAll = true;
14958            } else if ("-c".equals(opt)) {
14959                dumpClient = true;
14960            } else if ("-v".equals(opt)) {
14961                dumpVisibleStacksOnly = true;
14962            } else if ("-f".equals(opt)) {
14963                dumpFocusedStackOnly = true;
14964            } else if ("-p".equals(opt)) {
14965                if (opti < args.length) {
14966                    dumpPackage = args[opti];
14967                    opti++;
14968                } else {
14969                    pw.println("Error: -p option requires package argument");
14970                    return;
14971                }
14972                dumpClient = true;
14973            } else if ("--checkin".equals(opt)) {
14974                dumpCheckin = dumpCheckinFormat = true;
14975            } else if ("-C".equals(opt)) {
14976                dumpCheckinFormat = true;
14977            } else if ("-h".equals(opt)) {
14978                ActivityManagerShellCommand.dumpHelp(pw, true);
14979                return;
14980            } else {
14981                pw.println("Unknown argument: " + opt + "; use -h for help");
14982            }
14983        }
14984
14985        long origId = Binder.clearCallingIdentity();
14986        boolean more = false;
14987        // Is the caller requesting to dump a particular piece of data?
14988        if (opti < args.length) {
14989            String cmd = args[opti];
14990            opti++;
14991            if ("activities".equals(cmd) || "a".equals(cmd)) {
14992                synchronized (this) {
14993                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14994                }
14995            } else if ("lastanr".equals(cmd)) {
14996                synchronized (this) {
14997                    dumpLastANRLocked(pw);
14998                }
14999            } else if ("starter".equals(cmd)) {
15000                synchronized (this) {
15001                    dumpActivityStarterLocked(pw, dumpPackage);
15002                }
15003            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15004                synchronized (this) {
15005                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15006                }
15007            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15008                String[] newArgs;
15009                String name;
15010                if (opti >= args.length) {
15011                    name = null;
15012                    newArgs = EMPTY_STRING_ARRAY;
15013                } else {
15014                    dumpPackage = args[opti];
15015                    opti++;
15016                    newArgs = new String[args.length - opti];
15017                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15018                            args.length - opti);
15019                }
15020                synchronized (this) {
15021                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15022                }
15023            } else if ("broadcast-stats".equals(cmd)) {
15024                String[] newArgs;
15025                String name;
15026                if (opti >= args.length) {
15027                    name = null;
15028                    newArgs = EMPTY_STRING_ARRAY;
15029                } else {
15030                    dumpPackage = args[opti];
15031                    opti++;
15032                    newArgs = new String[args.length - opti];
15033                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15034                            args.length - opti);
15035                }
15036                synchronized (this) {
15037                    if (dumpCheckinFormat) {
15038                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15039                                dumpPackage);
15040                    } else {
15041                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15042                    }
15043                }
15044            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15045                String[] newArgs;
15046                String name;
15047                if (opti >= args.length) {
15048                    name = null;
15049                    newArgs = EMPTY_STRING_ARRAY;
15050                } else {
15051                    dumpPackage = args[opti];
15052                    opti++;
15053                    newArgs = new String[args.length - opti];
15054                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15055                            args.length - opti);
15056                }
15057                synchronized (this) {
15058                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15059                }
15060            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15061                String[] newArgs;
15062                String name;
15063                if (opti >= args.length) {
15064                    name = null;
15065                    newArgs = EMPTY_STRING_ARRAY;
15066                } else {
15067                    dumpPackage = args[opti];
15068                    opti++;
15069                    newArgs = new String[args.length - opti];
15070                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15071                            args.length - opti);
15072                }
15073                synchronized (this) {
15074                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15075                }
15076            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15077                synchronized (this) {
15078                    dumpOomLocked(fd, pw, args, opti, true);
15079                }
15080            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15081                synchronized (this) {
15082                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15083                }
15084            } else if ("provider".equals(cmd)) {
15085                String[] newArgs;
15086                String name;
15087                if (opti >= args.length) {
15088                    name = null;
15089                    newArgs = EMPTY_STRING_ARRAY;
15090                } else {
15091                    name = args[opti];
15092                    opti++;
15093                    newArgs = new String[args.length - opti];
15094                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15095                }
15096                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15097                    pw.println("No providers match: " + name);
15098                    pw.println("Use -h for help.");
15099                }
15100            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15101                synchronized (this) {
15102                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15103                }
15104            } else if ("service".equals(cmd)) {
15105                String[] newArgs;
15106                String name;
15107                if (opti >= args.length) {
15108                    name = null;
15109                    newArgs = EMPTY_STRING_ARRAY;
15110                } else {
15111                    name = args[opti];
15112                    opti++;
15113                    newArgs = new String[args.length - opti];
15114                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15115                            args.length - opti);
15116                }
15117                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15118                    pw.println("No services match: " + name);
15119                    pw.println("Use -h for help.");
15120                }
15121            } else if ("package".equals(cmd)) {
15122                String[] newArgs;
15123                if (opti >= args.length) {
15124                    pw.println("package: no package name specified");
15125                    pw.println("Use -h for help.");
15126                } else {
15127                    dumpPackage = args[opti];
15128                    opti++;
15129                    newArgs = new String[args.length - opti];
15130                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15131                            args.length - opti);
15132                    args = newArgs;
15133                    opti = 0;
15134                    more = true;
15135                }
15136            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15137                synchronized (this) {
15138                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15139                }
15140            } else if ("settings".equals(cmd)) {
15141                synchronized (this) {
15142                    mConstants.dump(pw);
15143                }
15144            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15145                if (dumpClient) {
15146                    ActiveServices.ServiceDumper dumper;
15147                    synchronized (this) {
15148                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15149                                dumpPackage);
15150                    }
15151                    dumper.dumpWithClient();
15152                } else {
15153                    synchronized (this) {
15154                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15155                                dumpPackage).dumpLocked();
15156                    }
15157                }
15158            } else if ("locks".equals(cmd)) {
15159                LockGuard.dump(fd, pw, args);
15160            } else {
15161                // Dumping a single activity?
15162                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15163                        dumpFocusedStackOnly)) {
15164                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15165                    int res = shell.exec(this, null, fd, null, args, null,
15166                            new ResultReceiver(null));
15167                    if (res < 0) {
15168                        pw.println("Bad activity command, or no activities match: " + cmd);
15169                        pw.println("Use -h for help.");
15170                    }
15171                }
15172            }
15173            if (!more) {
15174                Binder.restoreCallingIdentity(origId);
15175                return;
15176            }
15177        }
15178
15179        // No piece of data specified, dump everything.
15180        if (dumpCheckinFormat) {
15181            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15182        } else if (dumpClient) {
15183            ActiveServices.ServiceDumper sdumper;
15184            synchronized (this) {
15185                mConstants.dump(pw);
15186                pw.println();
15187                if (dumpAll) {
15188                    pw.println("-------------------------------------------------------------------------------");
15189                }
15190                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15191                pw.println();
15192                if (dumpAll) {
15193                    pw.println("-------------------------------------------------------------------------------");
15194                }
15195                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15196                pw.println();
15197                if (dumpAll) {
15198                    pw.println("-------------------------------------------------------------------------------");
15199                }
15200                if (dumpAll || dumpPackage != null) {
15201                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15202                    pw.println();
15203                    if (dumpAll) {
15204                        pw.println("-------------------------------------------------------------------------------");
15205                    }
15206                }
15207                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15208                pw.println();
15209                if (dumpAll) {
15210                    pw.println("-------------------------------------------------------------------------------");
15211                }
15212                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15213                pw.println();
15214                if (dumpAll) {
15215                    pw.println("-------------------------------------------------------------------------------");
15216                }
15217                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15218                        dumpPackage);
15219            }
15220            sdumper.dumpWithClient();
15221            pw.println();
15222            synchronized (this) {
15223                if (dumpAll) {
15224                    pw.println("-------------------------------------------------------------------------------");
15225                }
15226                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15227                pw.println();
15228                if (dumpAll) {
15229                    pw.println("-------------------------------------------------------------------------------");
15230                }
15231                dumpLastANRLocked(pw);
15232                pw.println();
15233                if (dumpAll) {
15234                    pw.println("-------------------------------------------------------------------------------");
15235                }
15236                dumpActivityStarterLocked(pw, dumpPackage);
15237                pw.println();
15238                if (dumpAll) {
15239                    pw.println("-------------------------------------------------------------------------------");
15240                }
15241                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15242                if (mAssociations.size() > 0) {
15243                    pw.println();
15244                    if (dumpAll) {
15245                        pw.println("-------------------------------------------------------------------------------");
15246                    }
15247                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15248                }
15249                pw.println();
15250                if (dumpAll) {
15251                    pw.println("-------------------------------------------------------------------------------");
15252                }
15253                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15254            }
15255
15256        } else {
15257            synchronized (this) {
15258                mConstants.dump(pw);
15259                pw.println();
15260                if (dumpAll) {
15261                    pw.println("-------------------------------------------------------------------------------");
15262                }
15263                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15264                pw.println();
15265                if (dumpAll) {
15266                    pw.println("-------------------------------------------------------------------------------");
15267                }
15268                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15269                pw.println();
15270                if (dumpAll) {
15271                    pw.println("-------------------------------------------------------------------------------");
15272                }
15273                if (dumpAll || dumpPackage != null) {
15274                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15275                    pw.println();
15276                    if (dumpAll) {
15277                        pw.println("-------------------------------------------------------------------------------");
15278                    }
15279                }
15280                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15281                pw.println();
15282                if (dumpAll) {
15283                    pw.println("-------------------------------------------------------------------------------");
15284                }
15285                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15286                pw.println();
15287                if (dumpAll) {
15288                    pw.println("-------------------------------------------------------------------------------");
15289                }
15290                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15291                        .dumpLocked();
15292                pw.println();
15293                if (dumpAll) {
15294                    pw.println("-------------------------------------------------------------------------------");
15295                }
15296                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15297                pw.println();
15298                if (dumpAll) {
15299                    pw.println("-------------------------------------------------------------------------------");
15300                }
15301                dumpLastANRLocked(pw);
15302                pw.println();
15303                if (dumpAll) {
15304                    pw.println("-------------------------------------------------------------------------------");
15305                }
15306                dumpActivityStarterLocked(pw, dumpPackage);
15307                pw.println();
15308                if (dumpAll) {
15309                    pw.println("-------------------------------------------------------------------------------");
15310                }
15311                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15312                if (mAssociations.size() > 0) {
15313                    pw.println();
15314                    if (dumpAll) {
15315                        pw.println("-------------------------------------------------------------------------------");
15316                    }
15317                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15318                }
15319                pw.println();
15320                if (dumpAll) {
15321                    pw.println("-------------------------------------------------------------------------------");
15322                }
15323                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15324            }
15325        }
15326        Binder.restoreCallingIdentity(origId);
15327    }
15328
15329    private void dumpLastANRLocked(PrintWriter pw) {
15330        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15331        if (mLastANRState == null) {
15332            pw.println("  <no ANR has occurred since boot>");
15333        } else {
15334            pw.println(mLastANRState);
15335        }
15336    }
15337
15338    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15339        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15340        mActivityStarter.dump(pw, "", dumpPackage);
15341    }
15342
15343    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15344            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15345        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15346                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15347    }
15348
15349    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15350            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15351        pw.println(header);
15352
15353        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15354                dumpPackage);
15355        boolean needSep = printedAnything;
15356
15357        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15358                mStackSupervisor.getResumedActivityLocked(),
15359                dumpPackage, needSep, "  ResumedActivity: ");
15360        if (printed) {
15361            printedAnything = true;
15362            needSep = false;
15363        }
15364
15365        if (dumpPackage == null) {
15366            if (needSep) {
15367                pw.println();
15368            }
15369            printedAnything = true;
15370            mStackSupervisor.dump(pw, "  ");
15371        }
15372
15373        if (!printedAnything) {
15374            pw.println("  (nothing)");
15375        }
15376    }
15377
15378    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15379            int opti, boolean dumpAll, String dumpPackage) {
15380        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15381
15382        boolean printedAnything = false;
15383
15384        if (mRecentTasks != null && mRecentTasks.size() > 0) {
15385            boolean printedHeader = false;
15386
15387            final int N = mRecentTasks.size();
15388            for (int i=0; i<N; i++) {
15389                TaskRecord tr = mRecentTasks.get(i);
15390                if (dumpPackage != null) {
15391                    if (tr.realActivity == null ||
15392                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
15393                        continue;
15394                    }
15395                }
15396                if (!printedHeader) {
15397                    pw.println("  Recent tasks:");
15398                    printedHeader = true;
15399                    printedAnything = true;
15400                }
15401                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15402                        pw.println(tr);
15403                if (dumpAll) {
15404                    mRecentTasks.get(i).dump(pw, "    ");
15405                }
15406            }
15407        }
15408
15409        if (!printedAnything) {
15410            pw.println("  (nothing)");
15411        }
15412    }
15413
15414    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15415            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15416        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15417
15418        int dumpUid = 0;
15419        if (dumpPackage != null) {
15420            IPackageManager pm = AppGlobals.getPackageManager();
15421            try {
15422                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15423            } catch (RemoteException e) {
15424            }
15425        }
15426
15427        boolean printedAnything = false;
15428
15429        final long now = SystemClock.uptimeMillis();
15430
15431        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15432            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15433                    = mAssociations.valueAt(i1);
15434            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15435                SparseArray<ArrayMap<String, Association>> sourceUids
15436                        = targetComponents.valueAt(i2);
15437                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15438                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15439                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15440                        Association ass = sourceProcesses.valueAt(i4);
15441                        if (dumpPackage != null) {
15442                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15443                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15444                                continue;
15445                            }
15446                        }
15447                        printedAnything = true;
15448                        pw.print("  ");
15449                        pw.print(ass.mTargetProcess);
15450                        pw.print("/");
15451                        UserHandle.formatUid(pw, ass.mTargetUid);
15452                        pw.print(" <- ");
15453                        pw.print(ass.mSourceProcess);
15454                        pw.print("/");
15455                        UserHandle.formatUid(pw, ass.mSourceUid);
15456                        pw.println();
15457                        pw.print("    via ");
15458                        pw.print(ass.mTargetComponent.flattenToShortString());
15459                        pw.println();
15460                        pw.print("    ");
15461                        long dur = ass.mTime;
15462                        if (ass.mNesting > 0) {
15463                            dur += now - ass.mStartTime;
15464                        }
15465                        TimeUtils.formatDuration(dur, pw);
15466                        pw.print(" (");
15467                        pw.print(ass.mCount);
15468                        pw.print(" times)");
15469                        pw.print("  ");
15470                        for (int i=0; i<ass.mStateTimes.length; i++) {
15471                            long amt = ass.mStateTimes[i];
15472                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15473                                amt += now - ass.mLastStateUptime;
15474                            }
15475                            if (amt != 0) {
15476                                pw.print(" ");
15477                                pw.print(ProcessList.makeProcStateString(
15478                                            i + ActivityManager.MIN_PROCESS_STATE));
15479                                pw.print("=");
15480                                TimeUtils.formatDuration(amt, pw);
15481                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15482                                    pw.print("*");
15483                                }
15484                            }
15485                        }
15486                        pw.println();
15487                        if (ass.mNesting > 0) {
15488                            pw.print("    Currently active: ");
15489                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15490                            pw.println();
15491                        }
15492                    }
15493                }
15494            }
15495
15496        }
15497
15498        if (!printedAnything) {
15499            pw.println("  (nothing)");
15500        }
15501    }
15502
15503    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15504            String header, boolean needSep) {
15505        boolean printed = false;
15506        int whichAppId = -1;
15507        if (dumpPackage != null) {
15508            try {
15509                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15510                        dumpPackage, 0);
15511                whichAppId = UserHandle.getAppId(info.uid);
15512            } catch (NameNotFoundException e) {
15513                e.printStackTrace();
15514            }
15515        }
15516        for (int i=0; i<uids.size(); i++) {
15517            UidRecord uidRec = uids.valueAt(i);
15518            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15519                continue;
15520            }
15521            if (!printed) {
15522                printed = true;
15523                if (needSep) {
15524                    pw.println();
15525                }
15526                pw.print("  ");
15527                pw.println(header);
15528                needSep = true;
15529            }
15530            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15531            pw.print(": "); pw.println(uidRec);
15532        }
15533        return printed;
15534    }
15535
15536    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15537            int opti, boolean dumpAll, String dumpPackage) {
15538        boolean needSep = false;
15539        boolean printedAnything = false;
15540        int numPers = 0;
15541
15542        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15543
15544        if (dumpAll) {
15545            final int NP = mProcessNames.getMap().size();
15546            for (int ip=0; ip<NP; ip++) {
15547                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15548                final int NA = procs.size();
15549                for (int ia=0; ia<NA; ia++) {
15550                    ProcessRecord r = procs.valueAt(ia);
15551                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15552                        continue;
15553                    }
15554                    if (!needSep) {
15555                        pw.println("  All known processes:");
15556                        needSep = true;
15557                        printedAnything = true;
15558                    }
15559                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15560                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15561                        pw.print(" "); pw.println(r);
15562                    r.dump(pw, "    ");
15563                    if (r.persistent) {
15564                        numPers++;
15565                    }
15566                }
15567            }
15568        }
15569
15570        if (mIsolatedProcesses.size() > 0) {
15571            boolean printed = false;
15572            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15573                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15574                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15575                    continue;
15576                }
15577                if (!printed) {
15578                    if (needSep) {
15579                        pw.println();
15580                    }
15581                    pw.println("  Isolated process list (sorted by uid):");
15582                    printedAnything = true;
15583                    printed = true;
15584                    needSep = true;
15585                }
15586                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15587                pw.println(r);
15588            }
15589        }
15590
15591        if (mActiveInstrumentation.size() > 0) {
15592            boolean printed = false;
15593            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15594                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15595                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15596                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15597                    continue;
15598                }
15599                if (!printed) {
15600                    if (needSep) {
15601                        pw.println();
15602                    }
15603                    pw.println("  Active instrumentation:");
15604                    printedAnything = true;
15605                    printed = true;
15606                    needSep = true;
15607                }
15608                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15609                pw.println(ai);
15610                ai.dump(pw, "      ");
15611            }
15612        }
15613
15614        if (mActiveUids.size() > 0) {
15615            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15616                printedAnything = needSep = true;
15617            }
15618        }
15619        if (dumpAll) {
15620            if (mValidateUids.size() > 0) {
15621                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15622                    printedAnything = needSep = true;
15623                }
15624            }
15625        }
15626
15627        if (mLruProcesses.size() > 0) {
15628            if (needSep) {
15629                pw.println();
15630            }
15631            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15632                    pw.print(" total, non-act at ");
15633                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15634                    pw.print(", non-svc at ");
15635                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15636                    pw.println("):");
15637            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15638            needSep = true;
15639            printedAnything = true;
15640        }
15641
15642        if (dumpAll || dumpPackage != null) {
15643            synchronized (mPidsSelfLocked) {
15644                boolean printed = false;
15645                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15646                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15647                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15648                        continue;
15649                    }
15650                    if (!printed) {
15651                        if (needSep) pw.println();
15652                        needSep = true;
15653                        pw.println("  PID mappings:");
15654                        printed = true;
15655                        printedAnything = true;
15656                    }
15657                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15658                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15659                }
15660            }
15661        }
15662
15663        if (mImportantProcesses.size() > 0) {
15664            synchronized (mPidsSelfLocked) {
15665                boolean printed = false;
15666                for (int i = 0; i< mImportantProcesses.size(); i++) {
15667                    ProcessRecord r = mPidsSelfLocked.get(
15668                            mImportantProcesses.valueAt(i).pid);
15669                    if (dumpPackage != null && (r == null
15670                            || !r.pkgList.containsKey(dumpPackage))) {
15671                        continue;
15672                    }
15673                    if (!printed) {
15674                        if (needSep) pw.println();
15675                        needSep = true;
15676                        pw.println("  Foreground Processes:");
15677                        printed = true;
15678                        printedAnything = true;
15679                    }
15680                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15681                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15682                }
15683            }
15684        }
15685
15686        if (mPersistentStartingProcesses.size() > 0) {
15687            if (needSep) pw.println();
15688            needSep = true;
15689            printedAnything = true;
15690            pw.println("  Persisent processes that are starting:");
15691            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15692                    "Starting Norm", "Restarting PERS", dumpPackage);
15693        }
15694
15695        if (mRemovedProcesses.size() > 0) {
15696            if (needSep) pw.println();
15697            needSep = true;
15698            printedAnything = true;
15699            pw.println("  Processes that are being removed:");
15700            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15701                    "Removed Norm", "Removed PERS", dumpPackage);
15702        }
15703
15704        if (mProcessesOnHold.size() > 0) {
15705            if (needSep) pw.println();
15706            needSep = true;
15707            printedAnything = true;
15708            pw.println("  Processes that are on old until the system is ready:");
15709            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15710                    "OnHold Norm", "OnHold PERS", dumpPackage);
15711        }
15712
15713        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15714
15715        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15716        if (needSep) {
15717            printedAnything = true;
15718        }
15719
15720        if (dumpPackage == null) {
15721            pw.println();
15722            needSep = false;
15723            mUserController.dump(pw, dumpAll);
15724        }
15725        if (mHomeProcess != null && (dumpPackage == null
15726                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15727            if (needSep) {
15728                pw.println();
15729                needSep = false;
15730            }
15731            pw.println("  mHomeProcess: " + mHomeProcess);
15732        }
15733        if (mPreviousProcess != null && (dumpPackage == null
15734                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15735            if (needSep) {
15736                pw.println();
15737                needSep = false;
15738            }
15739            pw.println("  mPreviousProcess: " + mPreviousProcess);
15740        }
15741        if (dumpAll) {
15742            StringBuilder sb = new StringBuilder(128);
15743            sb.append("  mPreviousProcessVisibleTime: ");
15744            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15745            pw.println(sb);
15746        }
15747        if (mHeavyWeightProcess != null && (dumpPackage == null
15748                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15749            if (needSep) {
15750                pw.println();
15751                needSep = false;
15752            }
15753            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15754        }
15755        if (dumpPackage == null) {
15756            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15757            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15758        }
15759        if (dumpAll) {
15760            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15761            if (mCompatModePackages.getPackages().size() > 0) {
15762                boolean printed = false;
15763                for (Map.Entry<String, Integer> entry
15764                        : mCompatModePackages.getPackages().entrySet()) {
15765                    String pkg = entry.getKey();
15766                    int mode = entry.getValue();
15767                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15768                        continue;
15769                    }
15770                    if (!printed) {
15771                        pw.println("  mScreenCompatPackages:");
15772                        printed = true;
15773                    }
15774                    pw.print("    "); pw.print(pkg); pw.print(": ");
15775                            pw.print(mode); pw.println();
15776                }
15777            }
15778            final int NI = mUidObservers.getRegisteredCallbackCount();
15779            boolean printed = false;
15780            for (int i=0; i<NI; i++) {
15781                final UidObserverRegistration reg = (UidObserverRegistration)
15782                        mUidObservers.getRegisteredCallbackCookie(i);
15783                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15784                    if (!printed) {
15785                        pw.println("  mUidObservers:");
15786                        printed = true;
15787                    }
15788                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15789                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15790                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15791                        pw.print(" IDLE");
15792                    }
15793                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15794                        pw.print(" ACT" );
15795                    }
15796                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15797                        pw.print(" GONE");
15798                    }
15799                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15800                        pw.print(" STATE");
15801                        pw.print(" (cut="); pw.print(reg.cutpoint);
15802                        pw.print(")");
15803                    }
15804                    pw.println();
15805                    if (reg.lastProcStates != null) {
15806                        final int NJ = reg.lastProcStates.size();
15807                        for (int j=0; j<NJ; j++) {
15808                            pw.print("      Last ");
15809                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15810                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15811                        }
15812                    }
15813                }
15814            }
15815            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15816            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15817            if (mPendingTempWhitelist.size() > 0) {
15818                pw.println("  mPendingTempWhitelist:");
15819                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15820                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15821                    pw.print("    ");
15822                    UserHandle.formatUid(pw, ptw.targetUid);
15823                    pw.print(": ");
15824                    TimeUtils.formatDuration(ptw.duration, pw);
15825                    pw.print(" ");
15826                    pw.println(ptw.tag);
15827                }
15828            }
15829        }
15830        if (dumpPackage == null) {
15831            pw.println("  mWakefulness="
15832                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15833            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
15834            pw.println("  mSleeping=" + mSleeping);
15835            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15836            if (mRunningVoice != null) {
15837                pw.println("  mRunningVoice=" + mRunningVoice);
15838                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15839            }
15840        }
15841        pw.println("  mVrController=" + mVrController);
15842        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15843                || mOrigWaitForDebugger) {
15844            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15845                    || dumpPackage.equals(mOrigDebugApp)) {
15846                if (needSep) {
15847                    pw.println();
15848                    needSep = false;
15849                }
15850                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15851                        + " mDebugTransient=" + mDebugTransient
15852                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15853            }
15854        }
15855        if (mCurAppTimeTracker != null) {
15856            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15857        }
15858        if (mMemWatchProcesses.getMap().size() > 0) {
15859            pw.println("  Mem watch processes:");
15860            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15861                    = mMemWatchProcesses.getMap();
15862            for (int i=0; i<procs.size(); i++) {
15863                final String proc = procs.keyAt(i);
15864                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15865                for (int j=0; j<uids.size(); j++) {
15866                    if (needSep) {
15867                        pw.println();
15868                        needSep = false;
15869                    }
15870                    StringBuilder sb = new StringBuilder();
15871                    sb.append("    ").append(proc).append('/');
15872                    UserHandle.formatUid(sb, uids.keyAt(j));
15873                    Pair<Long, String> val = uids.valueAt(j);
15874                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15875                    if (val.second != null) {
15876                        sb.append(", report to ").append(val.second);
15877                    }
15878                    pw.println(sb.toString());
15879                }
15880            }
15881            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15882            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15883            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15884                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15885        }
15886        if (mTrackAllocationApp != null) {
15887            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15888                if (needSep) {
15889                    pw.println();
15890                    needSep = false;
15891                }
15892                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15893            }
15894        }
15895        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15896                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15897            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15898                if (needSep) {
15899                    pw.println();
15900                    needSep = false;
15901                }
15902                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15903                if (mProfilerInfo != null) {
15904                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
15905                            mProfilerInfo.profileFd);
15906                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
15907                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
15908                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
15909                    pw.println("  mProfileType=" + mProfileType);
15910                }
15911            }
15912        }
15913        if (mNativeDebuggingApp != null) {
15914            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15915                if (needSep) {
15916                    pw.println();
15917                    needSep = false;
15918                }
15919                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15920            }
15921        }
15922        if (dumpPackage == null) {
15923            if (mAlwaysFinishActivities) {
15924                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15925            }
15926            if (mController != null) {
15927                pw.println("  mController=" + mController
15928                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15929            }
15930            if (dumpAll) {
15931                pw.println("  Total persistent processes: " + numPers);
15932                pw.println("  mProcessesReady=" + mProcessesReady
15933                        + " mSystemReady=" + mSystemReady
15934                        + " mBooted=" + mBooted
15935                        + " mFactoryTest=" + mFactoryTest);
15936                pw.println("  mBooting=" + mBooting
15937                        + " mCallFinishBooting=" + mCallFinishBooting
15938                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15939                pw.print("  mLastPowerCheckUptime=");
15940                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15941                        pw.println("");
15942                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15943                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15944                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15945                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15946                        + " (" + mLruProcesses.size() + " total)"
15947                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15948                        + " mNumServiceProcs=" + mNumServiceProcs
15949                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15950                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15951                        + " mLastMemoryLevel=" + mLastMemoryLevel
15952                        + " mLastNumProcesses=" + mLastNumProcesses);
15953                long now = SystemClock.uptimeMillis();
15954                pw.print("  mLastIdleTime=");
15955                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15956                        pw.print(" mLowRamSinceLastIdle=");
15957                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15958                        pw.println();
15959            }
15960        }
15961
15962        if (!printedAnything) {
15963            pw.println("  (nothing)");
15964        }
15965    }
15966
15967    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15968            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15969        if (mProcessesToGc.size() > 0) {
15970            boolean printed = false;
15971            long now = SystemClock.uptimeMillis();
15972            for (int i=0; i<mProcessesToGc.size(); i++) {
15973                ProcessRecord proc = mProcessesToGc.get(i);
15974                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15975                    continue;
15976                }
15977                if (!printed) {
15978                    if (needSep) pw.println();
15979                    needSep = true;
15980                    pw.println("  Processes that are waiting to GC:");
15981                    printed = true;
15982                }
15983                pw.print("    Process "); pw.println(proc);
15984                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15985                        pw.print(", last gced=");
15986                        pw.print(now-proc.lastRequestedGc);
15987                        pw.print(" ms ago, last lowMem=");
15988                        pw.print(now-proc.lastLowMemory);
15989                        pw.println(" ms ago");
15990
15991            }
15992        }
15993        return needSep;
15994    }
15995
15996    void printOomLevel(PrintWriter pw, String name, int adj) {
15997        pw.print("    ");
15998        if (adj >= 0) {
15999            pw.print(' ');
16000            if (adj < 10) pw.print(' ');
16001        } else {
16002            if (adj > -10) pw.print(' ');
16003        }
16004        pw.print(adj);
16005        pw.print(": ");
16006        pw.print(name);
16007        pw.print(" (");
16008        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16009        pw.println(")");
16010    }
16011
16012    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16013            int opti, boolean dumpAll) {
16014        boolean needSep = false;
16015
16016        if (mLruProcesses.size() > 0) {
16017            if (needSep) pw.println();
16018            needSep = true;
16019            pw.println("  OOM levels:");
16020            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16021            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16022            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16023            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16024            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16025            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16026            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16027            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16028            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16029            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16030            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16031            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16032            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16033            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16034
16035            if (needSep) pw.println();
16036            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16037                    pw.print(" total, non-act at ");
16038                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16039                    pw.print(", non-svc at ");
16040                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16041                    pw.println("):");
16042            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16043            needSep = true;
16044        }
16045
16046        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16047
16048        pw.println();
16049        pw.println("  mHomeProcess: " + mHomeProcess);
16050        pw.println("  mPreviousProcess: " + mPreviousProcess);
16051        if (mHeavyWeightProcess != null) {
16052            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16053        }
16054
16055        return true;
16056    }
16057
16058    /**
16059     * There are three ways to call this:
16060     *  - no provider specified: dump all the providers
16061     *  - a flattened component name that matched an existing provider was specified as the
16062     *    first arg: dump that one provider
16063     *  - the first arg isn't the flattened component name of an existing provider:
16064     *    dump all providers whose component contains the first arg as a substring
16065     */
16066    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16067            int opti, boolean dumpAll) {
16068        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16069    }
16070
16071    static class ItemMatcher {
16072        ArrayList<ComponentName> components;
16073        ArrayList<String> strings;
16074        ArrayList<Integer> objects;
16075        boolean all;
16076
16077        ItemMatcher() {
16078            all = true;
16079        }
16080
16081        void build(String name) {
16082            ComponentName componentName = ComponentName.unflattenFromString(name);
16083            if (componentName != null) {
16084                if (components == null) {
16085                    components = new ArrayList<ComponentName>();
16086                }
16087                components.add(componentName);
16088                all = false;
16089            } else {
16090                int objectId = 0;
16091                // Not a '/' separated full component name; maybe an object ID?
16092                try {
16093                    objectId = Integer.parseInt(name, 16);
16094                    if (objects == null) {
16095                        objects = new ArrayList<Integer>();
16096                    }
16097                    objects.add(objectId);
16098                    all = false;
16099                } catch (RuntimeException e) {
16100                    // Not an integer; just do string match.
16101                    if (strings == null) {
16102                        strings = new ArrayList<String>();
16103                    }
16104                    strings.add(name);
16105                    all = false;
16106                }
16107            }
16108        }
16109
16110        int build(String[] args, int opti) {
16111            for (; opti<args.length; opti++) {
16112                String name = args[opti];
16113                if ("--".equals(name)) {
16114                    return opti+1;
16115                }
16116                build(name);
16117            }
16118            return opti;
16119        }
16120
16121        boolean match(Object object, ComponentName comp) {
16122            if (all) {
16123                return true;
16124            }
16125            if (components != null) {
16126                for (int i=0; i<components.size(); i++) {
16127                    if (components.get(i).equals(comp)) {
16128                        return true;
16129                    }
16130                }
16131            }
16132            if (objects != null) {
16133                for (int i=0; i<objects.size(); i++) {
16134                    if (System.identityHashCode(object) == objects.get(i)) {
16135                        return true;
16136                    }
16137                }
16138            }
16139            if (strings != null) {
16140                String flat = comp.flattenToString();
16141                for (int i=0; i<strings.size(); i++) {
16142                    if (flat.contains(strings.get(i))) {
16143                        return true;
16144                    }
16145                }
16146            }
16147            return false;
16148        }
16149    }
16150
16151    /**
16152     * There are three things that cmd can be:
16153     *  - a flattened component name that matches an existing activity
16154     *  - the cmd arg isn't the flattened component name of an existing activity:
16155     *    dump all activity whose component contains the cmd as a substring
16156     *  - A hex number of the ActivityRecord object instance.
16157     *
16158     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16159     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16160     */
16161    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16162            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16163        ArrayList<ActivityRecord> activities;
16164
16165        synchronized (this) {
16166            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16167                    dumpFocusedStackOnly);
16168        }
16169
16170        if (activities.size() <= 0) {
16171            return false;
16172        }
16173
16174        String[] newArgs = new String[args.length - opti];
16175        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16176
16177        TaskRecord lastTask = null;
16178        boolean needSep = false;
16179        for (int i=activities.size()-1; i>=0; i--) {
16180            ActivityRecord r = activities.get(i);
16181            if (needSep) {
16182                pw.println();
16183            }
16184            needSep = true;
16185            synchronized (this) {
16186                final TaskRecord task = r.getTask();
16187                if (lastTask != task) {
16188                    lastTask = task;
16189                    pw.print("TASK "); pw.print(lastTask.affinity);
16190                            pw.print(" id="); pw.print(lastTask.taskId);
16191                            pw.print(" userId="); pw.println(lastTask.userId);
16192                    if (dumpAll) {
16193                        lastTask.dump(pw, "  ");
16194                    }
16195                }
16196            }
16197            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16198        }
16199        return true;
16200    }
16201
16202    /**
16203     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16204     * there is a thread associated with the activity.
16205     */
16206    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16207            final ActivityRecord r, String[] args, boolean dumpAll) {
16208        String innerPrefix = prefix + "  ";
16209        synchronized (this) {
16210            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16211                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16212                    pw.print(" pid=");
16213                    if (r.app != null) pw.println(r.app.pid);
16214                    else pw.println("(not running)");
16215            if (dumpAll) {
16216                r.dump(pw, innerPrefix);
16217            }
16218        }
16219        if (r.app != null && r.app.thread != null) {
16220            // flush anything that is already in the PrintWriter since the thread is going
16221            // to write to the file descriptor directly
16222            pw.flush();
16223            try {
16224                TransferPipe tp = new TransferPipe();
16225                try {
16226                    r.app.thread.dumpActivity(tp.getWriteFd(),
16227                            r.appToken, innerPrefix, args);
16228                    tp.go(fd);
16229                } finally {
16230                    tp.kill();
16231                }
16232            } catch (IOException e) {
16233                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16234            } catch (RemoteException e) {
16235                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16236            }
16237        }
16238    }
16239
16240    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16241            int opti, boolean dumpAll, String dumpPackage) {
16242        boolean needSep = false;
16243        boolean onlyHistory = false;
16244        boolean printedAnything = false;
16245
16246        if ("history".equals(dumpPackage)) {
16247            if (opti < args.length && "-s".equals(args[opti])) {
16248                dumpAll = false;
16249            }
16250            onlyHistory = true;
16251            dumpPackage = null;
16252        }
16253
16254        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16255        if (!onlyHistory && dumpAll) {
16256            if (mRegisteredReceivers.size() > 0) {
16257                boolean printed = false;
16258                Iterator it = mRegisteredReceivers.values().iterator();
16259                while (it.hasNext()) {
16260                    ReceiverList r = (ReceiverList)it.next();
16261                    if (dumpPackage != null && (r.app == null ||
16262                            !dumpPackage.equals(r.app.info.packageName))) {
16263                        continue;
16264                    }
16265                    if (!printed) {
16266                        pw.println("  Registered Receivers:");
16267                        needSep = true;
16268                        printed = true;
16269                        printedAnything = true;
16270                    }
16271                    pw.print("  * "); pw.println(r);
16272                    r.dump(pw, "    ");
16273                }
16274            }
16275
16276            if (mReceiverResolver.dump(pw, needSep ?
16277                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16278                    "    ", dumpPackage, false, false)) {
16279                needSep = true;
16280                printedAnything = true;
16281            }
16282        }
16283
16284        for (BroadcastQueue q : mBroadcastQueues) {
16285            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16286            printedAnything |= needSep;
16287        }
16288
16289        needSep = true;
16290
16291        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16292            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16293                if (needSep) {
16294                    pw.println();
16295                }
16296                needSep = true;
16297                printedAnything = true;
16298                pw.print("  Sticky broadcasts for user ");
16299                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16300                StringBuilder sb = new StringBuilder(128);
16301                for (Map.Entry<String, ArrayList<Intent>> ent
16302                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16303                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16304                    if (dumpAll) {
16305                        pw.println(":");
16306                        ArrayList<Intent> intents = ent.getValue();
16307                        final int N = intents.size();
16308                        for (int i=0; i<N; i++) {
16309                            sb.setLength(0);
16310                            sb.append("    Intent: ");
16311                            intents.get(i).toShortString(sb, false, true, false, false);
16312                            pw.println(sb.toString());
16313                            Bundle bundle = intents.get(i).getExtras();
16314                            if (bundle != null) {
16315                                pw.print("      ");
16316                                pw.println(bundle.toString());
16317                            }
16318                        }
16319                    } else {
16320                        pw.println("");
16321                    }
16322                }
16323            }
16324        }
16325
16326        if (!onlyHistory && dumpAll) {
16327            pw.println();
16328            for (BroadcastQueue queue : mBroadcastQueues) {
16329                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16330                        + queue.mBroadcastsScheduled);
16331            }
16332            pw.println("  mHandler:");
16333            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16334            needSep = true;
16335            printedAnything = true;
16336        }
16337
16338        if (!printedAnything) {
16339            pw.println("  (nothing)");
16340        }
16341    }
16342
16343    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16344            int opti, boolean dumpAll, String dumpPackage) {
16345        if (mCurBroadcastStats == null) {
16346            return;
16347        }
16348
16349        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16350        final long now = SystemClock.elapsedRealtime();
16351        if (mLastBroadcastStats != null) {
16352            pw.print("  Last stats (from ");
16353            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16354            pw.print(" to ");
16355            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16356            pw.print(", ");
16357            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16358                    - mLastBroadcastStats.mStartUptime, pw);
16359            pw.println(" uptime):");
16360            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16361                pw.println("    (nothing)");
16362            }
16363            pw.println();
16364        }
16365        pw.print("  Current stats (from ");
16366        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16367        pw.print(" to now, ");
16368        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16369                - mCurBroadcastStats.mStartUptime, pw);
16370        pw.println(" uptime):");
16371        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16372            pw.println("    (nothing)");
16373        }
16374    }
16375
16376    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16377            int opti, boolean fullCheckin, String dumpPackage) {
16378        if (mCurBroadcastStats == null) {
16379            return;
16380        }
16381
16382        if (mLastBroadcastStats != null) {
16383            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16384            if (fullCheckin) {
16385                mLastBroadcastStats = null;
16386                return;
16387            }
16388        }
16389        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16390        if (fullCheckin) {
16391            mCurBroadcastStats = null;
16392        }
16393    }
16394
16395    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16396            int opti, boolean dumpAll, String dumpPackage) {
16397        boolean needSep;
16398        boolean printedAnything = false;
16399
16400        ItemMatcher matcher = new ItemMatcher();
16401        matcher.build(args, opti);
16402
16403        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16404
16405        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16406        printedAnything |= needSep;
16407
16408        if (mLaunchingProviders.size() > 0) {
16409            boolean printed = false;
16410            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16411                ContentProviderRecord r = mLaunchingProviders.get(i);
16412                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16413                    continue;
16414                }
16415                if (!printed) {
16416                    if (needSep) pw.println();
16417                    needSep = true;
16418                    pw.println("  Launching content providers:");
16419                    printed = true;
16420                    printedAnything = true;
16421                }
16422                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16423                        pw.println(r);
16424            }
16425        }
16426
16427        if (!printedAnything) {
16428            pw.println("  (nothing)");
16429        }
16430    }
16431
16432    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16433            int opti, boolean dumpAll, String dumpPackage) {
16434        boolean needSep = false;
16435        boolean printedAnything = false;
16436
16437        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16438
16439        if (mGrantedUriPermissions.size() > 0) {
16440            boolean printed = false;
16441            int dumpUid = -2;
16442            if (dumpPackage != null) {
16443                try {
16444                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16445                            MATCH_ANY_USER, 0);
16446                } catch (NameNotFoundException e) {
16447                    dumpUid = -1;
16448                }
16449            }
16450            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16451                int uid = mGrantedUriPermissions.keyAt(i);
16452                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16453                    continue;
16454                }
16455                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16456                if (!printed) {
16457                    if (needSep) pw.println();
16458                    needSep = true;
16459                    pw.println("  Granted Uri Permissions:");
16460                    printed = true;
16461                    printedAnything = true;
16462                }
16463                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16464                for (UriPermission perm : perms.values()) {
16465                    pw.print("    "); pw.println(perm);
16466                    if (dumpAll) {
16467                        perm.dump(pw, "      ");
16468                    }
16469                }
16470            }
16471        }
16472
16473        if (!printedAnything) {
16474            pw.println("  (nothing)");
16475        }
16476    }
16477
16478    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16479            int opti, boolean dumpAll, String dumpPackage) {
16480        boolean printed = false;
16481
16482        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16483
16484        if (mIntentSenderRecords.size() > 0) {
16485            // Organize these by package name, so they are easier to read.
16486            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16487            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16488            final Iterator<WeakReference<PendingIntentRecord>> it
16489                    = mIntentSenderRecords.values().iterator();
16490            while (it.hasNext()) {
16491                WeakReference<PendingIntentRecord> ref = it.next();
16492                PendingIntentRecord rec = ref != null ? ref.get() : null;
16493                if (rec == null) {
16494                    weakRefs.add(ref);
16495                    continue;
16496                }
16497                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16498                    continue;
16499                }
16500                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16501                if (list == null) {
16502                    list = new ArrayList<>();
16503                    byPackage.put(rec.key.packageName, list);
16504                }
16505                list.add(rec);
16506            }
16507            for (int i = 0; i < byPackage.size(); i++) {
16508                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16509                printed = true;
16510                pw.print("  * "); pw.print(byPackage.keyAt(i));
16511                pw.print(": "); pw.print(intents.size()); pw.println(" items");
16512                for (int j = 0; j < intents.size(); j++) {
16513                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16514                    if (dumpAll) {
16515                        intents.get(j).dump(pw, "      ");
16516                    }
16517                }
16518            }
16519            if (weakRefs.size() > 0) {
16520                printed = true;
16521                pw.println("  * WEAK REFS:");
16522                for (int i = 0; i < weakRefs.size(); i++) {
16523                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16524                }
16525            }
16526        }
16527
16528        if (!printed) {
16529            pw.println("  (nothing)");
16530        }
16531    }
16532
16533    private static final int dumpProcessList(PrintWriter pw,
16534            ActivityManagerService service, List list,
16535            String prefix, String normalLabel, String persistentLabel,
16536            String dumpPackage) {
16537        int numPers = 0;
16538        final int N = list.size()-1;
16539        for (int i=N; i>=0; i--) {
16540            ProcessRecord r = (ProcessRecord)list.get(i);
16541            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16542                continue;
16543            }
16544            pw.println(String.format("%s%s #%2d: %s",
16545                    prefix, (r.persistent ? persistentLabel : normalLabel),
16546                    i, r.toString()));
16547            if (r.persistent) {
16548                numPers++;
16549            }
16550        }
16551        return numPers;
16552    }
16553
16554    private static final boolean dumpProcessOomList(PrintWriter pw,
16555            ActivityManagerService service, List<ProcessRecord> origList,
16556            String prefix, String normalLabel, String persistentLabel,
16557            boolean inclDetails, String dumpPackage) {
16558
16559        ArrayList<Pair<ProcessRecord, Integer>> list
16560                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16561        for (int i=0; i<origList.size(); i++) {
16562            ProcessRecord r = origList.get(i);
16563            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16564                continue;
16565            }
16566            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16567        }
16568
16569        if (list.size() <= 0) {
16570            return false;
16571        }
16572
16573        Comparator<Pair<ProcessRecord, Integer>> comparator
16574                = new Comparator<Pair<ProcessRecord, Integer>>() {
16575            @Override
16576            public int compare(Pair<ProcessRecord, Integer> object1,
16577                    Pair<ProcessRecord, Integer> object2) {
16578                if (object1.first.setAdj != object2.first.setAdj) {
16579                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16580                }
16581                if (object1.first.setProcState != object2.first.setProcState) {
16582                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16583                }
16584                if (object1.second.intValue() != object2.second.intValue()) {
16585                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16586                }
16587                return 0;
16588            }
16589        };
16590
16591        Collections.sort(list, comparator);
16592
16593        final long curUptime = SystemClock.uptimeMillis();
16594        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16595
16596        for (int i=list.size()-1; i>=0; i--) {
16597            ProcessRecord r = list.get(i).first;
16598            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16599            char schedGroup;
16600            switch (r.setSchedGroup) {
16601                case ProcessList.SCHED_GROUP_BACKGROUND:
16602                    schedGroup = 'B';
16603                    break;
16604                case ProcessList.SCHED_GROUP_DEFAULT:
16605                    schedGroup = 'F';
16606                    break;
16607                case ProcessList.SCHED_GROUP_TOP_APP:
16608                    schedGroup = 'T';
16609                    break;
16610                default:
16611                    schedGroup = '?';
16612                    break;
16613            }
16614            char foreground;
16615            if (r.foregroundActivities) {
16616                foreground = 'A';
16617            } else if (r.foregroundServices) {
16618                foreground = 'S';
16619            } else {
16620                foreground = ' ';
16621            }
16622            String procState = ProcessList.makeProcStateString(r.curProcState);
16623            pw.print(prefix);
16624            pw.print(r.persistent ? persistentLabel : normalLabel);
16625            pw.print(" #");
16626            int num = (origList.size()-1)-list.get(i).second;
16627            if (num < 10) pw.print(' ');
16628            pw.print(num);
16629            pw.print(": ");
16630            pw.print(oomAdj);
16631            pw.print(' ');
16632            pw.print(schedGroup);
16633            pw.print('/');
16634            pw.print(foreground);
16635            pw.print('/');
16636            pw.print(procState);
16637            pw.print(" trm:");
16638            if (r.trimMemoryLevel < 10) pw.print(' ');
16639            pw.print(r.trimMemoryLevel);
16640            pw.print(' ');
16641            pw.print(r.toShortString());
16642            pw.print(" (");
16643            pw.print(r.adjType);
16644            pw.println(')');
16645            if (r.adjSource != null || r.adjTarget != null) {
16646                pw.print(prefix);
16647                pw.print("    ");
16648                if (r.adjTarget instanceof ComponentName) {
16649                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16650                } else if (r.adjTarget != null) {
16651                    pw.print(r.adjTarget.toString());
16652                } else {
16653                    pw.print("{null}");
16654                }
16655                pw.print("<=");
16656                if (r.adjSource instanceof ProcessRecord) {
16657                    pw.print("Proc{");
16658                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16659                    pw.println("}");
16660                } else if (r.adjSource != null) {
16661                    pw.println(r.adjSource.toString());
16662                } else {
16663                    pw.println("{null}");
16664                }
16665            }
16666            if (inclDetails) {
16667                pw.print(prefix);
16668                pw.print("    ");
16669                pw.print("oom: max="); pw.print(r.maxAdj);
16670                pw.print(" curRaw="); pw.print(r.curRawAdj);
16671                pw.print(" setRaw="); pw.print(r.setRawAdj);
16672                pw.print(" cur="); pw.print(r.curAdj);
16673                pw.print(" set="); pw.println(r.setAdj);
16674                pw.print(prefix);
16675                pw.print("    ");
16676                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16677                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16678                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16679                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16680                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16681                pw.println();
16682                pw.print(prefix);
16683                pw.print("    ");
16684                pw.print("cached="); pw.print(r.cached);
16685                pw.print(" empty="); pw.print(r.empty);
16686                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16687
16688                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16689                    if (r.lastCpuTime != 0) {
16690                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16691                        pw.print(prefix);
16692                        pw.print("    ");
16693                        pw.print("run cpu over ");
16694                        TimeUtils.formatDuration(uptimeSince, pw);
16695                        pw.print(" used ");
16696                        TimeUtils.formatDuration(timeUsed, pw);
16697                        pw.print(" (");
16698                        pw.print((timeUsed*100)/uptimeSince);
16699                        pw.println("%)");
16700                    }
16701                }
16702            }
16703        }
16704        return true;
16705    }
16706
16707    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16708            String[] args) {
16709        ArrayList<ProcessRecord> procs;
16710        synchronized (this) {
16711            if (args != null && args.length > start
16712                    && args[start].charAt(0) != '-') {
16713                procs = new ArrayList<ProcessRecord>();
16714                int pid = -1;
16715                try {
16716                    pid = Integer.parseInt(args[start]);
16717                } catch (NumberFormatException e) {
16718                }
16719                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16720                    ProcessRecord proc = mLruProcesses.get(i);
16721                    if (proc.pid == pid) {
16722                        procs.add(proc);
16723                    } else if (allPkgs && proc.pkgList != null
16724                            && proc.pkgList.containsKey(args[start])) {
16725                        procs.add(proc);
16726                    } else if (proc.processName.equals(args[start])) {
16727                        procs.add(proc);
16728                    }
16729                }
16730                if (procs.size() <= 0) {
16731                    return null;
16732                }
16733            } else {
16734                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16735            }
16736        }
16737        return procs;
16738    }
16739
16740    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16741            PrintWriter pw, String[] args) {
16742        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16743        if (procs == null) {
16744            pw.println("No process found for: " + args[0]);
16745            return;
16746        }
16747
16748        long uptime = SystemClock.uptimeMillis();
16749        long realtime = SystemClock.elapsedRealtime();
16750        pw.println("Applications Graphics Acceleration Info:");
16751        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16752
16753        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16754            ProcessRecord r = procs.get(i);
16755            if (r.thread != null) {
16756                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16757                pw.flush();
16758                try {
16759                    TransferPipe tp = new TransferPipe();
16760                    try {
16761                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16762                        tp.go(fd);
16763                    } finally {
16764                        tp.kill();
16765                    }
16766                } catch (IOException e) {
16767                    pw.println("Failure while dumping the app: " + r);
16768                    pw.flush();
16769                } catch (RemoteException e) {
16770                    pw.println("Got a RemoteException while dumping the app " + r);
16771                    pw.flush();
16772                }
16773            }
16774        }
16775    }
16776
16777    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16778        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16779        if (procs == null) {
16780            pw.println("No process found for: " + args[0]);
16781            return;
16782        }
16783
16784        pw.println("Applications Database Info:");
16785
16786        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16787            ProcessRecord r = procs.get(i);
16788            if (r.thread != null) {
16789                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16790                pw.flush();
16791                try {
16792                    TransferPipe tp = new TransferPipe();
16793                    try {
16794                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16795                        tp.go(fd);
16796                    } finally {
16797                        tp.kill();
16798                    }
16799                } catch (IOException e) {
16800                    pw.println("Failure while dumping the app: " + r);
16801                    pw.flush();
16802                } catch (RemoteException e) {
16803                    pw.println("Got a RemoteException while dumping the app " + r);
16804                    pw.flush();
16805                }
16806            }
16807        }
16808    }
16809
16810    final static class MemItem {
16811        final boolean isProc;
16812        final String label;
16813        final String shortLabel;
16814        final long pss;
16815        final long swapPss;
16816        final int id;
16817        final boolean hasActivities;
16818        ArrayList<MemItem> subitems;
16819
16820        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16821                boolean _hasActivities) {
16822            isProc = true;
16823            label = _label;
16824            shortLabel = _shortLabel;
16825            pss = _pss;
16826            swapPss = _swapPss;
16827            id = _id;
16828            hasActivities = _hasActivities;
16829        }
16830
16831        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16832            isProc = false;
16833            label = _label;
16834            shortLabel = _shortLabel;
16835            pss = _pss;
16836            swapPss = _swapPss;
16837            id = _id;
16838            hasActivities = false;
16839        }
16840    }
16841
16842    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16843            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16844        if (sort && !isCompact) {
16845            Collections.sort(items, new Comparator<MemItem>() {
16846                @Override
16847                public int compare(MemItem lhs, MemItem rhs) {
16848                    if (lhs.pss < rhs.pss) {
16849                        return 1;
16850                    } else if (lhs.pss > rhs.pss) {
16851                        return -1;
16852                    }
16853                    return 0;
16854                }
16855            });
16856        }
16857
16858        for (int i=0; i<items.size(); i++) {
16859            MemItem mi = items.get(i);
16860            if (!isCompact) {
16861                if (dumpSwapPss) {
16862                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16863                            mi.label, stringifyKBSize(mi.swapPss));
16864                } else {
16865                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16866                }
16867            } else if (mi.isProc) {
16868                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16869                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16870                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16871                pw.println(mi.hasActivities ? ",a" : ",e");
16872            } else {
16873                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16874                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16875            }
16876            if (mi.subitems != null) {
16877                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16878                        true, isCompact, dumpSwapPss);
16879            }
16880        }
16881    }
16882
16883    // These are in KB.
16884    static final long[] DUMP_MEM_BUCKETS = new long[] {
16885        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16886        120*1024, 160*1024, 200*1024,
16887        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16888        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16889    };
16890
16891    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16892            boolean stackLike) {
16893        int start = label.lastIndexOf('.');
16894        if (start >= 0) start++;
16895        else start = 0;
16896        int end = label.length();
16897        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16898            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16899                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16900                out.append(bucket);
16901                out.append(stackLike ? "MB." : "MB ");
16902                out.append(label, start, end);
16903                return;
16904            }
16905        }
16906        out.append(memKB/1024);
16907        out.append(stackLike ? "MB." : "MB ");
16908        out.append(label, start, end);
16909    }
16910
16911    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16912            ProcessList.NATIVE_ADJ,
16913            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16914            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16915            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16916            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16917            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16918            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16919    };
16920    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16921            "Native",
16922            "System", "Persistent", "Persistent Service", "Foreground",
16923            "Visible", "Perceptible",
16924            "Heavy Weight", "Backup",
16925            "A Services", "Home",
16926            "Previous", "B Services", "Cached"
16927    };
16928    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16929            "native",
16930            "sys", "pers", "persvc", "fore",
16931            "vis", "percept",
16932            "heavy", "backup",
16933            "servicea", "home",
16934            "prev", "serviceb", "cached"
16935    };
16936
16937    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16938            long realtime, boolean isCheckinRequest, boolean isCompact) {
16939        if (isCompact) {
16940            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16941        }
16942        if (isCheckinRequest || isCompact) {
16943            // short checkin version
16944            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16945        } else {
16946            pw.println("Applications Memory Usage (in Kilobytes):");
16947            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16948        }
16949    }
16950
16951    private static final int KSM_SHARED = 0;
16952    private static final int KSM_SHARING = 1;
16953    private static final int KSM_UNSHARED = 2;
16954    private static final int KSM_VOLATILE = 3;
16955
16956    private final long[] getKsmInfo() {
16957        long[] longOut = new long[4];
16958        final int[] SINGLE_LONG_FORMAT = new int[] {
16959            PROC_SPACE_TERM| PROC_OUT_LONG
16960        };
16961        long[] longTmp = new long[1];
16962        readProcFile("/sys/kernel/mm/ksm/pages_shared",
16963                SINGLE_LONG_FORMAT, null, longTmp, null);
16964        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16965        longTmp[0] = 0;
16966        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16967                SINGLE_LONG_FORMAT, null, longTmp, null);
16968        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16969        longTmp[0] = 0;
16970        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16971                SINGLE_LONG_FORMAT, null, longTmp, null);
16972        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16973        longTmp[0] = 0;
16974        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16975                SINGLE_LONG_FORMAT, null, longTmp, null);
16976        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16977        return longOut;
16978    }
16979
16980    private static String stringifySize(long size, int order) {
16981        Locale locale = Locale.US;
16982        switch (order) {
16983            case 1:
16984                return String.format(locale, "%,13d", size);
16985            case 1024:
16986                return String.format(locale, "%,9dK", size / 1024);
16987            case 1024 * 1024:
16988                return String.format(locale, "%,5dM", size / 1024 / 1024);
16989            case 1024 * 1024 * 1024:
16990                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16991            default:
16992                throw new IllegalArgumentException("Invalid size order");
16993        }
16994    }
16995
16996    private static String stringifyKBSize(long size) {
16997        return stringifySize(size * 1024, 1024);
16998    }
16999
17000    // Update this version number in case you change the 'compact' format
17001    private static final int MEMINFO_COMPACT_VERSION = 1;
17002
17003    final void dumpApplicationMemoryUsage(FileDescriptor fd,
17004            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17005        boolean dumpDetails = false;
17006        boolean dumpFullDetails = false;
17007        boolean dumpDalvik = false;
17008        boolean dumpSummaryOnly = false;
17009        boolean dumpUnreachable = false;
17010        boolean oomOnly = false;
17011        boolean isCompact = false;
17012        boolean localOnly = false;
17013        boolean packages = false;
17014        boolean isCheckinRequest = false;
17015        boolean dumpSwapPss = false;
17016
17017        int opti = 0;
17018        while (opti < args.length) {
17019            String opt = args[opti];
17020            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17021                break;
17022            }
17023            opti++;
17024            if ("-a".equals(opt)) {
17025                dumpDetails = true;
17026                dumpFullDetails = true;
17027                dumpDalvik = true;
17028                dumpSwapPss = true;
17029            } else if ("-d".equals(opt)) {
17030                dumpDalvik = true;
17031            } else if ("-c".equals(opt)) {
17032                isCompact = true;
17033            } else if ("-s".equals(opt)) {
17034                dumpDetails = true;
17035                dumpSummaryOnly = true;
17036            } else if ("-S".equals(opt)) {
17037                dumpSwapPss = true;
17038            } else if ("--unreachable".equals(opt)) {
17039                dumpUnreachable = true;
17040            } else if ("--oom".equals(opt)) {
17041                oomOnly = true;
17042            } else if ("--local".equals(opt)) {
17043                localOnly = true;
17044            } else if ("--package".equals(opt)) {
17045                packages = true;
17046            } else if ("--checkin".equals(opt)) {
17047                isCheckinRequest = true;
17048
17049            } else if ("-h".equals(opt)) {
17050                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17051                pw.println("  -a: include all available information for each process.");
17052                pw.println("  -d: include dalvik details.");
17053                pw.println("  -c: dump in a compact machine-parseable representation.");
17054                pw.println("  -s: dump only summary of application memory usage.");
17055                pw.println("  -S: dump also SwapPss.");
17056                pw.println("  --oom: only show processes organized by oom adj.");
17057                pw.println("  --local: only collect details locally, don't call process.");
17058                pw.println("  --package: interpret process arg as package, dumping all");
17059                pw.println("             processes that have loaded that package.");
17060                pw.println("  --checkin: dump data for a checkin");
17061                pw.println("If [process] is specified it can be the name or ");
17062                pw.println("pid of a specific process to dump.");
17063                return;
17064            } else {
17065                pw.println("Unknown argument: " + opt + "; use -h for help");
17066            }
17067        }
17068
17069        long uptime = SystemClock.uptimeMillis();
17070        long realtime = SystemClock.elapsedRealtime();
17071        final long[] tmpLong = new long[1];
17072
17073        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17074        if (procs == null) {
17075            // No Java processes.  Maybe they want to print a native process.
17076            if (args != null && args.length > opti
17077                    && args[opti].charAt(0) != '-') {
17078                ArrayList<ProcessCpuTracker.Stats> nativeProcs
17079                        = new ArrayList<ProcessCpuTracker.Stats>();
17080                updateCpuStatsNow();
17081                int findPid = -1;
17082                try {
17083                    findPid = Integer.parseInt(args[opti]);
17084                } catch (NumberFormatException e) {
17085                }
17086                synchronized (mProcessCpuTracker) {
17087                    final int N = mProcessCpuTracker.countStats();
17088                    for (int i=0; i<N; i++) {
17089                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17090                        if (st.pid == findPid || (st.baseName != null
17091                                && st.baseName.equals(args[opti]))) {
17092                            nativeProcs.add(st);
17093                        }
17094                    }
17095                }
17096                if (nativeProcs.size() > 0) {
17097                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17098                            isCompact);
17099                    Debug.MemoryInfo mi = null;
17100                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17101                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17102                        final int pid = r.pid;
17103                        if (!isCheckinRequest && dumpDetails) {
17104                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17105                        }
17106                        if (mi == null) {
17107                            mi = new Debug.MemoryInfo();
17108                        }
17109                        if (dumpDetails || (!brief && !oomOnly)) {
17110                            Debug.getMemoryInfo(pid, mi);
17111                        } else {
17112                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17113                            mi.dalvikPrivateDirty = (int)tmpLong[0];
17114                        }
17115                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17116                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17117                        if (isCheckinRequest) {
17118                            pw.println();
17119                        }
17120                    }
17121                    return;
17122                }
17123            }
17124            pw.println("No process found for: " + args[opti]);
17125            return;
17126        }
17127
17128        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17129            dumpDetails = true;
17130        }
17131
17132        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17133
17134        String[] innerArgs = new String[args.length-opti];
17135        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17136
17137        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17138        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17139        long nativePss = 0;
17140        long nativeSwapPss = 0;
17141        long dalvikPss = 0;
17142        long dalvikSwapPss = 0;
17143        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17144                EmptyArray.LONG;
17145        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17146                EmptyArray.LONG;
17147        long otherPss = 0;
17148        long otherSwapPss = 0;
17149        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17150        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17151
17152        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17153        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17154        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17155                new ArrayList[DUMP_MEM_OOM_LABEL.length];
17156
17157        long totalPss = 0;
17158        long totalSwapPss = 0;
17159        long cachedPss = 0;
17160        long cachedSwapPss = 0;
17161        boolean hasSwapPss = false;
17162
17163        Debug.MemoryInfo mi = null;
17164        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17165            final ProcessRecord r = procs.get(i);
17166            final IApplicationThread thread;
17167            final int pid;
17168            final int oomAdj;
17169            final boolean hasActivities;
17170            synchronized (this) {
17171                thread = r.thread;
17172                pid = r.pid;
17173                oomAdj = r.getSetAdjWithServices();
17174                hasActivities = r.activities.size() > 0;
17175            }
17176            if (thread != null) {
17177                if (!isCheckinRequest && dumpDetails) {
17178                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17179                }
17180                if (mi == null) {
17181                    mi = new Debug.MemoryInfo();
17182                }
17183                if (dumpDetails || (!brief && !oomOnly)) {
17184                    Debug.getMemoryInfo(pid, mi);
17185                    hasSwapPss = mi.hasSwappedOutPss;
17186                } else {
17187                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17188                    mi.dalvikPrivateDirty = (int)tmpLong[0];
17189                }
17190                if (dumpDetails) {
17191                    if (localOnly) {
17192                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17193                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17194                        if (isCheckinRequest) {
17195                            pw.println();
17196                        }
17197                    } else {
17198                        pw.flush();
17199                        try {
17200                            TransferPipe tp = new TransferPipe();
17201                            try {
17202                                thread.dumpMemInfo(tp.getWriteFd(),
17203                                        mi, isCheckinRequest, dumpFullDetails,
17204                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17205                                tp.go(fd);
17206                            } finally {
17207                                tp.kill();
17208                            }
17209                        } catch (IOException e) {
17210                            if (!isCheckinRequest) {
17211                                pw.println("Got IoException! " + e);
17212                                pw.flush();
17213                            }
17214                        } catch (RemoteException e) {
17215                            if (!isCheckinRequest) {
17216                                pw.println("Got RemoteException! " + e);
17217                                pw.flush();
17218                            }
17219                        }
17220                    }
17221                }
17222
17223                final long myTotalPss = mi.getTotalPss();
17224                final long myTotalUss = mi.getTotalUss();
17225                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17226
17227                synchronized (this) {
17228                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17229                        // Record this for posterity if the process has been stable.
17230                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17231                    }
17232                }
17233
17234                if (!isCheckinRequest && mi != null) {
17235                    totalPss += myTotalPss;
17236                    totalSwapPss += myTotalSwapPss;
17237                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17238                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17239                            myTotalSwapPss, pid, hasActivities);
17240                    procMems.add(pssItem);
17241                    procMemsMap.put(pid, pssItem);
17242
17243                    nativePss += mi.nativePss;
17244                    nativeSwapPss += mi.nativeSwappedOutPss;
17245                    dalvikPss += mi.dalvikPss;
17246                    dalvikSwapPss += mi.dalvikSwappedOutPss;
17247                    for (int j=0; j<dalvikSubitemPss.length; j++) {
17248                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17249                        dalvikSubitemSwapPss[j] +=
17250                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17251                    }
17252                    otherPss += mi.otherPss;
17253                    otherSwapPss += mi.otherSwappedOutPss;
17254                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17255                        long mem = mi.getOtherPss(j);
17256                        miscPss[j] += mem;
17257                        otherPss -= mem;
17258                        mem = mi.getOtherSwappedOutPss(j);
17259                        miscSwapPss[j] += mem;
17260                        otherSwapPss -= mem;
17261                    }
17262
17263                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17264                        cachedPss += myTotalPss;
17265                        cachedSwapPss += myTotalSwapPss;
17266                    }
17267
17268                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17269                        if (oomIndex == (oomPss.length - 1)
17270                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17271                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17272                            oomPss[oomIndex] += myTotalPss;
17273                            oomSwapPss[oomIndex] += myTotalSwapPss;
17274                            if (oomProcs[oomIndex] == null) {
17275                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17276                            }
17277                            oomProcs[oomIndex].add(pssItem);
17278                            break;
17279                        }
17280                    }
17281                }
17282            }
17283        }
17284
17285        long nativeProcTotalPss = 0;
17286
17287        if (!isCheckinRequest && procs.size() > 1 && !packages) {
17288            // If we are showing aggregations, also look for native processes to
17289            // include so that our aggregations are more accurate.
17290            updateCpuStatsNow();
17291            mi = null;
17292            synchronized (mProcessCpuTracker) {
17293                final int N = mProcessCpuTracker.countStats();
17294                for (int i=0; i<N; i++) {
17295                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17296                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17297                        if (mi == null) {
17298                            mi = new Debug.MemoryInfo();
17299                        }
17300                        if (!brief && !oomOnly) {
17301                            Debug.getMemoryInfo(st.pid, mi);
17302                        } else {
17303                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17304                            mi.nativePrivateDirty = (int)tmpLong[0];
17305                        }
17306
17307                        final long myTotalPss = mi.getTotalPss();
17308                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17309                        totalPss += myTotalPss;
17310                        nativeProcTotalPss += myTotalPss;
17311
17312                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17313                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17314                        procMems.add(pssItem);
17315
17316                        nativePss += mi.nativePss;
17317                        nativeSwapPss += mi.nativeSwappedOutPss;
17318                        dalvikPss += mi.dalvikPss;
17319                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17320                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17321                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17322                            dalvikSubitemSwapPss[j] +=
17323                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17324                        }
17325                        otherPss += mi.otherPss;
17326                        otherSwapPss += mi.otherSwappedOutPss;
17327                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17328                            long mem = mi.getOtherPss(j);
17329                            miscPss[j] += mem;
17330                            otherPss -= mem;
17331                            mem = mi.getOtherSwappedOutPss(j);
17332                            miscSwapPss[j] += mem;
17333                            otherSwapPss -= mem;
17334                        }
17335                        oomPss[0] += myTotalPss;
17336                        oomSwapPss[0] += myTotalSwapPss;
17337                        if (oomProcs[0] == null) {
17338                            oomProcs[0] = new ArrayList<MemItem>();
17339                        }
17340                        oomProcs[0].add(pssItem);
17341                    }
17342                }
17343            }
17344
17345            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17346
17347            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17348            final int dalvikId = -2;
17349            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17350            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17351            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17352                String label = Debug.MemoryInfo.getOtherLabel(j);
17353                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17354            }
17355            if (dalvikSubitemPss.length > 0) {
17356                // Add dalvik subitems.
17357                for (MemItem memItem : catMems) {
17358                    int memItemStart = 0, memItemEnd = 0;
17359                    if (memItem.id == dalvikId) {
17360                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17361                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17362                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17363                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17364                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17365                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17366                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17367                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17368                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17369                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17370                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17371                    } else {
17372                        continue;  // No subitems, continue.
17373                    }
17374                    memItem.subitems = new ArrayList<MemItem>();
17375                    for (int j=memItemStart; j<=memItemEnd; j++) {
17376                        final String name = Debug.MemoryInfo.getOtherLabel(
17377                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
17378                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17379                                dalvikSubitemSwapPss[j], j));
17380                    }
17381                }
17382            }
17383
17384            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17385            for (int j=0; j<oomPss.length; j++) {
17386                if (oomPss[j] != 0) {
17387                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17388                            : DUMP_MEM_OOM_LABEL[j];
17389                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17390                            DUMP_MEM_OOM_ADJ[j]);
17391                    item.subitems = oomProcs[j];
17392                    oomMems.add(item);
17393                }
17394            }
17395
17396            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17397            if (!brief && !oomOnly && !isCompact) {
17398                pw.println();
17399                pw.println("Total PSS by process:");
17400                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17401                pw.println();
17402            }
17403            if (!isCompact) {
17404                pw.println("Total PSS by OOM adjustment:");
17405            }
17406            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17407            if (!brief && !oomOnly) {
17408                PrintWriter out = categoryPw != null ? categoryPw : pw;
17409                if (!isCompact) {
17410                    out.println();
17411                    out.println("Total PSS by category:");
17412                }
17413                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17414            }
17415            if (!isCompact) {
17416                pw.println();
17417            }
17418            MemInfoReader memInfo = new MemInfoReader();
17419            memInfo.readMemInfo();
17420            if (nativeProcTotalPss > 0) {
17421                synchronized (this) {
17422                    final long cachedKb = memInfo.getCachedSizeKb();
17423                    final long freeKb = memInfo.getFreeSizeKb();
17424                    final long zramKb = memInfo.getZramTotalSizeKb();
17425                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17426                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17427                            kernelKb*1024, nativeProcTotalPss*1024);
17428                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17429                            nativeProcTotalPss);
17430                }
17431            }
17432            if (!brief) {
17433                if (!isCompact) {
17434                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17435                    pw.print(" (status ");
17436                    switch (mLastMemoryLevel) {
17437                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17438                            pw.println("normal)");
17439                            break;
17440                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17441                            pw.println("moderate)");
17442                            break;
17443                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17444                            pw.println("low)");
17445                            break;
17446                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17447                            pw.println("critical)");
17448                            break;
17449                        default:
17450                            pw.print(mLastMemoryLevel);
17451                            pw.println(")");
17452                            break;
17453                    }
17454                    pw.print(" Free RAM: ");
17455                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17456                            + memInfo.getFreeSizeKb()));
17457                    pw.print(" (");
17458                    pw.print(stringifyKBSize(cachedPss));
17459                    pw.print(" cached pss + ");
17460                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17461                    pw.print(" cached kernel + ");
17462                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17463                    pw.println(" free)");
17464                } else {
17465                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17466                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17467                            + memInfo.getFreeSizeKb()); pw.print(",");
17468                    pw.println(totalPss - cachedPss);
17469                }
17470            }
17471            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17472                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17473                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17474            if (!isCompact) {
17475                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17476                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17477                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17478                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17479                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17480            } else {
17481                pw.print("lostram,"); pw.println(lostRAM);
17482            }
17483            if (!brief) {
17484                if (memInfo.getZramTotalSizeKb() != 0) {
17485                    if (!isCompact) {
17486                        pw.print("     ZRAM: ");
17487                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17488                                pw.print(" physical used for ");
17489                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17490                                        - memInfo.getSwapFreeSizeKb()));
17491                                pw.print(" in swap (");
17492                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17493                                pw.println(" total swap)");
17494                    } else {
17495                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17496                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17497                                pw.println(memInfo.getSwapFreeSizeKb());
17498                    }
17499                }
17500                final long[] ksm = getKsmInfo();
17501                if (!isCompact) {
17502                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17503                            || ksm[KSM_VOLATILE] != 0) {
17504                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17505                                pw.print(" saved from shared ");
17506                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17507                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17508                                pw.print(" unshared; ");
17509                                pw.print(stringifyKBSize(
17510                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17511                    }
17512                    pw.print("   Tuning: ");
17513                    pw.print(ActivityManager.staticGetMemoryClass());
17514                    pw.print(" (large ");
17515                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17516                    pw.print("), oom ");
17517                    pw.print(stringifySize(
17518                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17519                    pw.print(", restore limit ");
17520                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17521                    if (ActivityManager.isLowRamDeviceStatic()) {
17522                        pw.print(" (low-ram)");
17523                    }
17524                    if (ActivityManager.isHighEndGfx()) {
17525                        pw.print(" (high-end-gfx)");
17526                    }
17527                    pw.println();
17528                } else {
17529                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17530                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17531                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17532                    pw.print("tuning,");
17533                    pw.print(ActivityManager.staticGetMemoryClass());
17534                    pw.print(',');
17535                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17536                    pw.print(',');
17537                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17538                    if (ActivityManager.isLowRamDeviceStatic()) {
17539                        pw.print(",low-ram");
17540                    }
17541                    if (ActivityManager.isHighEndGfx()) {
17542                        pw.print(",high-end-gfx");
17543                    }
17544                    pw.println();
17545                }
17546            }
17547        }
17548    }
17549
17550    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17551            long memtrack, String name) {
17552        sb.append("  ");
17553        sb.append(ProcessList.makeOomAdjString(oomAdj));
17554        sb.append(' ');
17555        sb.append(ProcessList.makeProcStateString(procState));
17556        sb.append(' ');
17557        ProcessList.appendRamKb(sb, pss);
17558        sb.append(": ");
17559        sb.append(name);
17560        if (memtrack > 0) {
17561            sb.append(" (");
17562            sb.append(stringifyKBSize(memtrack));
17563            sb.append(" memtrack)");
17564        }
17565    }
17566
17567    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17568        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17569        sb.append(" (pid ");
17570        sb.append(mi.pid);
17571        sb.append(") ");
17572        sb.append(mi.adjType);
17573        sb.append('\n');
17574        if (mi.adjReason != null) {
17575            sb.append("                      ");
17576            sb.append(mi.adjReason);
17577            sb.append('\n');
17578        }
17579    }
17580
17581    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17582        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17583        for (int i=0, N=memInfos.size(); i<N; i++) {
17584            ProcessMemInfo mi = memInfos.get(i);
17585            infoMap.put(mi.pid, mi);
17586        }
17587        updateCpuStatsNow();
17588        long[] memtrackTmp = new long[1];
17589        final List<ProcessCpuTracker.Stats> stats;
17590        // Get a list of Stats that have vsize > 0
17591        synchronized (mProcessCpuTracker) {
17592            stats = mProcessCpuTracker.getStats((st) -> {
17593                return st.vsize > 0;
17594            });
17595        }
17596        final int statsCount = stats.size();
17597        for (int i = 0; i < statsCount; i++) {
17598            ProcessCpuTracker.Stats st = stats.get(i);
17599            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17600            if (pss > 0) {
17601                if (infoMap.indexOfKey(st.pid) < 0) {
17602                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17603                            ProcessList.NATIVE_ADJ, -1, "native", null);
17604                    mi.pss = pss;
17605                    mi.memtrack = memtrackTmp[0];
17606                    memInfos.add(mi);
17607                }
17608            }
17609        }
17610
17611        long totalPss = 0;
17612        long totalMemtrack = 0;
17613        for (int i=0, N=memInfos.size(); i<N; i++) {
17614            ProcessMemInfo mi = memInfos.get(i);
17615            if (mi.pss == 0) {
17616                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17617                mi.memtrack = memtrackTmp[0];
17618            }
17619            totalPss += mi.pss;
17620            totalMemtrack += mi.memtrack;
17621        }
17622        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17623            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17624                if (lhs.oomAdj != rhs.oomAdj) {
17625                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17626                }
17627                if (lhs.pss != rhs.pss) {
17628                    return lhs.pss < rhs.pss ? 1 : -1;
17629                }
17630                return 0;
17631            }
17632        });
17633
17634        StringBuilder tag = new StringBuilder(128);
17635        StringBuilder stack = new StringBuilder(128);
17636        tag.append("Low on memory -- ");
17637        appendMemBucket(tag, totalPss, "total", false);
17638        appendMemBucket(stack, totalPss, "total", true);
17639
17640        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17641        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17642        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17643
17644        boolean firstLine = true;
17645        int lastOomAdj = Integer.MIN_VALUE;
17646        long extraNativeRam = 0;
17647        long extraNativeMemtrack = 0;
17648        long cachedPss = 0;
17649        for (int i=0, N=memInfos.size(); i<N; i++) {
17650            ProcessMemInfo mi = memInfos.get(i);
17651
17652            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17653                cachedPss += mi.pss;
17654            }
17655
17656            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17657                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17658                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17659                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17660                if (lastOomAdj != mi.oomAdj) {
17661                    lastOomAdj = mi.oomAdj;
17662                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17663                        tag.append(" / ");
17664                    }
17665                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17666                        if (firstLine) {
17667                            stack.append(":");
17668                            firstLine = false;
17669                        }
17670                        stack.append("\n\t at ");
17671                    } else {
17672                        stack.append("$");
17673                    }
17674                } else {
17675                    tag.append(" ");
17676                    stack.append("$");
17677                }
17678                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17679                    appendMemBucket(tag, mi.pss, mi.name, false);
17680                }
17681                appendMemBucket(stack, mi.pss, mi.name, true);
17682                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17683                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17684                    stack.append("(");
17685                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17686                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17687                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17688                            stack.append(":");
17689                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17690                        }
17691                    }
17692                    stack.append(")");
17693                }
17694            }
17695
17696            appendMemInfo(fullNativeBuilder, mi);
17697            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17698                // The short form only has native processes that are >= 512K.
17699                if (mi.pss >= 512) {
17700                    appendMemInfo(shortNativeBuilder, mi);
17701                } else {
17702                    extraNativeRam += mi.pss;
17703                    extraNativeMemtrack += mi.memtrack;
17704                }
17705            } else {
17706                // Short form has all other details, but if we have collected RAM
17707                // from smaller native processes let's dump a summary of that.
17708                if (extraNativeRam > 0) {
17709                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17710                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17711                    shortNativeBuilder.append('\n');
17712                    extraNativeRam = 0;
17713                }
17714                appendMemInfo(fullJavaBuilder, mi);
17715            }
17716        }
17717
17718        fullJavaBuilder.append("           ");
17719        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17720        fullJavaBuilder.append(": TOTAL");
17721        if (totalMemtrack > 0) {
17722            fullJavaBuilder.append(" (");
17723            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17724            fullJavaBuilder.append(" memtrack)");
17725        } else {
17726        }
17727        fullJavaBuilder.append("\n");
17728
17729        MemInfoReader memInfo = new MemInfoReader();
17730        memInfo.readMemInfo();
17731        final long[] infos = memInfo.getRawInfo();
17732
17733        StringBuilder memInfoBuilder = new StringBuilder(1024);
17734        Debug.getMemInfo(infos);
17735        memInfoBuilder.append("  MemInfo: ");
17736        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17737        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17738        memInfoBuilder.append(stringifyKBSize(
17739                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17740        memInfoBuilder.append(stringifyKBSize(
17741                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17742        memInfoBuilder.append(stringifyKBSize(
17743                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17744        memInfoBuilder.append("           ");
17745        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17746        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17747        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17748        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17749        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17750            memInfoBuilder.append("  ZRAM: ");
17751            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17752            memInfoBuilder.append(" RAM, ");
17753            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17754            memInfoBuilder.append(" swap total, ");
17755            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17756            memInfoBuilder.append(" swap free\n");
17757        }
17758        final long[] ksm = getKsmInfo();
17759        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17760                || ksm[KSM_VOLATILE] != 0) {
17761            memInfoBuilder.append("  KSM: ");
17762            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17763            memInfoBuilder.append(" saved from shared ");
17764            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17765            memInfoBuilder.append("\n       ");
17766            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17767            memInfoBuilder.append(" unshared; ");
17768            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17769            memInfoBuilder.append(" volatile\n");
17770        }
17771        memInfoBuilder.append("  Free RAM: ");
17772        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17773                + memInfo.getFreeSizeKb()));
17774        memInfoBuilder.append("\n");
17775        memInfoBuilder.append("  Used RAM: ");
17776        memInfoBuilder.append(stringifyKBSize(
17777                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17778        memInfoBuilder.append("\n");
17779        memInfoBuilder.append("  Lost RAM: ");
17780        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17781                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17782                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17783        memInfoBuilder.append("\n");
17784        Slog.i(TAG, "Low on memory:");
17785        Slog.i(TAG, shortNativeBuilder.toString());
17786        Slog.i(TAG, fullJavaBuilder.toString());
17787        Slog.i(TAG, memInfoBuilder.toString());
17788
17789        StringBuilder dropBuilder = new StringBuilder(1024);
17790        /*
17791        StringWriter oomSw = new StringWriter();
17792        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17793        StringWriter catSw = new StringWriter();
17794        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17795        String[] emptyArgs = new String[] { };
17796        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17797        oomPw.flush();
17798        String oomString = oomSw.toString();
17799        */
17800        dropBuilder.append("Low on memory:");
17801        dropBuilder.append(stack);
17802        dropBuilder.append('\n');
17803        dropBuilder.append(fullNativeBuilder);
17804        dropBuilder.append(fullJavaBuilder);
17805        dropBuilder.append('\n');
17806        dropBuilder.append(memInfoBuilder);
17807        dropBuilder.append('\n');
17808        /*
17809        dropBuilder.append(oomString);
17810        dropBuilder.append('\n');
17811        */
17812        StringWriter catSw = new StringWriter();
17813        synchronized (ActivityManagerService.this) {
17814            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17815            String[] emptyArgs = new String[] { };
17816            catPw.println();
17817            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17818            catPw.println();
17819            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17820                    false, null).dumpLocked();
17821            catPw.println();
17822            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17823            catPw.flush();
17824        }
17825        dropBuilder.append(catSw.toString());
17826        addErrorToDropBox("lowmem", null, "system_server", null,
17827                null, tag.toString(), dropBuilder.toString(), null, null);
17828        //Slog.i(TAG, "Sent to dropbox:");
17829        //Slog.i(TAG, dropBuilder.toString());
17830        synchronized (ActivityManagerService.this) {
17831            long now = SystemClock.uptimeMillis();
17832            if (mLastMemUsageReportTime < now) {
17833                mLastMemUsageReportTime = now;
17834            }
17835        }
17836    }
17837
17838    /**
17839     * Searches array of arguments for the specified string
17840     * @param args array of argument strings
17841     * @param value value to search for
17842     * @return true if the value is contained in the array
17843     */
17844    private static boolean scanArgs(String[] args, String value) {
17845        if (args != null) {
17846            for (String arg : args) {
17847                if (value.equals(arg)) {
17848                    return true;
17849                }
17850            }
17851        }
17852        return false;
17853    }
17854
17855    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17856            ContentProviderRecord cpr, boolean always) {
17857        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17858
17859        if (!inLaunching || always) {
17860            synchronized (cpr) {
17861                cpr.launchingApp = null;
17862                cpr.notifyAll();
17863            }
17864            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17865            String names[] = cpr.info.authority.split(";");
17866            for (int j = 0; j < names.length; j++) {
17867                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17868            }
17869        }
17870
17871        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17872            ContentProviderConnection conn = cpr.connections.get(i);
17873            if (conn.waiting) {
17874                // If this connection is waiting for the provider, then we don't
17875                // need to mess with its process unless we are always removing
17876                // or for some reason the provider is not currently launching.
17877                if (inLaunching && !always) {
17878                    continue;
17879                }
17880            }
17881            ProcessRecord capp = conn.client;
17882            conn.dead = true;
17883            if (conn.stableCount > 0) {
17884                if (!capp.persistent && capp.thread != null
17885                        && capp.pid != 0
17886                        && capp.pid != MY_PID) {
17887                    capp.kill("depends on provider "
17888                            + cpr.name.flattenToShortString()
17889                            + " in dying proc " + (proc != null ? proc.processName : "??")
17890                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17891                }
17892            } else if (capp.thread != null && conn.provider.provider != null) {
17893                try {
17894                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17895                } catch (RemoteException e) {
17896                }
17897                // In the protocol here, we don't expect the client to correctly
17898                // clean up this connection, we'll just remove it.
17899                cpr.connections.remove(i);
17900                if (conn.client.conProviders.remove(conn)) {
17901                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17902                }
17903            }
17904        }
17905
17906        if (inLaunching && always) {
17907            mLaunchingProviders.remove(cpr);
17908        }
17909        return inLaunching;
17910    }
17911
17912    /**
17913     * Main code for cleaning up a process when it has gone away.  This is
17914     * called both as a result of the process dying, or directly when stopping
17915     * a process when running in single process mode.
17916     *
17917     * @return Returns true if the given process has been restarted, so the
17918     * app that was passed in must remain on the process lists.
17919     */
17920    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17921            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17922        if (index >= 0) {
17923            removeLruProcessLocked(app);
17924            ProcessList.remove(app.pid);
17925        }
17926
17927        mProcessesToGc.remove(app);
17928        mPendingPssProcesses.remove(app);
17929
17930        // Dismiss any open dialogs.
17931        if (app.crashDialog != null && !app.forceCrashReport) {
17932            app.crashDialog.dismiss();
17933            app.crashDialog = null;
17934        }
17935        if (app.anrDialog != null) {
17936            app.anrDialog.dismiss();
17937            app.anrDialog = null;
17938        }
17939        if (app.waitDialog != null) {
17940            app.waitDialog.dismiss();
17941            app.waitDialog = null;
17942        }
17943
17944        app.crashing = false;
17945        app.notResponding = false;
17946
17947        app.resetPackageList(mProcessStats);
17948        app.unlinkDeathRecipient();
17949        app.makeInactive(mProcessStats);
17950        app.waitingToKill = null;
17951        app.forcingToImportant = null;
17952        updateProcessForegroundLocked(app, false, false);
17953        app.foregroundActivities = false;
17954        app.hasShownUi = false;
17955        app.treatLikeActivity = false;
17956        app.hasAboveClient = false;
17957        app.hasClientActivities = false;
17958
17959        mServices.killServicesLocked(app, allowRestart);
17960
17961        boolean restart = false;
17962
17963        // Remove published content providers.
17964        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17965            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17966            final boolean always = app.bad || !allowRestart;
17967            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17968            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17969                // We left the provider in the launching list, need to
17970                // restart it.
17971                restart = true;
17972            }
17973
17974            cpr.provider = null;
17975            cpr.proc = null;
17976        }
17977        app.pubProviders.clear();
17978
17979        // Take care of any launching providers waiting for this process.
17980        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17981            restart = true;
17982        }
17983
17984        // Unregister from connected content providers.
17985        if (!app.conProviders.isEmpty()) {
17986            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17987                ContentProviderConnection conn = app.conProviders.get(i);
17988                conn.provider.connections.remove(conn);
17989                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17990                        conn.provider.name);
17991            }
17992            app.conProviders.clear();
17993        }
17994
17995        // At this point there may be remaining entries in mLaunchingProviders
17996        // where we were the only one waiting, so they are no longer of use.
17997        // Look for these and clean up if found.
17998        // XXX Commented out for now.  Trying to figure out a way to reproduce
17999        // the actual situation to identify what is actually going on.
18000        if (false) {
18001            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18002                ContentProviderRecord cpr = mLaunchingProviders.get(i);
18003                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18004                    synchronized (cpr) {
18005                        cpr.launchingApp = null;
18006                        cpr.notifyAll();
18007                    }
18008                }
18009            }
18010        }
18011
18012        skipCurrentReceiverLocked(app);
18013
18014        // Unregister any receivers.
18015        for (int i = app.receivers.size() - 1; i >= 0; i--) {
18016            removeReceiverLocked(app.receivers.valueAt(i));
18017        }
18018        app.receivers.clear();
18019
18020        // If the app is undergoing backup, tell the backup manager about it
18021        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18022            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18023                    + mBackupTarget.appInfo + " died during backup");
18024            mHandler.post(new Runnable() {
18025                @Override
18026                public void run(){
18027                    try {
18028                        IBackupManager bm = IBackupManager.Stub.asInterface(
18029                                ServiceManager.getService(Context.BACKUP_SERVICE));
18030                        bm.agentDisconnected(app.info.packageName);
18031                    } catch (RemoteException e) {
18032                        // can't happen; backup manager is local
18033                    }
18034                }
18035            });
18036        }
18037
18038        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18039            ProcessChangeItem item = mPendingProcessChanges.get(i);
18040            if (item.pid == app.pid) {
18041                mPendingProcessChanges.remove(i);
18042                mAvailProcessChanges.add(item);
18043            }
18044        }
18045        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18046                null).sendToTarget();
18047
18048        // If the caller is restarting this app, then leave it in its
18049        // current lists and let the caller take care of it.
18050        if (restarting) {
18051            return false;
18052        }
18053
18054        if (!app.persistent || app.isolated) {
18055            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18056                    "Removing non-persistent process during cleanup: " + app);
18057            if (!replacingPid) {
18058                removeProcessNameLocked(app.processName, app.uid, app);
18059            }
18060            if (mHeavyWeightProcess == app) {
18061                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18062                        mHeavyWeightProcess.userId, 0));
18063                mHeavyWeightProcess = null;
18064            }
18065        } else if (!app.removed) {
18066            // This app is persistent, so we need to keep its record around.
18067            // If it is not already on the pending app list, add it there
18068            // and start a new process for it.
18069            if (mPersistentStartingProcesses.indexOf(app) < 0) {
18070                mPersistentStartingProcesses.add(app);
18071                restart = true;
18072            }
18073        }
18074        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18075                TAG_CLEANUP, "Clean-up removing on hold: " + app);
18076        mProcessesOnHold.remove(app);
18077
18078        if (app == mHomeProcess) {
18079            mHomeProcess = null;
18080        }
18081        if (app == mPreviousProcess) {
18082            mPreviousProcess = null;
18083        }
18084
18085        if (restart && !app.isolated) {
18086            // We have components that still need to be running in the
18087            // process, so re-launch it.
18088            if (index < 0) {
18089                ProcessList.remove(app.pid);
18090            }
18091            addProcessNameLocked(app);
18092            startProcessLocked(app, "restart", app.processName);
18093            return true;
18094        } else if (app.pid > 0 && app.pid != MY_PID) {
18095            // Goodbye!
18096            boolean removed;
18097            synchronized (mPidsSelfLocked) {
18098                mPidsSelfLocked.remove(app.pid);
18099                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18100            }
18101            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18102            if (app.isolated) {
18103                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18104            }
18105            app.setPid(0);
18106        }
18107        return false;
18108    }
18109
18110    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18111        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18112            ContentProviderRecord cpr = mLaunchingProviders.get(i);
18113            if (cpr.launchingApp == app) {
18114                return true;
18115            }
18116        }
18117        return false;
18118    }
18119
18120    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18121        // Look through the content providers we are waiting to have launched,
18122        // and if any run in this process then either schedule a restart of
18123        // the process or kill the client waiting for it if this process has
18124        // gone bad.
18125        boolean restart = false;
18126        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18127            ContentProviderRecord cpr = mLaunchingProviders.get(i);
18128            if (cpr.launchingApp == app) {
18129                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18130                    restart = true;
18131                } else {
18132                    removeDyingProviderLocked(app, cpr, true);
18133                }
18134            }
18135        }
18136        return restart;
18137    }
18138
18139    // =========================================================
18140    // SERVICES
18141    // =========================================================
18142
18143    @Override
18144    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18145            int flags) {
18146        enforceNotIsolatedCaller("getServices");
18147
18148        final int callingUid = Binder.getCallingUid();
18149        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18150            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18151        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18152            callingUid);
18153        synchronized (this) {
18154            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18155                allowed, canInteractAcrossUsers);
18156        }
18157    }
18158
18159    @Override
18160    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18161        enforceNotIsolatedCaller("getRunningServiceControlPanel");
18162        synchronized (this) {
18163            return mServices.getRunningServiceControlPanelLocked(name);
18164        }
18165    }
18166
18167    @Override
18168    public ComponentName startService(IApplicationThread caller, Intent service,
18169            String resolvedType, boolean requireForeground, String callingPackage, int userId)
18170            throws TransactionTooLargeException {
18171        enforceNotIsolatedCaller("startService");
18172        // Refuse possible leaked file descriptors
18173        if (service != null && service.hasFileDescriptors() == true) {
18174            throw new IllegalArgumentException("File descriptors passed in Intent");
18175        }
18176
18177        if (callingPackage == null) {
18178            throw new IllegalArgumentException("callingPackage cannot be null");
18179        }
18180
18181        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18182                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18183        synchronized(this) {
18184            final int callingPid = Binder.getCallingPid();
18185            final int callingUid = Binder.getCallingUid();
18186            final long origId = Binder.clearCallingIdentity();
18187            ComponentName res;
18188            try {
18189                res = mServices.startServiceLocked(caller, service,
18190                        resolvedType, callingPid, callingUid,
18191                        requireForeground, callingPackage, userId);
18192            } finally {
18193                Binder.restoreCallingIdentity(origId);
18194            }
18195            return res;
18196        }
18197    }
18198
18199    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18200            boolean fgRequired, String callingPackage, int userId)
18201            throws TransactionTooLargeException {
18202        synchronized(this) {
18203            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18204                    "startServiceInPackage: " + service + " type=" + resolvedType);
18205            final long origId = Binder.clearCallingIdentity();
18206            ComponentName res;
18207            try {
18208                res = mServices.startServiceLocked(null, service,
18209                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
18210            } finally {
18211                Binder.restoreCallingIdentity(origId);
18212            }
18213            return res;
18214        }
18215    }
18216
18217    @Override
18218    public int stopService(IApplicationThread caller, Intent service,
18219            String resolvedType, int userId) {
18220        enforceNotIsolatedCaller("stopService");
18221        // Refuse possible leaked file descriptors
18222        if (service != null && service.hasFileDescriptors() == true) {
18223            throw new IllegalArgumentException("File descriptors passed in Intent");
18224        }
18225
18226        synchronized(this) {
18227            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18228        }
18229    }
18230
18231    @Override
18232    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18233        enforceNotIsolatedCaller("peekService");
18234        // Refuse possible leaked file descriptors
18235        if (service != null && service.hasFileDescriptors() == true) {
18236            throw new IllegalArgumentException("File descriptors passed in Intent");
18237        }
18238
18239        if (callingPackage == null) {
18240            throw new IllegalArgumentException("callingPackage cannot be null");
18241        }
18242
18243        synchronized(this) {
18244            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18245        }
18246    }
18247
18248    @Override
18249    public boolean stopServiceToken(ComponentName className, IBinder token,
18250            int startId) {
18251        synchronized(this) {
18252            return mServices.stopServiceTokenLocked(className, token, startId);
18253        }
18254    }
18255
18256    @Override
18257    public void setServiceForeground(ComponentName className, IBinder token,
18258            int id, Notification notification, int flags) {
18259        synchronized(this) {
18260            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18261        }
18262    }
18263
18264    @Override
18265    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18266            boolean requireFull, String name, String callerPackage) {
18267        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18268                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18269    }
18270
18271    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18272            String className, int flags) {
18273        boolean result = false;
18274        // For apps that don't have pre-defined UIDs, check for permission
18275        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18276            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18277                if (ActivityManager.checkUidPermission(
18278                        INTERACT_ACROSS_USERS,
18279                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18280                    ComponentName comp = new ComponentName(aInfo.packageName, className);
18281                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
18282                            + " requests FLAG_SINGLE_USER, but app does not hold "
18283                            + INTERACT_ACROSS_USERS;
18284                    Slog.w(TAG, msg);
18285                    throw new SecurityException(msg);
18286                }
18287                // Permission passed
18288                result = true;
18289            }
18290        } else if ("system".equals(componentProcessName)) {
18291            result = true;
18292        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18293            // Phone app and persistent apps are allowed to export singleuser providers.
18294            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18295                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18296        }
18297        if (DEBUG_MU) Slog.v(TAG_MU,
18298                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18299                + Integer.toHexString(flags) + ") = " + result);
18300        return result;
18301    }
18302
18303    /**
18304     * Checks to see if the caller is in the same app as the singleton
18305     * component, or the component is in a special app. It allows special apps
18306     * to export singleton components but prevents exporting singleton
18307     * components for regular apps.
18308     */
18309    boolean isValidSingletonCall(int callingUid, int componentUid) {
18310        int componentAppId = UserHandle.getAppId(componentUid);
18311        return UserHandle.isSameApp(callingUid, componentUid)
18312                || componentAppId == SYSTEM_UID
18313                || componentAppId == PHONE_UID
18314                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18315                        == PackageManager.PERMISSION_GRANTED;
18316    }
18317
18318    public int bindService(IApplicationThread caller, IBinder token, Intent service,
18319            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18320            int userId) throws TransactionTooLargeException {
18321        enforceNotIsolatedCaller("bindService");
18322
18323        // Refuse possible leaked file descriptors
18324        if (service != null && service.hasFileDescriptors() == true) {
18325            throw new IllegalArgumentException("File descriptors passed in Intent");
18326        }
18327
18328        if (callingPackage == null) {
18329            throw new IllegalArgumentException("callingPackage cannot be null");
18330        }
18331
18332        synchronized(this) {
18333            return mServices.bindServiceLocked(caller, token, service,
18334                    resolvedType, connection, flags, callingPackage, userId);
18335        }
18336    }
18337
18338    public boolean unbindService(IServiceConnection connection) {
18339        synchronized (this) {
18340            return mServices.unbindServiceLocked(connection);
18341        }
18342    }
18343
18344    public void publishService(IBinder token, Intent intent, IBinder service) {
18345        // Refuse possible leaked file descriptors
18346        if (intent != null && intent.hasFileDescriptors() == true) {
18347            throw new IllegalArgumentException("File descriptors passed in Intent");
18348        }
18349
18350        synchronized(this) {
18351            if (!(token instanceof ServiceRecord)) {
18352                throw new IllegalArgumentException("Invalid service token");
18353            }
18354            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18355        }
18356    }
18357
18358    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18359        // Refuse possible leaked file descriptors
18360        if (intent != null && intent.hasFileDescriptors() == true) {
18361            throw new IllegalArgumentException("File descriptors passed in Intent");
18362        }
18363
18364        synchronized(this) {
18365            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18366        }
18367    }
18368
18369    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18370        synchronized(this) {
18371            if (!(token instanceof ServiceRecord)) {
18372                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18373                throw new IllegalArgumentException("Invalid service token");
18374            }
18375            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18376        }
18377    }
18378
18379    // =========================================================
18380    // BACKUP AND RESTORE
18381    // =========================================================
18382
18383    // Cause the target app to be launched if necessary and its backup agent
18384    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18385    // activity manager to announce its creation.
18386    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18387        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18388        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18389
18390        IPackageManager pm = AppGlobals.getPackageManager();
18391        ApplicationInfo app = null;
18392        try {
18393            app = pm.getApplicationInfo(packageName, 0, userId);
18394        } catch (RemoteException e) {
18395            // can't happen; package manager is process-local
18396        }
18397        if (app == null) {
18398            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18399            return false;
18400        }
18401
18402        int oldBackupUid;
18403        int newBackupUid;
18404
18405        synchronized(this) {
18406            // !!! TODO: currently no check here that we're already bound
18407            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18408            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18409            synchronized (stats) {
18410                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18411            }
18412
18413            // Backup agent is now in use, its package can't be stopped.
18414            try {
18415                AppGlobals.getPackageManager().setPackageStoppedState(
18416                        app.packageName, false, UserHandle.getUserId(app.uid));
18417            } catch (RemoteException e) {
18418            } catch (IllegalArgumentException e) {
18419                Slog.w(TAG, "Failed trying to unstop package "
18420                        + app.packageName + ": " + e);
18421            }
18422
18423            BackupRecord r = new BackupRecord(ss, app, backupMode);
18424            ComponentName hostingName =
18425                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18426                            ? new ComponentName(app.packageName, app.backupAgentName)
18427                            : new ComponentName("android", "FullBackupAgent");
18428            // startProcessLocked() returns existing proc's record if it's already running
18429            ProcessRecord proc = startProcessLocked(app.processName, app,
18430                    false, 0, "backup", hostingName, false, false, false);
18431            if (proc == null) {
18432                Slog.e(TAG, "Unable to start backup agent process " + r);
18433                return false;
18434            }
18435
18436            // If the app is a regular app (uid >= 10000) and not the system server or phone
18437            // process, etc, then mark it as being in full backup so that certain calls to the
18438            // process can be blocked. This is not reset to false anywhere because we kill the
18439            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18440            if (UserHandle.isApp(app.uid) &&
18441                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18442                proc.inFullBackup = true;
18443            }
18444            r.app = proc;
18445            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18446            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18447            mBackupTarget = r;
18448            mBackupAppName = app.packageName;
18449
18450            // Try not to kill the process during backup
18451            updateOomAdjLocked(proc, true);
18452
18453            // If the process is already attached, schedule the creation of the backup agent now.
18454            // If it is not yet live, this will be done when it attaches to the framework.
18455            if (proc.thread != null) {
18456                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18457                try {
18458                    proc.thread.scheduleCreateBackupAgent(app,
18459                            compatibilityInfoForPackageLocked(app), backupMode);
18460                } catch (RemoteException e) {
18461                    // Will time out on the backup manager side
18462                }
18463            } else {
18464                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18465            }
18466            // Invariants: at this point, the target app process exists and the application
18467            // is either already running or in the process of coming up.  mBackupTarget and
18468            // mBackupAppName describe the app, so that when it binds back to the AM we
18469            // know that it's scheduled for a backup-agent operation.
18470        }
18471
18472        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18473        if (oldBackupUid != -1) {
18474            js.removeBackingUpUid(oldBackupUid);
18475        }
18476        if (newBackupUid != -1) {
18477            js.addBackingUpUid(newBackupUid);
18478        }
18479
18480        return true;
18481    }
18482
18483    @Override
18484    public void clearPendingBackup() {
18485        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18486        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18487
18488        synchronized (this) {
18489            mBackupTarget = null;
18490            mBackupAppName = null;
18491        }
18492
18493        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18494        js.clearAllBackingUpUids();
18495    }
18496
18497    // A backup agent has just come up
18498    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18499        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18500                + " = " + agent);
18501
18502        synchronized(this) {
18503            if (!agentPackageName.equals(mBackupAppName)) {
18504                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18505                return;
18506            }
18507        }
18508
18509        long oldIdent = Binder.clearCallingIdentity();
18510        try {
18511            IBackupManager bm = IBackupManager.Stub.asInterface(
18512                    ServiceManager.getService(Context.BACKUP_SERVICE));
18513            bm.agentConnected(agentPackageName, agent);
18514        } catch (RemoteException e) {
18515            // can't happen; the backup manager service is local
18516        } catch (Exception e) {
18517            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18518            e.printStackTrace();
18519        } finally {
18520            Binder.restoreCallingIdentity(oldIdent);
18521        }
18522    }
18523
18524    // done with this agent
18525    public void unbindBackupAgent(ApplicationInfo appInfo) {
18526        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18527        if (appInfo == null) {
18528            Slog.w(TAG, "unbind backup agent for null app");
18529            return;
18530        }
18531
18532        int oldBackupUid;
18533
18534        synchronized(this) {
18535            try {
18536                if (mBackupAppName == null) {
18537                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18538                    return;
18539                }
18540
18541                if (!mBackupAppName.equals(appInfo.packageName)) {
18542                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18543                    return;
18544                }
18545
18546                // Not backing this app up any more; reset its OOM adjustment
18547                final ProcessRecord proc = mBackupTarget.app;
18548                updateOomAdjLocked(proc, true);
18549                proc.inFullBackup = false;
18550
18551                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18552
18553                // If the app crashed during backup, 'thread' will be null here
18554                if (proc.thread != null) {
18555                    try {
18556                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18557                                compatibilityInfoForPackageLocked(appInfo));
18558                    } catch (Exception e) {
18559                        Slog.e(TAG, "Exception when unbinding backup agent:");
18560                        e.printStackTrace();
18561                    }
18562                }
18563            } finally {
18564                mBackupTarget = null;
18565                mBackupAppName = null;
18566            }
18567        }
18568
18569        if (oldBackupUid != -1) {
18570            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18571            js.removeBackingUpUid(oldBackupUid);
18572        }
18573    }
18574
18575    // =========================================================
18576    // BROADCASTS
18577    // =========================================================
18578
18579    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18580        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18581            return false;
18582        }
18583        // Easy case -- we have the app's ProcessRecord.
18584        if (record != null) {
18585            return record.info.isInstantApp();
18586        }
18587        // Otherwise check with PackageManager.
18588        if (callerPackage == null) {
18589            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18590            throw new IllegalArgumentException("Calling application did not provide package name");
18591        }
18592        mAppOpsService.checkPackage(uid, callerPackage);
18593        try {
18594            IPackageManager pm = AppGlobals.getPackageManager();
18595            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18596        } catch (RemoteException e) {
18597            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18598            return true;
18599        }
18600    }
18601
18602    boolean isPendingBroadcastProcessLocked(int pid) {
18603        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18604                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18605    }
18606
18607    void skipPendingBroadcastLocked(int pid) {
18608            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18609            for (BroadcastQueue queue : mBroadcastQueues) {
18610                queue.skipPendingBroadcastLocked(pid);
18611            }
18612    }
18613
18614    // The app just attached; send any pending broadcasts that it should receive
18615    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18616        boolean didSomething = false;
18617        for (BroadcastQueue queue : mBroadcastQueues) {
18618            didSomething |= queue.sendPendingBroadcastsLocked(app);
18619        }
18620        return didSomething;
18621    }
18622
18623    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18624            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18625            int flags) {
18626        enforceNotIsolatedCaller("registerReceiver");
18627        ArrayList<Intent> stickyIntents = null;
18628        ProcessRecord callerApp = null;
18629        final boolean visibleToInstantApps
18630                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18631        int callingUid;
18632        int callingPid;
18633        boolean instantApp;
18634        synchronized(this) {
18635            if (caller != null) {
18636                callerApp = getRecordForAppLocked(caller);
18637                if (callerApp == null) {
18638                    throw new SecurityException(
18639                            "Unable to find app for caller " + caller
18640                            + " (pid=" + Binder.getCallingPid()
18641                            + ") when registering receiver " + receiver);
18642                }
18643                if (callerApp.info.uid != SYSTEM_UID &&
18644                        !callerApp.pkgList.containsKey(callerPackage) &&
18645                        !"android".equals(callerPackage)) {
18646                    throw new SecurityException("Given caller package " + callerPackage
18647                            + " is not running in process " + callerApp);
18648                }
18649                callingUid = callerApp.info.uid;
18650                callingPid = callerApp.pid;
18651            } else {
18652                callerPackage = null;
18653                callingUid = Binder.getCallingUid();
18654                callingPid = Binder.getCallingPid();
18655            }
18656
18657            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18658            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18659                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18660
18661            Iterator<String> actions = filter.actionsIterator();
18662            if (actions == null) {
18663                ArrayList<String> noAction = new ArrayList<String>(1);
18664                noAction.add(null);
18665                actions = noAction.iterator();
18666            }
18667
18668            // Collect stickies of users
18669            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18670            while (actions.hasNext()) {
18671                String action = actions.next();
18672                for (int id : userIds) {
18673                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18674                    if (stickies != null) {
18675                        ArrayList<Intent> intents = stickies.get(action);
18676                        if (intents != null) {
18677                            if (stickyIntents == null) {
18678                                stickyIntents = new ArrayList<Intent>();
18679                            }
18680                            stickyIntents.addAll(intents);
18681                        }
18682                    }
18683                }
18684            }
18685        }
18686
18687        ArrayList<Intent> allSticky = null;
18688        if (stickyIntents != null) {
18689            final ContentResolver resolver = mContext.getContentResolver();
18690            // Look for any matching sticky broadcasts...
18691            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18692                Intent intent = stickyIntents.get(i);
18693                // Don't provided intents that aren't available to instant apps.
18694                if (instantApp &&
18695                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18696                    continue;
18697                }
18698                // If intent has scheme "content", it will need to acccess
18699                // provider that needs to lock mProviderMap in ActivityThread
18700                // and also it may need to wait application response, so we
18701                // cannot lock ActivityManagerService here.
18702                if (filter.match(resolver, intent, true, TAG) >= 0) {
18703                    if (allSticky == null) {
18704                        allSticky = new ArrayList<Intent>();
18705                    }
18706                    allSticky.add(intent);
18707                }
18708            }
18709        }
18710
18711        // The first sticky in the list is returned directly back to the client.
18712        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18713        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18714        if (receiver == null) {
18715            return sticky;
18716        }
18717
18718        synchronized (this) {
18719            if (callerApp != null && (callerApp.thread == null
18720                    || callerApp.thread.asBinder() != caller.asBinder())) {
18721                // Original caller already died
18722                return null;
18723            }
18724            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18725            if (rl == null) {
18726                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18727                        userId, receiver);
18728                if (rl.app != null) {
18729                    rl.app.receivers.add(rl);
18730                } else {
18731                    try {
18732                        receiver.asBinder().linkToDeath(rl, 0);
18733                    } catch (RemoteException e) {
18734                        return sticky;
18735                    }
18736                    rl.linkedToDeath = true;
18737                }
18738                mRegisteredReceivers.put(receiver.asBinder(), rl);
18739            } else if (rl.uid != callingUid) {
18740                throw new IllegalArgumentException(
18741                        "Receiver requested to register for uid " + callingUid
18742                        + " was previously registered for uid " + rl.uid
18743                        + " callerPackage is " + callerPackage);
18744            } else if (rl.pid != callingPid) {
18745                throw new IllegalArgumentException(
18746                        "Receiver requested to register for pid " + callingPid
18747                        + " was previously registered for pid " + rl.pid
18748                        + " callerPackage is " + callerPackage);
18749            } else if (rl.userId != userId) {
18750                throw new IllegalArgumentException(
18751                        "Receiver requested to register for user " + userId
18752                        + " was previously registered for user " + rl.userId
18753                        + " callerPackage is " + callerPackage);
18754            }
18755            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18756                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18757            rl.add(bf);
18758            if (!bf.debugCheck()) {
18759                Slog.w(TAG, "==> For Dynamic broadcast");
18760            }
18761            mReceiverResolver.addFilter(bf);
18762
18763            // Enqueue broadcasts for all existing stickies that match
18764            // this filter.
18765            if (allSticky != null) {
18766                ArrayList receivers = new ArrayList();
18767                receivers.add(bf);
18768
18769                final int stickyCount = allSticky.size();
18770                for (int i = 0; i < stickyCount; i++) {
18771                    Intent intent = allSticky.get(i);
18772                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18773                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18774                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18775                            null, 0, null, null, false, true, true, -1);
18776                    queue.enqueueParallelBroadcastLocked(r);
18777                    queue.scheduleBroadcastsLocked();
18778                }
18779            }
18780
18781            return sticky;
18782        }
18783    }
18784
18785    public void unregisterReceiver(IIntentReceiver receiver) {
18786        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18787
18788        final long origId = Binder.clearCallingIdentity();
18789        try {
18790            boolean doTrim = false;
18791
18792            synchronized(this) {
18793                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18794                if (rl != null) {
18795                    final BroadcastRecord r = rl.curBroadcast;
18796                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18797                        final boolean doNext = r.queue.finishReceiverLocked(
18798                                r, r.resultCode, r.resultData, r.resultExtras,
18799                                r.resultAbort, false);
18800                        if (doNext) {
18801                            doTrim = true;
18802                            r.queue.processNextBroadcast(false);
18803                        }
18804                    }
18805
18806                    if (rl.app != null) {
18807                        rl.app.receivers.remove(rl);
18808                    }
18809                    removeReceiverLocked(rl);
18810                    if (rl.linkedToDeath) {
18811                        rl.linkedToDeath = false;
18812                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18813                    }
18814                }
18815            }
18816
18817            // If we actually concluded any broadcasts, we might now be able
18818            // to trim the recipients' apps from our working set
18819            if (doTrim) {
18820                trimApplications();
18821                return;
18822            }
18823
18824        } finally {
18825            Binder.restoreCallingIdentity(origId);
18826        }
18827    }
18828
18829    void removeReceiverLocked(ReceiverList rl) {
18830        mRegisteredReceivers.remove(rl.receiver.asBinder());
18831        for (int i = rl.size() - 1; i >= 0; i--) {
18832            mReceiverResolver.removeFilter(rl.get(i));
18833        }
18834    }
18835
18836    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18837        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18838            ProcessRecord r = mLruProcesses.get(i);
18839            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18840                try {
18841                    r.thread.dispatchPackageBroadcast(cmd, packages);
18842                } catch (RemoteException ex) {
18843                }
18844            }
18845        }
18846    }
18847
18848    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18849            int callingUid, int[] users) {
18850        // TODO: come back and remove this assumption to triage all broadcasts
18851        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18852
18853        List<ResolveInfo> receivers = null;
18854        try {
18855            HashSet<ComponentName> singleUserReceivers = null;
18856            boolean scannedFirstReceivers = false;
18857            for (int user : users) {
18858                // Skip users that have Shell restrictions, with exception of always permitted
18859                // Shell broadcasts
18860                if (callingUid == SHELL_UID
18861                        && mUserController.hasUserRestriction(
18862                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18863                        && !isPermittedShellBroadcast(intent)) {
18864                    continue;
18865                }
18866                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18867                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18868                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18869                    // If this is not the system user, we need to check for
18870                    // any receivers that should be filtered out.
18871                    for (int i=0; i<newReceivers.size(); i++) {
18872                        ResolveInfo ri = newReceivers.get(i);
18873                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18874                            newReceivers.remove(i);
18875                            i--;
18876                        }
18877                    }
18878                }
18879                if (newReceivers != null && newReceivers.size() == 0) {
18880                    newReceivers = null;
18881                }
18882                if (receivers == null) {
18883                    receivers = newReceivers;
18884                } else if (newReceivers != null) {
18885                    // We need to concatenate the additional receivers
18886                    // found with what we have do far.  This would be easy,
18887                    // but we also need to de-dup any receivers that are
18888                    // singleUser.
18889                    if (!scannedFirstReceivers) {
18890                        // Collect any single user receivers we had already retrieved.
18891                        scannedFirstReceivers = true;
18892                        for (int i=0; i<receivers.size(); i++) {
18893                            ResolveInfo ri = receivers.get(i);
18894                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18895                                ComponentName cn = new ComponentName(
18896                                        ri.activityInfo.packageName, ri.activityInfo.name);
18897                                if (singleUserReceivers == null) {
18898                                    singleUserReceivers = new HashSet<ComponentName>();
18899                                }
18900                                singleUserReceivers.add(cn);
18901                            }
18902                        }
18903                    }
18904                    // Add the new results to the existing results, tracking
18905                    // and de-dupping single user receivers.
18906                    for (int i=0; i<newReceivers.size(); i++) {
18907                        ResolveInfo ri = newReceivers.get(i);
18908                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18909                            ComponentName cn = new ComponentName(
18910                                    ri.activityInfo.packageName, ri.activityInfo.name);
18911                            if (singleUserReceivers == null) {
18912                                singleUserReceivers = new HashSet<ComponentName>();
18913                            }
18914                            if (!singleUserReceivers.contains(cn)) {
18915                                singleUserReceivers.add(cn);
18916                                receivers.add(ri);
18917                            }
18918                        } else {
18919                            receivers.add(ri);
18920                        }
18921                    }
18922                }
18923            }
18924        } catch (RemoteException ex) {
18925            // pm is in same process, this will never happen.
18926        }
18927        return receivers;
18928    }
18929
18930    private boolean isPermittedShellBroadcast(Intent intent) {
18931        // remote bugreport should always be allowed to be taken
18932        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18933    }
18934
18935    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18936            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18937        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18938            // Don't yell about broadcasts sent via shell
18939            return;
18940        }
18941
18942        final String action = intent.getAction();
18943        if (isProtectedBroadcast
18944                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18945                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18946                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18947                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18948                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18949                || Intent.ACTION_MASTER_CLEAR.equals(action)
18950                || Intent.ACTION_FACTORY_RESET.equals(action)
18951                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18952                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18953                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18954                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18955                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18956                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18957                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18958            // Broadcast is either protected, or it's a public action that
18959            // we've relaxed, so it's fine for system internals to send.
18960            return;
18961        }
18962
18963        // This broadcast may be a problem...  but there are often system components that
18964        // want to send an internal broadcast to themselves, which is annoying to have to
18965        // explicitly list each action as a protected broadcast, so we will check for that
18966        // one safe case and allow it: an explicit broadcast, only being received by something
18967        // that has protected itself.
18968        if (receivers != null && receivers.size() > 0
18969                && (intent.getPackage() != null || intent.getComponent() != null)) {
18970            boolean allProtected = true;
18971            for (int i = receivers.size()-1; i >= 0; i--) {
18972                Object target = receivers.get(i);
18973                if (target instanceof ResolveInfo) {
18974                    ResolveInfo ri = (ResolveInfo)target;
18975                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18976                        allProtected = false;
18977                        break;
18978                    }
18979                } else {
18980                    BroadcastFilter bf = (BroadcastFilter)target;
18981                    if (bf.requiredPermission == null) {
18982                        allProtected = false;
18983                        break;
18984                    }
18985                }
18986            }
18987            if (allProtected) {
18988                // All safe!
18989                return;
18990            }
18991        }
18992
18993        // The vast majority of broadcasts sent from system internals
18994        // should be protected to avoid security holes, so yell loudly
18995        // to ensure we examine these cases.
18996        if (callerApp != null) {
18997            Log.wtf(TAG, "Sending non-protected broadcast " + action
18998                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18999                    new Throwable());
19000        } else {
19001            Log.wtf(TAG, "Sending non-protected broadcast " + action
19002                            + " from system uid " + UserHandle.formatUid(callingUid)
19003                            + " pkg " + callerPackage,
19004                    new Throwable());
19005        }
19006    }
19007
19008    final int broadcastIntentLocked(ProcessRecord callerApp,
19009            String callerPackage, Intent intent, String resolvedType,
19010            IIntentReceiver resultTo, int resultCode, String resultData,
19011            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19012            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19013        intent = new Intent(intent);
19014
19015        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19016        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19017        if (callerInstantApp) {
19018            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19019        }
19020
19021        // By default broadcasts do not go to stopped apps.
19022        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19023
19024        // If we have not finished booting, don't allow this to launch new processes.
19025        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19026            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19027        }
19028
19029        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19030                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19031                + " ordered=" + ordered + " userid=" + userId);
19032        if ((resultTo != null) && !ordered) {
19033            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19034        }
19035
19036        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19037                ALLOW_NON_FULL, "broadcast", callerPackage);
19038
19039        // Make sure that the user who is receiving this broadcast is running.
19040        // If not, we will just skip it. Make an exception for shutdown broadcasts
19041        // and upgrade steps.
19042
19043        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19044            if ((callingUid != SYSTEM_UID
19045                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19046                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19047                Slog.w(TAG, "Skipping broadcast of " + intent
19048                        + ": user " + userId + " is stopped");
19049                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19050            }
19051        }
19052
19053        BroadcastOptions brOptions = null;
19054        if (bOptions != null) {
19055            brOptions = new BroadcastOptions(bOptions);
19056            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19057                // See if the caller is allowed to do this.  Note we are checking against
19058                // the actual real caller (not whoever provided the operation as say a
19059                // PendingIntent), because that who is actually supplied the arguments.
19060                if (checkComponentPermission(
19061                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19062                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19063                        != PackageManager.PERMISSION_GRANTED) {
19064                    String msg = "Permission Denial: " + intent.getAction()
19065                            + " broadcast from " + callerPackage + " (pid=" + callingPid
19066                            + ", uid=" + callingUid + ")"
19067                            + " requires "
19068                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19069                    Slog.w(TAG, msg);
19070                    throw new SecurityException(msg);
19071                }
19072            }
19073        }
19074
19075        // Verify that protected broadcasts are only being sent by system code,
19076        // and that system code is only sending protected broadcasts.
19077        final String action = intent.getAction();
19078        final boolean isProtectedBroadcast;
19079        try {
19080            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19081        } catch (RemoteException e) {
19082            Slog.w(TAG, "Remote exception", e);
19083            return ActivityManager.BROADCAST_SUCCESS;
19084        }
19085
19086        final boolean isCallerSystem;
19087        switch (UserHandle.getAppId(callingUid)) {
19088            case ROOT_UID:
19089            case SYSTEM_UID:
19090            case PHONE_UID:
19091            case BLUETOOTH_UID:
19092            case NFC_UID:
19093                isCallerSystem = true;
19094                break;
19095            default:
19096                isCallerSystem = (callerApp != null) && callerApp.persistent;
19097                break;
19098        }
19099
19100        // First line security check before anything else: stop non-system apps from
19101        // sending protected broadcasts.
19102        if (!isCallerSystem) {
19103            if (isProtectedBroadcast) {
19104                String msg = "Permission Denial: not allowed to send broadcast "
19105                        + action + " from pid="
19106                        + callingPid + ", uid=" + callingUid;
19107                Slog.w(TAG, msg);
19108                throw new SecurityException(msg);
19109
19110            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19111                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19112                // Special case for compatibility: we don't want apps to send this,
19113                // but historically it has not been protected and apps may be using it
19114                // to poke their own app widget.  So, instead of making it protected,
19115                // just limit it to the caller.
19116                if (callerPackage == null) {
19117                    String msg = "Permission Denial: not allowed to send broadcast "
19118                            + action + " from unknown caller.";
19119                    Slog.w(TAG, msg);
19120                    throw new SecurityException(msg);
19121                } else if (intent.getComponent() != null) {
19122                    // They are good enough to send to an explicit component...  verify
19123                    // it is being sent to the calling app.
19124                    if (!intent.getComponent().getPackageName().equals(
19125                            callerPackage)) {
19126                        String msg = "Permission Denial: not allowed to send broadcast "
19127                                + action + " to "
19128                                + intent.getComponent().getPackageName() + " from "
19129                                + callerPackage;
19130                        Slog.w(TAG, msg);
19131                        throw new SecurityException(msg);
19132                    }
19133                } else {
19134                    // Limit broadcast to their own package.
19135                    intent.setPackage(callerPackage);
19136                }
19137            }
19138        }
19139
19140        if (action != null) {
19141            if (getBackgroundLaunchBroadcasts().contains(action)) {
19142                if (DEBUG_BACKGROUND_CHECK) {
19143                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19144                }
19145                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19146            }
19147
19148            switch (action) {
19149                case Intent.ACTION_UID_REMOVED:
19150                case Intent.ACTION_PACKAGE_REMOVED:
19151                case Intent.ACTION_PACKAGE_CHANGED:
19152                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19153                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19154                case Intent.ACTION_PACKAGES_SUSPENDED:
19155                case Intent.ACTION_PACKAGES_UNSUSPENDED:
19156                    // Handle special intents: if this broadcast is from the package
19157                    // manager about a package being removed, we need to remove all of
19158                    // its activities from the history stack.
19159                    if (checkComponentPermission(
19160                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19161                            callingPid, callingUid, -1, true)
19162                            != PackageManager.PERMISSION_GRANTED) {
19163                        String msg = "Permission Denial: " + intent.getAction()
19164                                + " broadcast from " + callerPackage + " (pid=" + callingPid
19165                                + ", uid=" + callingUid + ")"
19166                                + " requires "
19167                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19168                        Slog.w(TAG, msg);
19169                        throw new SecurityException(msg);
19170                    }
19171                    switch (action) {
19172                        case Intent.ACTION_UID_REMOVED:
19173                            final int uid = getUidFromIntent(intent);
19174                            if (uid >= 0) {
19175                                mBatteryStatsService.removeUid(uid);
19176                                mAppOpsService.uidRemoved(uid);
19177                            }
19178                            break;
19179                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19180                            // If resources are unavailable just force stop all those packages
19181                            // and flush the attribute cache as well.
19182                            String list[] =
19183                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19184                            if (list != null && list.length > 0) {
19185                                for (int i = 0; i < list.length; i++) {
19186                                    forceStopPackageLocked(list[i], -1, false, true, true,
19187                                            false, false, userId, "storage unmount");
19188                                }
19189                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19190                                sendPackageBroadcastLocked(
19191                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19192                                        list, userId);
19193                            }
19194                            break;
19195                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19196                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19197                            break;
19198                        case Intent.ACTION_PACKAGE_REMOVED:
19199                        case Intent.ACTION_PACKAGE_CHANGED:
19200                            Uri data = intent.getData();
19201                            String ssp;
19202                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19203                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19204                                final boolean replacing =
19205                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19206                                final boolean killProcess =
19207                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19208                                final boolean fullUninstall = removed && !replacing;
19209                                if (removed) {
19210                                    if (killProcess) {
19211                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
19212                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19213                                                false, true, true, false, fullUninstall, userId,
19214                                                removed ? "pkg removed" : "pkg changed");
19215                                    }
19216                                    final int cmd = killProcess
19217                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
19218                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19219                                    sendPackageBroadcastLocked(cmd,
19220                                            new String[] {ssp}, userId);
19221                                    if (fullUninstall) {
19222                                        mAppOpsService.packageRemoved(
19223                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19224
19225                                        // Remove all permissions granted from/to this package
19226                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
19227
19228                                        removeTasksByPackageNameLocked(ssp, userId);
19229
19230                                        mServices.forceStopPackageLocked(ssp, userId);
19231
19232                                        // Hide the "unsupported display" dialog if necessary.
19233                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19234                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19235                                            mUnsupportedDisplaySizeDialog.dismiss();
19236                                            mUnsupportedDisplaySizeDialog = null;
19237                                        }
19238                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
19239                                        mBatteryStatsService.notePackageUninstalled(ssp);
19240                                    }
19241                                } else {
19242                                    if (killProcess) {
19243                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
19244                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19245                                                userId, ProcessList.INVALID_ADJ,
19246                                                false, true, true, false, "change " + ssp);
19247                                    }
19248                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19249                                            intent.getStringArrayExtra(
19250                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19251                                }
19252                            }
19253                            break;
19254                        case Intent.ACTION_PACKAGES_SUSPENDED:
19255                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
19256                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19257                                    intent.getAction());
19258                            final String[] packageNames = intent.getStringArrayExtra(
19259                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
19260                            final int userHandle = intent.getIntExtra(
19261                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19262
19263                            synchronized(ActivityManagerService.this) {
19264                                mRecentTasks.onPackagesSuspendedChanged(
19265                                        packageNames, suspended, userHandle);
19266                            }
19267                            break;
19268                    }
19269                    break;
19270                case Intent.ACTION_PACKAGE_REPLACED:
19271                {
19272                    final Uri data = intent.getData();
19273                    final String ssp;
19274                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19275                        ApplicationInfo aInfo = null;
19276                        try {
19277                            aInfo = AppGlobals.getPackageManager()
19278                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
19279                        } catch (RemoteException ignore) {}
19280                        if (aInfo == null) {
19281                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19282                                    + " ssp=" + ssp + " data=" + data);
19283                            return ActivityManager.BROADCAST_SUCCESS;
19284                        }
19285                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19286                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19287                                new String[] {ssp}, userId);
19288                    }
19289                    break;
19290                }
19291                case Intent.ACTION_PACKAGE_ADDED:
19292                {
19293                    // Special case for adding a package: by default turn on compatibility mode.
19294                    Uri data = intent.getData();
19295                    String ssp;
19296                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19297                        final boolean replacing =
19298                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19299                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19300
19301                        try {
19302                            ApplicationInfo ai = AppGlobals.getPackageManager().
19303                                    getApplicationInfo(ssp, 0, 0);
19304                            mBatteryStatsService.notePackageInstalled(ssp,
19305                                    ai != null ? ai.versionCode : 0);
19306                        } catch (RemoteException e) {
19307                        }
19308                    }
19309                    break;
19310                }
19311                case Intent.ACTION_PACKAGE_DATA_CLEARED:
19312                {
19313                    Uri data = intent.getData();
19314                    String ssp;
19315                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19316                        // Hide the "unsupported display" dialog if necessary.
19317                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19318                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19319                            mUnsupportedDisplaySizeDialog.dismiss();
19320                            mUnsupportedDisplaySizeDialog = null;
19321                        }
19322                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
19323                    }
19324                    break;
19325                }
19326                case Intent.ACTION_TIMEZONE_CHANGED:
19327                    // If this is the time zone changed action, queue up a message that will reset
19328                    // the timezone of all currently running processes. This message will get
19329                    // queued up before the broadcast happens.
19330                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19331                    break;
19332                case Intent.ACTION_TIME_CHANGED:
19333                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19334                    // the tri-state value it may contain and "unknown".
19335                    // For convenience we re-use the Intent extra values.
19336                    final int NO_EXTRA_VALUE_FOUND = -1;
19337                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19338                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19339                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
19340                    // Only send a message if the time preference is available.
19341                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19342                        Message updateTimePreferenceMsg =
19343                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19344                                        timeFormatPreferenceMsgValue, 0);
19345                        mHandler.sendMessage(updateTimePreferenceMsg);
19346                    }
19347                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19348                    synchronized (stats) {
19349                        stats.noteCurrentTimeChangedLocked();
19350                    }
19351                    break;
19352                case Intent.ACTION_CLEAR_DNS_CACHE:
19353                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19354                    break;
19355                case Proxy.PROXY_CHANGE_ACTION:
19356                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19357                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19358                    break;
19359                case android.hardware.Camera.ACTION_NEW_PICTURE:
19360                case android.hardware.Camera.ACTION_NEW_VIDEO:
19361                    // In N we just turned these off; in O we are turing them back on partly,
19362                    // only for registered receivers.  This will still address the main problem
19363                    // (a spam of apps waking up when a picture is taken putting significant
19364                    // memory pressure on the system at a bad point), while still allowing apps
19365                    // that are already actively running to know about this happening.
19366                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19367                    break;
19368                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19369                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19370                    break;
19371                case "com.android.launcher.action.INSTALL_SHORTCUT":
19372                    // As of O, we no longer support this broadcasts, even for pre-O apps.
19373                    // Apps should now be using ShortcutManager.pinRequestShortcut().
19374                    Log.w(TAG, "Broadcast " + action
19375                            + " no longer supported. It will not be delivered.");
19376                    return ActivityManager.BROADCAST_SUCCESS;
19377            }
19378
19379            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19380                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19381                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19382                final int uid = getUidFromIntent(intent);
19383                if (uid != -1) {
19384                    final UidRecord uidRec = mActiveUids.get(uid);
19385                    if (uidRec != null) {
19386                        uidRec.updateHasInternetPermission();
19387                    }
19388                }
19389            }
19390        }
19391
19392        // Add to the sticky list if requested.
19393        if (sticky) {
19394            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19395                    callingPid, callingUid)
19396                    != PackageManager.PERMISSION_GRANTED) {
19397                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19398                        + callingPid + ", uid=" + callingUid
19399                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19400                Slog.w(TAG, msg);
19401                throw new SecurityException(msg);
19402            }
19403            if (requiredPermissions != null && requiredPermissions.length > 0) {
19404                Slog.w(TAG, "Can't broadcast sticky intent " + intent
19405                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19406                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19407            }
19408            if (intent.getComponent() != null) {
19409                throw new SecurityException(
19410                        "Sticky broadcasts can't target a specific component");
19411            }
19412            // We use userId directly here, since the "all" target is maintained
19413            // as a separate set of sticky broadcasts.
19414            if (userId != UserHandle.USER_ALL) {
19415                // But first, if this is not a broadcast to all users, then
19416                // make sure it doesn't conflict with an existing broadcast to
19417                // all users.
19418                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19419                        UserHandle.USER_ALL);
19420                if (stickies != null) {
19421                    ArrayList<Intent> list = stickies.get(intent.getAction());
19422                    if (list != null) {
19423                        int N = list.size();
19424                        int i;
19425                        for (i=0; i<N; i++) {
19426                            if (intent.filterEquals(list.get(i))) {
19427                                throw new IllegalArgumentException(
19428                                        "Sticky broadcast " + intent + " for user "
19429                                        + userId + " conflicts with existing global broadcast");
19430                            }
19431                        }
19432                    }
19433                }
19434            }
19435            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19436            if (stickies == null) {
19437                stickies = new ArrayMap<>();
19438                mStickyBroadcasts.put(userId, stickies);
19439            }
19440            ArrayList<Intent> list = stickies.get(intent.getAction());
19441            if (list == null) {
19442                list = new ArrayList<>();
19443                stickies.put(intent.getAction(), list);
19444            }
19445            final int stickiesCount = list.size();
19446            int i;
19447            for (i = 0; i < stickiesCount; i++) {
19448                if (intent.filterEquals(list.get(i))) {
19449                    // This sticky already exists, replace it.
19450                    list.set(i, new Intent(intent));
19451                    break;
19452                }
19453            }
19454            if (i >= stickiesCount) {
19455                list.add(new Intent(intent));
19456            }
19457        }
19458
19459        int[] users;
19460        if (userId == UserHandle.USER_ALL) {
19461            // Caller wants broadcast to go to all started users.
19462            users = mUserController.getStartedUserArrayLocked();
19463        } else {
19464            // Caller wants broadcast to go to one specific user.
19465            users = new int[] {userId};
19466        }
19467
19468        // Figure out who all will receive this broadcast.
19469        List receivers = null;
19470        List<BroadcastFilter> registeredReceivers = null;
19471        // Need to resolve the intent to interested receivers...
19472        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19473                 == 0) {
19474            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19475        }
19476        if (intent.getComponent() == null) {
19477            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19478                // Query one target user at a time, excluding shell-restricted users
19479                for (int i = 0; i < users.length; i++) {
19480                    if (mUserController.hasUserRestriction(
19481                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19482                        continue;
19483                    }
19484                    List<BroadcastFilter> registeredReceiversForUser =
19485                            mReceiverResolver.queryIntent(intent,
19486                                    resolvedType, false /*defaultOnly*/, users[i]);
19487                    if (registeredReceivers == null) {
19488                        registeredReceivers = registeredReceiversForUser;
19489                    } else if (registeredReceiversForUser != null) {
19490                        registeredReceivers.addAll(registeredReceiversForUser);
19491                    }
19492                }
19493            } else {
19494                registeredReceivers = mReceiverResolver.queryIntent(intent,
19495                        resolvedType, false /*defaultOnly*/, userId);
19496            }
19497        }
19498
19499        final boolean replacePending =
19500                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19501
19502        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19503                + " replacePending=" + replacePending);
19504
19505        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19506        if (!ordered && NR > 0) {
19507            // If we are not serializing this broadcast, then send the
19508            // registered receivers separately so they don't wait for the
19509            // components to be launched.
19510            if (isCallerSystem) {
19511                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19512                        isProtectedBroadcast, registeredReceivers);
19513            }
19514            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19515            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19516                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19517                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19518                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19519            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19520            final boolean replaced = replacePending
19521                    && (queue.replaceParallelBroadcastLocked(r) != null);
19522            // Note: We assume resultTo is null for non-ordered broadcasts.
19523            if (!replaced) {
19524                queue.enqueueParallelBroadcastLocked(r);
19525                queue.scheduleBroadcastsLocked();
19526            }
19527            registeredReceivers = null;
19528            NR = 0;
19529        }
19530
19531        // Merge into one list.
19532        int ir = 0;
19533        if (receivers != null) {
19534            // A special case for PACKAGE_ADDED: do not allow the package
19535            // being added to see this broadcast.  This prevents them from
19536            // using this as a back door to get run as soon as they are
19537            // installed.  Maybe in the future we want to have a special install
19538            // broadcast or such for apps, but we'd like to deliberately make
19539            // this decision.
19540            String skipPackages[] = null;
19541            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19542                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19543                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19544                Uri data = intent.getData();
19545                if (data != null) {
19546                    String pkgName = data.getSchemeSpecificPart();
19547                    if (pkgName != null) {
19548                        skipPackages = new String[] { pkgName };
19549                    }
19550                }
19551            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19552                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19553            }
19554            if (skipPackages != null && (skipPackages.length > 0)) {
19555                for (String skipPackage : skipPackages) {
19556                    if (skipPackage != null) {
19557                        int NT = receivers.size();
19558                        for (int it=0; it<NT; it++) {
19559                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19560                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19561                                receivers.remove(it);
19562                                it--;
19563                                NT--;
19564                            }
19565                        }
19566                    }
19567                }
19568            }
19569
19570            int NT = receivers != null ? receivers.size() : 0;
19571            int it = 0;
19572            ResolveInfo curt = null;
19573            BroadcastFilter curr = null;
19574            while (it < NT && ir < NR) {
19575                if (curt == null) {
19576                    curt = (ResolveInfo)receivers.get(it);
19577                }
19578                if (curr == null) {
19579                    curr = registeredReceivers.get(ir);
19580                }
19581                if (curr.getPriority() >= curt.priority) {
19582                    // Insert this broadcast record into the final list.
19583                    receivers.add(it, curr);
19584                    ir++;
19585                    curr = null;
19586                    it++;
19587                    NT++;
19588                } else {
19589                    // Skip to the next ResolveInfo in the final list.
19590                    it++;
19591                    curt = null;
19592                }
19593            }
19594        }
19595        while (ir < NR) {
19596            if (receivers == null) {
19597                receivers = new ArrayList();
19598            }
19599            receivers.add(registeredReceivers.get(ir));
19600            ir++;
19601        }
19602
19603        if (isCallerSystem) {
19604            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19605                    isProtectedBroadcast, receivers);
19606        }
19607
19608        if ((receivers != null && receivers.size() > 0)
19609                || resultTo != null) {
19610            BroadcastQueue queue = broadcastQueueForIntent(intent);
19611            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19612                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19613                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19614                    resultData, resultExtras, ordered, sticky, false, userId);
19615
19616            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19617                    + ": prev had " + queue.mOrderedBroadcasts.size());
19618            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19619                    "Enqueueing broadcast " + r.intent.getAction());
19620
19621            final BroadcastRecord oldRecord =
19622                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19623            if (oldRecord != null) {
19624                // Replaced, fire the result-to receiver.
19625                if (oldRecord.resultTo != null) {
19626                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19627                    try {
19628                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19629                                oldRecord.intent,
19630                                Activity.RESULT_CANCELED, null, null,
19631                                false, false, oldRecord.userId);
19632                    } catch (RemoteException e) {
19633                        Slog.w(TAG, "Failure ["
19634                                + queue.mQueueName + "] sending broadcast result of "
19635                                + intent, e);
19636
19637                    }
19638                }
19639            } else {
19640                queue.enqueueOrderedBroadcastLocked(r);
19641                queue.scheduleBroadcastsLocked();
19642            }
19643        } else {
19644            // There was nobody interested in the broadcast, but we still want to record
19645            // that it happened.
19646            if (intent.getComponent() == null && intent.getPackage() == null
19647                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19648                // This was an implicit broadcast... let's record it for posterity.
19649                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19650            }
19651        }
19652
19653        return ActivityManager.BROADCAST_SUCCESS;
19654    }
19655
19656    /**
19657     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19658     */
19659    private int getUidFromIntent(Intent intent) {
19660        if (intent == null) {
19661            return -1;
19662        }
19663        final Bundle intentExtras = intent.getExtras();
19664        return intent.hasExtra(Intent.EXTRA_UID)
19665                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19666    }
19667
19668    final void rotateBroadcastStatsIfNeededLocked() {
19669        final long now = SystemClock.elapsedRealtime();
19670        if (mCurBroadcastStats == null ||
19671                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19672            mLastBroadcastStats = mCurBroadcastStats;
19673            if (mLastBroadcastStats != null) {
19674                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19675                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19676            }
19677            mCurBroadcastStats = new BroadcastStats();
19678        }
19679    }
19680
19681    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19682            int skipCount, long dispatchTime) {
19683        rotateBroadcastStatsIfNeededLocked();
19684        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19685    }
19686
19687    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19688        rotateBroadcastStatsIfNeededLocked();
19689        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19690    }
19691
19692    final Intent verifyBroadcastLocked(Intent intent) {
19693        // Refuse possible leaked file descriptors
19694        if (intent != null && intent.hasFileDescriptors() == true) {
19695            throw new IllegalArgumentException("File descriptors passed in Intent");
19696        }
19697
19698        int flags = intent.getFlags();
19699
19700        if (!mProcessesReady) {
19701            // if the caller really truly claims to know what they're doing, go
19702            // ahead and allow the broadcast without launching any receivers
19703            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19704                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19705            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19706                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19707                        + " before boot completion");
19708                throw new IllegalStateException("Cannot broadcast before boot completed");
19709            }
19710        }
19711
19712        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19713            throw new IllegalArgumentException(
19714                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19715        }
19716
19717        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19718            switch (Binder.getCallingUid()) {
19719                case ROOT_UID:
19720                case SHELL_UID:
19721                    break;
19722                default:
19723                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19724                            + Binder.getCallingUid());
19725                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19726                    break;
19727            }
19728        }
19729
19730        return intent;
19731    }
19732
19733    public final int broadcastIntent(IApplicationThread caller,
19734            Intent intent, String resolvedType, IIntentReceiver resultTo,
19735            int resultCode, String resultData, Bundle resultExtras,
19736            String[] requiredPermissions, int appOp, Bundle bOptions,
19737            boolean serialized, boolean sticky, int userId) {
19738        enforceNotIsolatedCaller("broadcastIntent");
19739        synchronized(this) {
19740            intent = verifyBroadcastLocked(intent);
19741
19742            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19743            final int callingPid = Binder.getCallingPid();
19744            final int callingUid = Binder.getCallingUid();
19745            final long origId = Binder.clearCallingIdentity();
19746            int res = broadcastIntentLocked(callerApp,
19747                    callerApp != null ? callerApp.info.packageName : null,
19748                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19749                    requiredPermissions, appOp, bOptions, serialized, sticky,
19750                    callingPid, callingUid, userId);
19751            Binder.restoreCallingIdentity(origId);
19752            return res;
19753        }
19754    }
19755
19756
19757    int broadcastIntentInPackage(String packageName, int uid,
19758            Intent intent, String resolvedType, IIntentReceiver resultTo,
19759            int resultCode, String resultData, Bundle resultExtras,
19760            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19761            int userId) {
19762        synchronized(this) {
19763            intent = verifyBroadcastLocked(intent);
19764
19765            final long origId = Binder.clearCallingIdentity();
19766            String[] requiredPermissions = requiredPermission == null ? null
19767                    : new String[] {requiredPermission};
19768            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19769                    resultTo, resultCode, resultData, resultExtras,
19770                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19771                    sticky, -1, uid, userId);
19772            Binder.restoreCallingIdentity(origId);
19773            return res;
19774        }
19775    }
19776
19777    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19778        // Refuse possible leaked file descriptors
19779        if (intent != null && intent.hasFileDescriptors() == true) {
19780            throw new IllegalArgumentException("File descriptors passed in Intent");
19781        }
19782
19783        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19784                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19785
19786        synchronized(this) {
19787            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19788                    != PackageManager.PERMISSION_GRANTED) {
19789                String msg = "Permission Denial: unbroadcastIntent() from pid="
19790                        + Binder.getCallingPid()
19791                        + ", uid=" + Binder.getCallingUid()
19792                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19793                Slog.w(TAG, msg);
19794                throw new SecurityException(msg);
19795            }
19796            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19797            if (stickies != null) {
19798                ArrayList<Intent> list = stickies.get(intent.getAction());
19799                if (list != null) {
19800                    int N = list.size();
19801                    int i;
19802                    for (i=0; i<N; i++) {
19803                        if (intent.filterEquals(list.get(i))) {
19804                            list.remove(i);
19805                            break;
19806                        }
19807                    }
19808                    if (list.size() <= 0) {
19809                        stickies.remove(intent.getAction());
19810                    }
19811                }
19812                if (stickies.size() <= 0) {
19813                    mStickyBroadcasts.remove(userId);
19814                }
19815            }
19816        }
19817    }
19818
19819    void backgroundServicesFinishedLocked(int userId) {
19820        for (BroadcastQueue queue : mBroadcastQueues) {
19821            queue.backgroundServicesFinishedLocked(userId);
19822        }
19823    }
19824
19825    public void finishReceiver(IBinder who, int resultCode, String resultData,
19826            Bundle resultExtras, boolean resultAbort, int flags) {
19827        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19828
19829        // Refuse possible leaked file descriptors
19830        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19831            throw new IllegalArgumentException("File descriptors passed in Bundle");
19832        }
19833
19834        final long origId = Binder.clearCallingIdentity();
19835        try {
19836            boolean doNext = false;
19837            BroadcastRecord r;
19838
19839            synchronized(this) {
19840                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19841                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19842                r = queue.getMatchingOrderedReceiver(who);
19843                if (r != null) {
19844                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19845                        resultData, resultExtras, resultAbort, true);
19846                }
19847            }
19848
19849            if (doNext) {
19850                r.queue.processNextBroadcast(false);
19851            }
19852            trimApplications();
19853        } finally {
19854            Binder.restoreCallingIdentity(origId);
19855        }
19856    }
19857
19858    // =========================================================
19859    // INSTRUMENTATION
19860    // =========================================================
19861
19862    public boolean startInstrumentation(ComponentName className,
19863            String profileFile, int flags, Bundle arguments,
19864            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19865            int userId, String abiOverride) {
19866        enforceNotIsolatedCaller("startInstrumentation");
19867        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19868                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19869        // Refuse possible leaked file descriptors
19870        if (arguments != null && arguments.hasFileDescriptors()) {
19871            throw new IllegalArgumentException("File descriptors passed in Bundle");
19872        }
19873
19874        synchronized(this) {
19875            InstrumentationInfo ii = null;
19876            ApplicationInfo ai = null;
19877            try {
19878                ii = mContext.getPackageManager().getInstrumentationInfo(
19879                    className, STOCK_PM_FLAGS);
19880                ai = AppGlobals.getPackageManager().getApplicationInfo(
19881                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19882            } catch (PackageManager.NameNotFoundException e) {
19883            } catch (RemoteException e) {
19884            }
19885            if (ii == null) {
19886                reportStartInstrumentationFailureLocked(watcher, className,
19887                        "Unable to find instrumentation info for: " + className);
19888                return false;
19889            }
19890            if (ai == null) {
19891                reportStartInstrumentationFailureLocked(watcher, className,
19892                        "Unable to find instrumentation target package: " + ii.targetPackage);
19893                return false;
19894            }
19895            if (!ai.hasCode()) {
19896                reportStartInstrumentationFailureLocked(watcher, className,
19897                        "Instrumentation target has no code: " + ii.targetPackage);
19898                return false;
19899            }
19900
19901            int match = mContext.getPackageManager().checkSignatures(
19902                    ii.targetPackage, ii.packageName);
19903            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19904                String msg = "Permission Denial: starting instrumentation "
19905                        + className + " from pid="
19906                        + Binder.getCallingPid()
19907                        + ", uid=" + Binder.getCallingPid()
19908                        + " not allowed because package " + ii.packageName
19909                        + " does not have a signature matching the target "
19910                        + ii.targetPackage;
19911                reportStartInstrumentationFailureLocked(watcher, className, msg);
19912                throw new SecurityException(msg);
19913            }
19914
19915            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19916            activeInstr.mClass = className;
19917            String defProcess = ai.processName;;
19918            if (ii.targetProcesses == null) {
19919                activeInstr.mTargetProcesses = new String[]{ai.processName};
19920            } else if (ii.targetProcesses.equals("*")) {
19921                activeInstr.mTargetProcesses = new String[0];
19922            } else {
19923                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19924                defProcess = activeInstr.mTargetProcesses[0];
19925            }
19926            activeInstr.mTargetInfo = ai;
19927            activeInstr.mProfileFile = profileFile;
19928            activeInstr.mArguments = arguments;
19929            activeInstr.mWatcher = watcher;
19930            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19931            activeInstr.mResultClass = className;
19932
19933            final long origId = Binder.clearCallingIdentity();
19934            // Instrumentation can kill and relaunch even persistent processes
19935            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19936                    "start instr");
19937            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19938            app.instr = activeInstr;
19939            activeInstr.mFinished = false;
19940            activeInstr.mRunningProcesses.add(app);
19941            if (!mActiveInstrumentation.contains(activeInstr)) {
19942                mActiveInstrumentation.add(activeInstr);
19943            }
19944            Binder.restoreCallingIdentity(origId);
19945        }
19946
19947        return true;
19948    }
19949
19950    /**
19951     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19952     * error to the logs, but if somebody is watching, send the report there too.  This enables
19953     * the "am" command to report errors with more information.
19954     *
19955     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19956     * @param cn The component name of the instrumentation.
19957     * @param report The error report.
19958     */
19959    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19960            ComponentName cn, String report) {
19961        Slog.w(TAG, report);
19962        if (watcher != null) {
19963            Bundle results = new Bundle();
19964            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19965            results.putString("Error", report);
19966            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19967        }
19968    }
19969
19970    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19971        if (app.instr == null) {
19972            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19973            return;
19974        }
19975
19976        if (!app.instr.mFinished && results != null) {
19977            if (app.instr.mCurResults == null) {
19978                app.instr.mCurResults = new Bundle(results);
19979            } else {
19980                app.instr.mCurResults.putAll(results);
19981            }
19982        }
19983    }
19984
19985    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19986        int userId = UserHandle.getCallingUserId();
19987        // Refuse possible leaked file descriptors
19988        if (results != null && results.hasFileDescriptors()) {
19989            throw new IllegalArgumentException("File descriptors passed in Intent");
19990        }
19991
19992        synchronized(this) {
19993            ProcessRecord app = getRecordForAppLocked(target);
19994            if (app == null) {
19995                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19996                return;
19997            }
19998            final long origId = Binder.clearCallingIdentity();
19999            addInstrumentationResultsLocked(app, results);
20000            Binder.restoreCallingIdentity(origId);
20001        }
20002    }
20003
20004    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20005        if (app.instr == null) {
20006            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20007            return;
20008        }
20009
20010        if (!app.instr.mFinished) {
20011            if (app.instr.mWatcher != null) {
20012                Bundle finalResults = app.instr.mCurResults;
20013                if (finalResults != null) {
20014                    if (app.instr.mCurResults != null && results != null) {
20015                        finalResults.putAll(results);
20016                    }
20017                } else {
20018                    finalResults = results;
20019                }
20020                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20021                        app.instr.mClass, resultCode, finalResults);
20022            }
20023
20024            // Can't call out of the system process with a lock held, so post a message.
20025            if (app.instr.mUiAutomationConnection != null) {
20026                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20027                        app.instr.mUiAutomationConnection).sendToTarget();
20028            }
20029            app.instr.mFinished = true;
20030        }
20031
20032        app.instr.removeProcess(app);
20033        app.instr = null;
20034
20035        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20036                "finished inst");
20037    }
20038
20039    public void finishInstrumentation(IApplicationThread target,
20040            int resultCode, Bundle results) {
20041        int userId = UserHandle.getCallingUserId();
20042        // Refuse possible leaked file descriptors
20043        if (results != null && results.hasFileDescriptors()) {
20044            throw new IllegalArgumentException("File descriptors passed in Intent");
20045        }
20046
20047        synchronized(this) {
20048            ProcessRecord app = getRecordForAppLocked(target);
20049            if (app == null) {
20050                Slog.w(TAG, "finishInstrumentation: no app for " + target);
20051                return;
20052            }
20053            final long origId = Binder.clearCallingIdentity();
20054            finishInstrumentationLocked(app, resultCode, results);
20055            Binder.restoreCallingIdentity(origId);
20056        }
20057    }
20058
20059    // =========================================================
20060    // CONFIGURATION
20061    // =========================================================
20062
20063    public ConfigurationInfo getDeviceConfigurationInfo() {
20064        ConfigurationInfo config = new ConfigurationInfo();
20065        synchronized (this) {
20066            final Configuration globalConfig = getGlobalConfiguration();
20067            config.reqTouchScreen = globalConfig.touchscreen;
20068            config.reqKeyboardType = globalConfig.keyboard;
20069            config.reqNavigation = globalConfig.navigation;
20070            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20071                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20072                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20073            }
20074            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20075                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20076                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20077            }
20078            config.reqGlEsVersion = GL_ES_VERSION;
20079        }
20080        return config;
20081    }
20082
20083    ActivityStack getFocusedStack() {
20084        return mStackSupervisor.getFocusedStack();
20085    }
20086
20087    @Override
20088    public int getFocusedStackId() throws RemoteException {
20089        ActivityStack focusedStack = getFocusedStack();
20090        if (focusedStack != null) {
20091            return focusedStack.getStackId();
20092        }
20093        return -1;
20094    }
20095
20096    public Configuration getConfiguration() {
20097        Configuration ci;
20098        synchronized(this) {
20099            ci = new Configuration(getGlobalConfiguration());
20100            ci.userSetLocale = false;
20101        }
20102        return ci;
20103    }
20104
20105    @Override
20106    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20107        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20108        synchronized (this) {
20109            mSuppressResizeConfigChanges = suppress;
20110        }
20111    }
20112
20113    /**
20114     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20115     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20116     *       activity and clearing the task at the same time.
20117     */
20118    @Override
20119    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20120        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20121        if (StackId.isHomeOrRecentsStack(fromStackId)) {
20122            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20123        }
20124        synchronized (this) {
20125            final long origId = Binder.clearCallingIdentity();
20126            try {
20127                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20128            } finally {
20129                Binder.restoreCallingIdentity(origId);
20130            }
20131        }
20132    }
20133
20134    @Override
20135    public void updatePersistentConfiguration(Configuration values) {
20136        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20137        enforceWriteSettingsPermission("updatePersistentConfiguration()");
20138        if (values == null) {
20139            throw new NullPointerException("Configuration must not be null");
20140        }
20141
20142        int userId = UserHandle.getCallingUserId();
20143
20144        synchronized(this) {
20145            updatePersistentConfigurationLocked(values, userId);
20146        }
20147    }
20148
20149    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20150        final long origId = Binder.clearCallingIdentity();
20151        try {
20152            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20153        } finally {
20154            Binder.restoreCallingIdentity(origId);
20155        }
20156    }
20157
20158    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20159        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20160                FONT_SCALE, 1.0f, userId);
20161
20162        synchronized (this) {
20163            if (getGlobalConfiguration().fontScale == scaleFactor) {
20164                return;
20165            }
20166
20167            final Configuration configuration
20168                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20169            configuration.fontScale = scaleFactor;
20170            updatePersistentConfigurationLocked(configuration, userId);
20171        }
20172    }
20173
20174    private void enforceWriteSettingsPermission(String func) {
20175        int uid = Binder.getCallingUid();
20176        if (uid == ROOT_UID) {
20177            return;
20178        }
20179
20180        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20181                Settings.getPackageNameForUid(mContext, uid), false)) {
20182            return;
20183        }
20184
20185        String msg = "Permission Denial: " + func + " from pid="
20186                + Binder.getCallingPid()
20187                + ", uid=" + uid
20188                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20189        Slog.w(TAG, msg);
20190        throw new SecurityException(msg);
20191    }
20192
20193    @Override
20194    public boolean updateConfiguration(Configuration values) {
20195        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20196
20197        synchronized(this) {
20198            if (values == null && mWindowManager != null) {
20199                // sentinel: fetch the current configuration from the window manager
20200                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20201            }
20202
20203            if (mWindowManager != null) {
20204                // Update OOM levels based on display size.
20205                mProcessList.applyDisplaySize(mWindowManager);
20206            }
20207
20208            final long origId = Binder.clearCallingIdentity();
20209            try {
20210                if (values != null) {
20211                    Settings.System.clearConfiguration(values);
20212                }
20213                updateConfigurationLocked(values, null, false, false /* persistent */,
20214                        UserHandle.USER_NULL, false /* deferResume */,
20215                        mTmpUpdateConfigurationResult);
20216                return mTmpUpdateConfigurationResult.changes != 0;
20217            } finally {
20218                Binder.restoreCallingIdentity(origId);
20219            }
20220        }
20221    }
20222
20223    void updateUserConfigurationLocked() {
20224        final Configuration configuration = new Configuration(getGlobalConfiguration());
20225        final int currentUserId = mUserController.getCurrentUserIdLocked();
20226        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20227                currentUserId, Settings.System.canWrite(mContext));
20228        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20229                false /* persistent */, currentUserId, false /* deferResume */);
20230    }
20231
20232    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20233            boolean initLocale) {
20234        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20235    }
20236
20237    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20238            boolean initLocale, boolean deferResume) {
20239        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20240        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20241                UserHandle.USER_NULL, deferResume);
20242    }
20243
20244    // To cache the list of supported system locales
20245    private String[] mSupportedSystemLocales = null;
20246
20247    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20248            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20249        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20250                deferResume, null /* result */);
20251    }
20252
20253    /**
20254     * Do either or both things: (1) change the current configuration, and (2)
20255     * make sure the given activity is running with the (now) current
20256     * configuration.  Returns true if the activity has been left running, or
20257     * false if <var>starting</var> is being destroyed to match the new
20258     * configuration.
20259     *
20260     * @param userId is only used when persistent parameter is set to true to persist configuration
20261     *               for that particular user
20262     */
20263    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20264            boolean initLocale, boolean persistent, int userId, boolean deferResume,
20265            UpdateConfigurationResult result) {
20266        int changes = 0;
20267        boolean kept = true;
20268
20269        if (mWindowManager != null) {
20270            mWindowManager.deferSurfaceLayout();
20271        }
20272        try {
20273            if (values != null) {
20274                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20275                        deferResume);
20276            }
20277
20278            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20279        } finally {
20280            if (mWindowManager != null) {
20281                mWindowManager.continueSurfaceLayout();
20282            }
20283        }
20284
20285        if (result != null) {
20286            result.changes = changes;
20287            result.activityRelaunched = !kept;
20288        }
20289        return kept;
20290    }
20291
20292    /** Update default (global) configuration and notify listeners about changes. */
20293    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20294            boolean persistent, int userId, boolean deferResume) {
20295        mTempConfig.setTo(getGlobalConfiguration());
20296        final int changes = mTempConfig.updateFrom(values);
20297        if (changes == 0) {
20298            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20299            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20300            // performDisplayOverrideConfigUpdate in order to send the new display configuration
20301            // (even if there are no actual changes) to unfreeze the window.
20302            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20303            return 0;
20304        }
20305
20306        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20307                "Updating global configuration to: " + values);
20308
20309        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20310
20311        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20312            final LocaleList locales = values.getLocales();
20313            int bestLocaleIndex = 0;
20314            if (locales.size() > 1) {
20315                if (mSupportedSystemLocales == null) {
20316                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20317                }
20318                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20319            }
20320            SystemProperties.set("persist.sys.locale",
20321                    locales.get(bestLocaleIndex).toLanguageTag());
20322            LocaleList.setDefault(locales, bestLocaleIndex);
20323            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20324                    locales.get(bestLocaleIndex)));
20325        }
20326
20327        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20328        mTempConfig.seq = mConfigurationSeq;
20329
20330        // Update stored global config and notify everyone about the change.
20331        mStackSupervisor.onConfigurationChanged(mTempConfig);
20332
20333        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20334        // TODO(multi-display): Update UsageEvents#Event to include displayId.
20335        mUsageStatsService.reportConfigurationChange(mTempConfig,
20336                mUserController.getCurrentUserIdLocked());
20337
20338        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20339        mShowDialogs = shouldShowDialogs(mTempConfig);
20340
20341        AttributeCache ac = AttributeCache.instance();
20342        if (ac != null) {
20343            ac.updateConfiguration(mTempConfig);
20344        }
20345
20346        // Make sure all resources in our process are updated right now, so that anyone who is going
20347        // to retrieve resource values after we return will be sure to get the new ones. This is
20348        // especially important during boot, where the first config change needs to guarantee all
20349        // resources have that config before following boot code is executed.
20350        mSystemThread.applyConfigurationToResources(mTempConfig);
20351
20352        // We need another copy of global config because we're scheduling some calls instead of
20353        // running them in place. We need to be sure that object we send will be handled unchanged.
20354        final Configuration configCopy = new Configuration(mTempConfig);
20355        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20356            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20357            msg.obj = configCopy;
20358            msg.arg1 = userId;
20359            mHandler.sendMessage(msg);
20360        }
20361
20362        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20363            ProcessRecord app = mLruProcesses.get(i);
20364            try {
20365                if (app.thread != null) {
20366                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20367                            + app.processName + " new config " + configCopy);
20368                    app.thread.scheduleConfigurationChanged(configCopy);
20369                }
20370            } catch (Exception e) {
20371            }
20372        }
20373
20374        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20375        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20376                | Intent.FLAG_RECEIVER_FOREGROUND
20377                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20378        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20379                AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20380                UserHandle.USER_ALL);
20381        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20382            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20383            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20384                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20385                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20386            if (initLocale || !mProcessesReady) {
20387                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20388            }
20389            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20390                    AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20391                    UserHandle.USER_ALL);
20392        }
20393
20394        // Override configuration of the default display duplicates global config, so we need to
20395        // update it also. This will also notify WindowManager about changes.
20396        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20397                DEFAULT_DISPLAY);
20398
20399        return changes;
20400    }
20401
20402    @Override
20403    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20404        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20405
20406        synchronized (this) {
20407            // Check if display is initialized in AM.
20408            if (!mStackSupervisor.isDisplayAdded(displayId)) {
20409                // Call might come when display is not yet added or has already been removed.
20410                if (DEBUG_CONFIGURATION) {
20411                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20412                            + displayId);
20413                }
20414                return false;
20415            }
20416
20417            if (values == null && mWindowManager != null) {
20418                // sentinel: fetch the current configuration from the window manager
20419                values = mWindowManager.computeNewConfiguration(displayId);
20420            }
20421
20422            if (mWindowManager != null) {
20423                // Update OOM levels based on display size.
20424                mProcessList.applyDisplaySize(mWindowManager);
20425            }
20426
20427            final long origId = Binder.clearCallingIdentity();
20428            try {
20429                if (values != null) {
20430                    Settings.System.clearConfiguration(values);
20431                }
20432                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20433                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20434                return mTmpUpdateConfigurationResult.changes != 0;
20435            } finally {
20436                Binder.restoreCallingIdentity(origId);
20437            }
20438        }
20439    }
20440
20441    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20442            boolean deferResume, int displayId) {
20443        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20444                displayId, null /* result */);
20445    }
20446
20447    /**
20448     * Updates override configuration specific for the selected display. If no config is provided,
20449     * new one will be computed in WM based on current display info.
20450     */
20451    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20452            ActivityRecord starting, boolean deferResume, int displayId,
20453            UpdateConfigurationResult result) {
20454        int changes = 0;
20455        boolean kept = true;
20456
20457        if (mWindowManager != null) {
20458            mWindowManager.deferSurfaceLayout();
20459        }
20460        try {
20461            if (values != null) {
20462                if (displayId == DEFAULT_DISPLAY) {
20463                    // Override configuration of the default display duplicates global config, so
20464                    // we're calling global config update instead for default display. It will also
20465                    // apply the correct override config.
20466                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20467                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20468                } else {
20469                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20470                }
20471            }
20472
20473            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20474        } finally {
20475            if (mWindowManager != null) {
20476                mWindowManager.continueSurfaceLayout();
20477            }
20478        }
20479
20480        if (result != null) {
20481            result.changes = changes;
20482            result.activityRelaunched = !kept;
20483        }
20484        return kept;
20485    }
20486
20487    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20488            int displayId) {
20489        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20490        final int changes = mTempConfig.updateFrom(values);
20491        if (changes != 0) {
20492            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20493                    + mTempConfig + " for displayId=" + displayId);
20494            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20495
20496            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20497            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20498                // Reset the unsupported display size dialog.
20499                mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20500
20501                killAllBackgroundProcessesExcept(N,
20502                        ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20503            }
20504        }
20505
20506        // Update the configuration with WM first and check if any of the stacks need to be resized
20507        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20508        // necessary. This way we don't need to relaunch again afterwards in
20509        // ensureActivityConfigurationLocked().
20510        if (mWindowManager != null) {
20511            final int[] resizedStacks =
20512                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20513            if (resizedStacks != null) {
20514                for (int stackId : resizedStacks) {
20515                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20516                }
20517            }
20518        }
20519
20520        return changes;
20521    }
20522
20523    /** Applies latest configuration and/or visibility updates if needed. */
20524    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20525        boolean kept = true;
20526        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20527        // mainStack is null during startup.
20528        if (mainStack != null) {
20529            if (changes != 0 && starting == null) {
20530                // If the configuration changed, and the caller is not already
20531                // in the process of starting an activity, then find the top
20532                // activity to check if its configuration needs to change.
20533                starting = mainStack.topRunningActivityLocked();
20534            }
20535
20536            if (starting != null) {
20537                kept = starting.ensureActivityConfigurationLocked(changes,
20538                        false /* preserveWindow */);
20539                // And we need to make sure at this point that all other activities
20540                // are made visible with the correct configuration.
20541                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20542                        !PRESERVE_WINDOWS);
20543            }
20544        }
20545
20546        return kept;
20547    }
20548
20549    /** Helper method that requests bounds from WM and applies them to stack. */
20550    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20551        final Rect newStackBounds = new Rect();
20552        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20553        mStackSupervisor.resizeStackLocked(
20554                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20555                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20556                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20557    }
20558
20559    /**
20560     * Decide based on the configuration whether we should show the ANR,
20561     * crash, etc dialogs.  The idea is that if there is no affordance to
20562     * press the on-screen buttons, or the user experience would be more
20563     * greatly impacted than the crash itself, we shouldn't show the dialog.
20564     *
20565     * A thought: SystemUI might also want to get told about this, the Power
20566     * dialog / global actions also might want different behaviors.
20567     */
20568    private static boolean shouldShowDialogs(Configuration config) {
20569        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20570                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20571                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20572        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20573        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20574                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20575                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20576                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20577        return inputMethodExists && uiModeSupportsDialogs;
20578    }
20579
20580    @Override
20581    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20582        synchronized (this) {
20583            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20584            if (srec != null) {
20585                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20586            }
20587        }
20588        return false;
20589    }
20590
20591    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20592            Intent resultData) {
20593
20594        synchronized (this) {
20595            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20596            if (r != null) {
20597                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20598            }
20599            return false;
20600        }
20601    }
20602
20603    public int getLaunchedFromUid(IBinder activityToken) {
20604        ActivityRecord srec;
20605        synchronized (this) {
20606            srec = ActivityRecord.forTokenLocked(activityToken);
20607        }
20608        if (srec == null) {
20609            return -1;
20610        }
20611        return srec.launchedFromUid;
20612    }
20613
20614    public String getLaunchedFromPackage(IBinder activityToken) {
20615        ActivityRecord srec;
20616        synchronized (this) {
20617            srec = ActivityRecord.forTokenLocked(activityToken);
20618        }
20619        if (srec == null) {
20620            return null;
20621        }
20622        return srec.launchedFromPackage;
20623    }
20624
20625    // =========================================================
20626    // LIFETIME MANAGEMENT
20627    // =========================================================
20628
20629    // Returns whether the app is receiving broadcast.
20630    // If receiving, fetch all broadcast queues which the app is
20631    // the current [or imminent] receiver on.
20632    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20633            ArraySet<BroadcastQueue> receivingQueues) {
20634        if (!app.curReceivers.isEmpty()) {
20635            for (BroadcastRecord r : app.curReceivers) {
20636                receivingQueues.add(r.queue);
20637            }
20638            return true;
20639        }
20640
20641        // It's not the current receiver, but it might be starting up to become one
20642        for (BroadcastQueue queue : mBroadcastQueues) {
20643            final BroadcastRecord r = queue.mPendingBroadcast;
20644            if (r != null && r.curApp == app) {
20645                // found it; report which queue it's in
20646                receivingQueues.add(queue);
20647            }
20648        }
20649
20650        return !receivingQueues.isEmpty();
20651    }
20652
20653    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20654            int targetUid, ComponentName targetComponent, String targetProcess) {
20655        if (!mTrackingAssociations) {
20656            return null;
20657        }
20658        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20659                = mAssociations.get(targetUid);
20660        if (components == null) {
20661            components = new ArrayMap<>();
20662            mAssociations.put(targetUid, components);
20663        }
20664        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20665        if (sourceUids == null) {
20666            sourceUids = new SparseArray<>();
20667            components.put(targetComponent, sourceUids);
20668        }
20669        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20670        if (sourceProcesses == null) {
20671            sourceProcesses = new ArrayMap<>();
20672            sourceUids.put(sourceUid, sourceProcesses);
20673        }
20674        Association ass = sourceProcesses.get(sourceProcess);
20675        if (ass == null) {
20676            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20677                    targetProcess);
20678            sourceProcesses.put(sourceProcess, ass);
20679        }
20680        ass.mCount++;
20681        ass.mNesting++;
20682        if (ass.mNesting == 1) {
20683            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20684            ass.mLastState = sourceState;
20685        }
20686        return ass;
20687    }
20688
20689    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20690            ComponentName targetComponent) {
20691        if (!mTrackingAssociations) {
20692            return;
20693        }
20694        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20695                = mAssociations.get(targetUid);
20696        if (components == null) {
20697            return;
20698        }
20699        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20700        if (sourceUids == null) {
20701            return;
20702        }
20703        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20704        if (sourceProcesses == null) {
20705            return;
20706        }
20707        Association ass = sourceProcesses.get(sourceProcess);
20708        if (ass == null || ass.mNesting <= 0) {
20709            return;
20710        }
20711        ass.mNesting--;
20712        if (ass.mNesting == 0) {
20713            long uptime = SystemClock.uptimeMillis();
20714            ass.mTime += uptime - ass.mStartTime;
20715            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20716                    += uptime - ass.mLastStateUptime;
20717            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20718        }
20719    }
20720
20721    private void noteUidProcessState(final int uid, final int state) {
20722        mBatteryStatsService.noteUidProcessState(uid, state);
20723        if (mTrackingAssociations) {
20724            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20725                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20726                        = mAssociations.valueAt(i1);
20727                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20728                    SparseArray<ArrayMap<String, Association>> sourceUids
20729                            = targetComponents.valueAt(i2);
20730                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20731                    if (sourceProcesses != null) {
20732                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20733                            Association ass = sourceProcesses.valueAt(i4);
20734                            if (ass.mNesting >= 1) {
20735                                // currently associated
20736                                long uptime = SystemClock.uptimeMillis();
20737                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20738                                        += uptime - ass.mLastStateUptime;
20739                                ass.mLastState = state;
20740                                ass.mLastStateUptime = uptime;
20741                            }
20742                        }
20743                    }
20744                }
20745            }
20746        }
20747    }
20748
20749    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20750            boolean doingAll, long now) {
20751        if (mAdjSeq == app.adjSeq) {
20752            // This adjustment has already been computed.
20753            return app.curRawAdj;
20754        }
20755
20756        if (app.thread == null) {
20757            app.adjSeq = mAdjSeq;
20758            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20759            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20760            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20761        }
20762
20763        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20764        app.adjSource = null;
20765        app.adjTarget = null;
20766        app.empty = false;
20767        app.cached = false;
20768
20769        final int activitiesSize = app.activities.size();
20770
20771        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20772            // The max adjustment doesn't allow this app to be anything
20773            // below foreground, so it is not worth doing work for it.
20774            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20775            app.adjType = "fixed";
20776            app.adjSeq = mAdjSeq;
20777            app.curRawAdj = app.maxAdj;
20778            app.foregroundActivities = false;
20779            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20780            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20781            // System processes can do UI, and when they do we want to have
20782            // them trim their memory after the user leaves the UI.  To
20783            // facilitate this, here we need to determine whether or not it
20784            // is currently showing UI.
20785            app.systemNoUi = true;
20786            if (app == TOP_APP) {
20787                app.systemNoUi = false;
20788                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20789                app.adjType = "pers-top-activity";
20790            } else if (app.hasTopUi) {
20791                app.systemNoUi = false;
20792                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20793                app.adjType = "pers-top-ui";
20794            } else if (activitiesSize > 0) {
20795                for (int j = 0; j < activitiesSize; j++) {
20796                    final ActivityRecord r = app.activities.get(j);
20797                    if (r.visible) {
20798                        app.systemNoUi = false;
20799                    }
20800                }
20801            }
20802            if (!app.systemNoUi) {
20803                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20804            }
20805            return (app.curAdj=app.maxAdj);
20806        }
20807
20808        app.systemNoUi = false;
20809
20810        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20811
20812        // Determine the importance of the process, starting with most
20813        // important to least, and assign an appropriate OOM adjustment.
20814        int adj;
20815        int schedGroup;
20816        int procState;
20817        boolean foregroundActivities = false;
20818        mTmpBroadcastQueue.clear();
20819        if (app == TOP_APP) {
20820            // The last app on the list is the foreground app.
20821            adj = ProcessList.FOREGROUND_APP_ADJ;
20822            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20823            app.adjType = "top-activity";
20824            foregroundActivities = true;
20825            procState = PROCESS_STATE_CUR_TOP;
20826            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20827        } else if (app.instr != null) {
20828            // Don't want to kill running instrumentation.
20829            adj = ProcessList.FOREGROUND_APP_ADJ;
20830            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20831            app.adjType = "instrumentation";
20832            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20833            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20834        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20835            // An app that is currently receiving a broadcast also
20836            // counts as being in the foreground for OOM killer purposes.
20837            // It's placed in a sched group based on the nature of the
20838            // broadcast as reflected by which queue it's active in.
20839            adj = ProcessList.FOREGROUND_APP_ADJ;
20840            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20841                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20842            app.adjType = "broadcast";
20843            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20844            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20845        } else if (app.executingServices.size() > 0) {
20846            // An app that is currently executing a service callback also
20847            // counts as being in the foreground.
20848            adj = ProcessList.FOREGROUND_APP_ADJ;
20849            schedGroup = app.execServicesFg ?
20850                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20851            app.adjType = "exec-service";
20852            procState = ActivityManager.PROCESS_STATE_SERVICE;
20853            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20854            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20855        } else {
20856            // As far as we know the process is empty.  We may change our mind later.
20857            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20858            // At this point we don't actually know the adjustment.  Use the cached adj
20859            // value that the caller wants us to.
20860            adj = cachedAdj;
20861            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20862            app.cached = true;
20863            app.empty = true;
20864            app.adjType = "cch-empty";
20865            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20866        }
20867
20868        // Examine all activities if not already foreground.
20869        if (!foregroundActivities && activitiesSize > 0) {
20870            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20871            for (int j = 0; j < activitiesSize; j++) {
20872                final ActivityRecord r = app.activities.get(j);
20873                if (r.app != app) {
20874                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20875                            + " instead of expected " + app);
20876                    if (r.app == null || (r.app.uid == app.uid)) {
20877                        // Only fix things up when they look sane
20878                        r.app = app;
20879                    } else {
20880                        continue;
20881                    }
20882                }
20883                if (r.visible) {
20884                    // App has a visible activity; only upgrade adjustment.
20885                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20886                        adj = ProcessList.VISIBLE_APP_ADJ;
20887                        app.adjType = "vis-activity";
20888                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20889                    }
20890                    if (procState > PROCESS_STATE_CUR_TOP) {
20891                        procState = PROCESS_STATE_CUR_TOP;
20892                        app.adjType = "vis-activity";
20893                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20894                    }
20895                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20896                    app.cached = false;
20897                    app.empty = false;
20898                    foregroundActivities = true;
20899                    final TaskRecord task = r.getTask();
20900                    if (task != null && minLayer > 0) {
20901                        final int layer = task.mLayerRank;
20902                        if (layer >= 0 && minLayer > layer) {
20903                            minLayer = layer;
20904                        }
20905                    }
20906                    break;
20907                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20908                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20909                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20910                        app.adjType = "pause-activity";
20911                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20912                    }
20913                    if (procState > PROCESS_STATE_CUR_TOP) {
20914                        procState = PROCESS_STATE_CUR_TOP;
20915                        app.adjType = "pause-activity";
20916                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20917                    }
20918                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20919                    app.cached = false;
20920                    app.empty = false;
20921                    foregroundActivities = true;
20922                } else if (r.state == ActivityState.STOPPING) {
20923                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20924                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20925                        app.adjType = "stop-activity";
20926                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20927                    }
20928                    // For the process state, we will at this point consider the
20929                    // process to be cached.  It will be cached either as an activity
20930                    // or empty depending on whether the activity is finishing.  We do
20931                    // this so that we can treat the process as cached for purposes of
20932                    // memory trimming (determing current memory level, trim command to
20933                    // send to process) since there can be an arbitrary number of stopping
20934                    // processes and they should soon all go into the cached state.
20935                    if (!r.finishing) {
20936                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20937                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20938                            app.adjType = "stop-activity";
20939                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20940                        }
20941                    }
20942                    app.cached = false;
20943                    app.empty = false;
20944                    foregroundActivities = true;
20945                } else {
20946                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20947                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20948                        app.adjType = "cch-act";
20949                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
20950                    }
20951                }
20952            }
20953            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20954                adj += minLayer;
20955            }
20956        }
20957
20958        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20959                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20960            if (app.foregroundServices) {
20961                // The user is aware of this app, so make it visible.
20962                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20963                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20964                app.cached = false;
20965                app.adjType = "fg-service";
20966                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20967                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
20968            } else if (app.hasOverlayUi) {
20969                // The process is display an overlay UI.
20970                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20971                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20972                app.cached = false;
20973                app.adjType = "has-overlay-ui";
20974                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20975                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
20976            }
20977        }
20978
20979        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20980                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
20981            if (app.forcingToImportant != null) {
20982                // This is currently used for toasts...  they are not interactive, and
20983                // we don't want them to cause the app to become fully foreground (and
20984                // thus out of background check), so we yes the best background level we can.
20985                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20986                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
20987                app.cached = false;
20988                app.adjType = "force-imp";
20989                app.adjSource = app.forcingToImportant;
20990                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20991                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
20992            }
20993        }
20994
20995        if (app == mHeavyWeightProcess) {
20996            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20997                // We don't want to kill the current heavy-weight process.
20998                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20999                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21000                app.cached = false;
21001                app.adjType = "heavy";
21002                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21003            }
21004            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21005                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21006                app.adjType = "heavy";
21007                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21008            }
21009        }
21010
21011        if (app == mHomeProcess) {
21012            if (adj > ProcessList.HOME_APP_ADJ) {
21013                // This process is hosting what we currently consider to be the
21014                // home app, so we don't want to let it go into the background.
21015                adj = ProcessList.HOME_APP_ADJ;
21016                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21017                app.cached = false;
21018                app.adjType = "home";
21019                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21020            }
21021            if (procState > ActivityManager.PROCESS_STATE_HOME) {
21022                procState = ActivityManager.PROCESS_STATE_HOME;
21023                app.adjType = "home";
21024                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21025            }
21026        }
21027
21028        if (app == mPreviousProcess && app.activities.size() > 0) {
21029            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21030                // This was the previous process that showed UI to the user.
21031                // We want to try to keep it around more aggressively, to give
21032                // a good experience around switching between two apps.
21033                adj = ProcessList.PREVIOUS_APP_ADJ;
21034                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21035                app.cached = false;
21036                app.adjType = "previous";
21037                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21038            }
21039            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21040                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21041                app.adjType = "previous";
21042                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21043            }
21044        }
21045
21046        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21047                + " reason=" + app.adjType);
21048
21049        // By default, we use the computed adjustment.  It may be changed if
21050        // there are applications dependent on our services or providers, but
21051        // this gives us a baseline and makes sure we don't get into an
21052        // infinite recursion.
21053        app.adjSeq = mAdjSeq;
21054        app.curRawAdj = adj;
21055        app.hasStartedServices = false;
21056
21057        if (mBackupTarget != null && app == mBackupTarget.app) {
21058            // If possible we want to avoid killing apps while they're being backed up
21059            if (adj > ProcessList.BACKUP_APP_ADJ) {
21060                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21061                adj = ProcessList.BACKUP_APP_ADJ;
21062                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21063                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21064                }
21065                app.adjType = "backup";
21066                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21067                app.cached = false;
21068            }
21069            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21070                procState = ActivityManager.PROCESS_STATE_BACKUP;
21071                app.adjType = "backup";
21072                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21073            }
21074        }
21075
21076        boolean mayBeTop = false;
21077        String mayBeTopType = null;
21078        Object mayBeTopSource = null;
21079        Object mayBeTopTarget = null;
21080
21081        for (int is = app.services.size()-1;
21082                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21083                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21084                        || procState > ActivityManager.PROCESS_STATE_TOP);
21085                is--) {
21086            ServiceRecord s = app.services.valueAt(is);
21087            if (s.startRequested) {
21088                app.hasStartedServices = true;
21089                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21090                    procState = ActivityManager.PROCESS_STATE_SERVICE;
21091                    app.adjType = "started-services";
21092                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21093                }
21094                if (app.hasShownUi && app != mHomeProcess) {
21095                    // If this process has shown some UI, let it immediately
21096                    // go to the LRU list because it may be pretty heavy with
21097                    // UI stuff.  We'll tag it with a label just to help
21098                    // debug and understand what is going on.
21099                    if (adj > ProcessList.SERVICE_ADJ) {
21100                        app.adjType = "cch-started-ui-services";
21101                    }
21102                } else {
21103                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21104                        // This service has seen some activity within
21105                        // recent memory, so we will keep its process ahead
21106                        // of the background processes.
21107                        if (adj > ProcessList.SERVICE_ADJ) {
21108                            adj = ProcessList.SERVICE_ADJ;
21109                            app.adjType = "started-services";
21110                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21111                            app.cached = false;
21112                        }
21113                    }
21114                    // If we have let the service slide into the background
21115                    // state, still have some text describing what it is doing
21116                    // even though the service no longer has an impact.
21117                    if (adj > ProcessList.SERVICE_ADJ) {
21118                        app.adjType = "cch-started-services";
21119                    }
21120                }
21121            }
21122
21123            for (int conni = s.connections.size()-1;
21124                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21125                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21126                            || procState > ActivityManager.PROCESS_STATE_TOP);
21127                    conni--) {
21128                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21129                for (int i = 0;
21130                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21131                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21132                                || procState > ActivityManager.PROCESS_STATE_TOP);
21133                        i++) {
21134                    // XXX should compute this based on the max of
21135                    // all connected clients.
21136                    ConnectionRecord cr = clist.get(i);
21137                    if (cr.binding.client == app) {
21138                        // Binding to ourself is not interesting.
21139                        continue;
21140                    }
21141
21142                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21143                        ProcessRecord client = cr.binding.client;
21144                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
21145                                TOP_APP, doingAll, now);
21146                        int clientProcState = client.curProcState;
21147                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21148                            // If the other app is cached for any reason, for purposes here
21149                            // we are going to consider it empty.  The specific cached state
21150                            // doesn't propagate except under certain conditions.
21151                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21152                        }
21153                        String adjType = null;
21154                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21155                            // Not doing bind OOM management, so treat
21156                            // this guy more like a started service.
21157                            if (app.hasShownUi && app != mHomeProcess) {
21158                                // If this process has shown some UI, let it immediately
21159                                // go to the LRU list because it may be pretty heavy with
21160                                // UI stuff.  We'll tag it with a label just to help
21161                                // debug and understand what is going on.
21162                                if (adj > clientAdj) {
21163                                    adjType = "cch-bound-ui-services";
21164                                }
21165                                app.cached = false;
21166                                clientAdj = adj;
21167                                clientProcState = procState;
21168                            } else {
21169                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21170                                    // This service has not seen activity within
21171                                    // recent memory, so allow it to drop to the
21172                                    // LRU list if there is no other reason to keep
21173                                    // it around.  We'll also tag it with a label just
21174                                    // to help debug and undertand what is going on.
21175                                    if (adj > clientAdj) {
21176                                        adjType = "cch-bound-services";
21177                                    }
21178                                    clientAdj = adj;
21179                                }
21180                            }
21181                        }
21182                        if (adj > clientAdj) {
21183                            // If this process has recently shown UI, and
21184                            // the process that is binding to it is less
21185                            // important than being visible, then we don't
21186                            // care about the binding as much as we care
21187                            // about letting this process get into the LRU
21188                            // list to be killed and restarted if needed for
21189                            // memory.
21190                            if (app.hasShownUi && app != mHomeProcess
21191                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21192                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21193                                    adjType = "cch-bound-ui-services";
21194                                }
21195                            } else {
21196                                int newAdj;
21197                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21198                                        |Context.BIND_IMPORTANT)) != 0) {
21199                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21200                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21201                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21202                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21203                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21204                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21205                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21206                                    newAdj = clientAdj;
21207                                } else {
21208                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
21209                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21210                                    } else {
21211                                        newAdj = adj;
21212                                    }
21213                                }
21214                                if (!client.cached) {
21215                                    app.cached = false;
21216                                }
21217                                if (adj >  newAdj) {
21218                                    adj = newAdj;
21219                                    adjType = "service";
21220                                }
21221                            }
21222                        }
21223                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21224                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21225                            // This will treat important bound services identically to
21226                            // the top app, which may behave differently than generic
21227                            // foreground work.
21228                            if (client.curSchedGroup > schedGroup) {
21229                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21230                                    schedGroup = client.curSchedGroup;
21231                                } else {
21232                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21233                                }
21234                            }
21235                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21236                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21237                                    // Special handling of clients who are in the top state.
21238                                    // We *may* want to consider this process to be in the
21239                                    // top state as well, but only if there is not another
21240                                    // reason for it to be running.  Being on the top is a
21241                                    // special state, meaning you are specifically running
21242                                    // for the current top app.  If the process is already
21243                                    // running in the background for some other reason, it
21244                                    // is more important to continue considering it to be
21245                                    // in the background state.
21246                                    mayBeTop = true;
21247                                    mayBeTopType = "service";
21248                                    mayBeTopSource = cr.binding.client;
21249                                    mayBeTopTarget = s.name;
21250                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21251                                } else {
21252                                    // Special handling for above-top states (persistent
21253                                    // processes).  These should not bring the current process
21254                                    // into the top state, since they are not on top.  Instead
21255                                    // give them the best state after that.
21256                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21257                                        clientProcState =
21258                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21259                                    } else if (mWakefulness
21260                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21261                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21262                                                    != 0) {
21263                                        clientProcState =
21264                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21265                                    } else {
21266                                        clientProcState =
21267                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21268                                    }
21269                                }
21270                            }
21271                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21272                            if (clientProcState <
21273                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21274                                clientProcState =
21275                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21276                            }
21277                        } else {
21278                            if (clientProcState <
21279                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21280                                clientProcState =
21281                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21282                            }
21283                        }
21284                        if (procState > clientProcState) {
21285                            procState = clientProcState;
21286                            if (adjType == null) {
21287                                adjType = "service";
21288                            }
21289                        }
21290                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21291                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21292                            app.pendingUiClean = true;
21293                        }
21294                        if (adjType != null) {
21295                            app.adjType = adjType;
21296                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21297                                    .REASON_SERVICE_IN_USE;
21298                            app.adjSource = cr.binding.client;
21299                            app.adjSourceProcState = clientProcState;
21300                            app.adjTarget = s.name;
21301                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21302                                    + ": " + app + ", due to " + cr.binding.client
21303                                    + " adj=" + adj + " procState=" + procState);
21304                        }
21305                    }
21306                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21307                        app.treatLikeActivity = true;
21308                    }
21309                    final ActivityRecord a = cr.activity;
21310                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21311                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21312                            (a.visible || a.state == ActivityState.RESUMED ||
21313                             a.state == ActivityState.PAUSING)) {
21314                            adj = ProcessList.FOREGROUND_APP_ADJ;
21315                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21316                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21317                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21318                                } else {
21319                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21320                                }
21321                            }
21322                            app.cached = false;
21323                            app.adjType = "service";
21324                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21325                                    .REASON_SERVICE_IN_USE;
21326                            app.adjSource = a;
21327                            app.adjSourceProcState = procState;
21328                            app.adjTarget = s.name;
21329                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21330                                    + app);
21331                        }
21332                    }
21333                }
21334            }
21335        }
21336
21337        for (int provi = app.pubProviders.size()-1;
21338                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21339                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21340                        || procState > ActivityManager.PROCESS_STATE_TOP);
21341                provi--) {
21342            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21343            for (int i = cpr.connections.size()-1;
21344                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21345                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21346                            || procState > ActivityManager.PROCESS_STATE_TOP);
21347                    i--) {
21348                ContentProviderConnection conn = cpr.connections.get(i);
21349                ProcessRecord client = conn.client;
21350                if (client == app) {
21351                    // Being our own client is not interesting.
21352                    continue;
21353                }
21354                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21355                int clientProcState = client.curProcState;
21356                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21357                    // If the other app is cached for any reason, for purposes here
21358                    // we are going to consider it empty.
21359                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21360                }
21361                String adjType = null;
21362                if (adj > clientAdj) {
21363                    if (app.hasShownUi && app != mHomeProcess
21364                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21365                        adjType = "cch-ui-provider";
21366                    } else {
21367                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21368                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21369                        adjType = "provider";
21370                    }
21371                    app.cached &= client.cached;
21372                }
21373                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21374                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21375                        // Special handling of clients who are in the top state.
21376                        // We *may* want to consider this process to be in the
21377                        // top state as well, but only if there is not another
21378                        // reason for it to be running.  Being on the top is a
21379                        // special state, meaning you are specifically running
21380                        // for the current top app.  If the process is already
21381                        // running in the background for some other reason, it
21382                        // is more important to continue considering it to be
21383                        // in the background state.
21384                        mayBeTop = true;
21385                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21386                        mayBeTopType = adjType = "provider-top";
21387                        mayBeTopSource = client;
21388                        mayBeTopTarget = cpr.name;
21389                    } else {
21390                        // Special handling for above-top states (persistent
21391                        // processes).  These should not bring the current process
21392                        // into the top state, since they are not on top.  Instead
21393                        // give them the best state after that.
21394                        clientProcState =
21395                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21396                        if (adjType == null) {
21397                            adjType = "provider";
21398                        }
21399                    }
21400                }
21401                if (procState > clientProcState) {
21402                    procState = clientProcState;
21403                }
21404                if (client.curSchedGroup > schedGroup) {
21405                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21406                }
21407                if (adjType != null) {
21408                    app.adjType = adjType;
21409                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21410                            .REASON_PROVIDER_IN_USE;
21411                    app.adjSource = client;
21412                    app.adjSourceProcState = clientProcState;
21413                    app.adjTarget = cpr.name;
21414                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21415                            + ": " + app + ", due to " + client
21416                            + " adj=" + adj + " procState=" + procState);
21417                }
21418            }
21419            // If the provider has external (non-framework) process
21420            // dependencies, ensure that its adjustment is at least
21421            // FOREGROUND_APP_ADJ.
21422            if (cpr.hasExternalProcessHandles()) {
21423                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21424                    adj = ProcessList.FOREGROUND_APP_ADJ;
21425                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21426                    app.cached = false;
21427                    app.adjType = "ext-provider";
21428                    app.adjTarget = cpr.name;
21429                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21430                }
21431                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21432                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21433                }
21434            }
21435        }
21436
21437        if (app.lastProviderTime > 0 &&
21438                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21439            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21440                adj = ProcessList.PREVIOUS_APP_ADJ;
21441                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21442                app.cached = false;
21443                app.adjType = "recent-provider";
21444                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21445            }
21446            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21447                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21448                app.adjType = "recent-provider";
21449                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21450            }
21451        }
21452
21453        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21454            // A client of one of our services or providers is in the top state.  We
21455            // *may* want to be in the top state, but not if we are already running in
21456            // the background for some other reason.  For the decision here, we are going
21457            // to pick out a few specific states that we want to remain in when a client
21458            // is top (states that tend to be longer-term) and otherwise allow it to go
21459            // to the top state.
21460            switch (procState) {
21461                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21462                    // Something else is keeping it at this level, just leave it.
21463                    break;
21464                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21465                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21466                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21467                case ActivityManager.PROCESS_STATE_SERVICE:
21468                    // These all are longer-term states, so pull them up to the top
21469                    // of the background states, but not all the way to the top state.
21470                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21471                    app.adjType = mayBeTopType;
21472                    app.adjSource = mayBeTopSource;
21473                    app.adjTarget = mayBeTopTarget;
21474                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21475                            + ": " + app + ", due to " + mayBeTopSource
21476                            + " adj=" + adj + " procState=" + procState);
21477                    break;
21478                default:
21479                    // Otherwise, top is a better choice, so take it.
21480                    procState = ActivityManager.PROCESS_STATE_TOP;
21481                    app.adjType = mayBeTopType;
21482                    app.adjSource = mayBeTopSource;
21483                    app.adjTarget = mayBeTopTarget;
21484                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21485                            + ": " + app + ", due to " + mayBeTopSource
21486                            + " adj=" + adj + " procState=" + procState);
21487                    break;
21488            }
21489        }
21490
21491        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21492            if (app.hasClientActivities) {
21493                // This is a cached process, but with client activities.  Mark it so.
21494                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21495                app.adjType = "cch-client-act";
21496            } else if (app.treatLikeActivity) {
21497                // This is a cached process, but somebody wants us to treat it like it has
21498                // an activity, okay!
21499                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21500                app.adjType = "cch-as-act";
21501            }
21502        }
21503
21504        if (adj == ProcessList.SERVICE_ADJ) {
21505            if (doingAll) {
21506                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21507                mNewNumServiceProcs++;
21508                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21509                if (!app.serviceb) {
21510                    // This service isn't far enough down on the LRU list to
21511                    // normally be a B service, but if we are low on RAM and it
21512                    // is large we want to force it down since we would prefer to
21513                    // keep launcher over it.
21514                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21515                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21516                        app.serviceHighRam = true;
21517                        app.serviceb = true;
21518                        //Slog.i(TAG, "ADJ " + app + " high ram!");
21519                    } else {
21520                        mNewNumAServiceProcs++;
21521                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
21522                    }
21523                } else {
21524                    app.serviceHighRam = false;
21525                }
21526            }
21527            if (app.serviceb) {
21528                adj = ProcessList.SERVICE_B_ADJ;
21529            }
21530        }
21531
21532        app.curRawAdj = adj;
21533
21534        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21535        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21536        if (adj > app.maxAdj) {
21537            adj = app.maxAdj;
21538            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21539                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21540            }
21541        }
21542
21543        // Do final modification to adj.  Everything we do between here and applying
21544        // the final setAdj must be done in this function, because we will also use
21545        // it when computing the final cached adj later.  Note that we don't need to
21546        // worry about this for max adj above, since max adj will always be used to
21547        // keep it out of the cached vaues.
21548        app.curAdj = app.modifyRawOomAdj(adj);
21549        app.curSchedGroup = schedGroup;
21550        app.curProcState = procState;
21551        app.foregroundActivities = foregroundActivities;
21552
21553        return app.curRawAdj;
21554    }
21555
21556    /**
21557     * Record new PSS sample for a process.
21558     */
21559    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21560            long now) {
21561        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21562                swapPss * 1024);
21563        proc.lastPssTime = now;
21564        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21565        if (DEBUG_PSS) Slog.d(TAG_PSS,
21566                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21567                + " state=" + ProcessList.makeProcStateString(procState));
21568        if (proc.initialIdlePss == 0) {
21569            proc.initialIdlePss = pss;
21570        }
21571        proc.lastPss = pss;
21572        proc.lastSwapPss = swapPss;
21573        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21574            proc.lastCachedPss = pss;
21575            proc.lastCachedSwapPss = swapPss;
21576        }
21577
21578        final SparseArray<Pair<Long, String>> watchUids
21579                = mMemWatchProcesses.getMap().get(proc.processName);
21580        Long check = null;
21581        if (watchUids != null) {
21582            Pair<Long, String> val = watchUids.get(proc.uid);
21583            if (val == null) {
21584                val = watchUids.get(0);
21585            }
21586            if (val != null) {
21587                check = val.first;
21588            }
21589        }
21590        if (check != null) {
21591            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21592                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21593                if (!isDebuggable) {
21594                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21595                        isDebuggable = true;
21596                    }
21597                }
21598                if (isDebuggable) {
21599                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21600                    final ProcessRecord myProc = proc;
21601                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21602                    mMemWatchDumpProcName = proc.processName;
21603                    mMemWatchDumpFile = heapdumpFile.toString();
21604                    mMemWatchDumpPid = proc.pid;
21605                    mMemWatchDumpUid = proc.uid;
21606                    BackgroundThread.getHandler().post(new Runnable() {
21607                        @Override
21608                        public void run() {
21609                            revokeUriPermission(ActivityThread.currentActivityThread()
21610                                            .getApplicationThread(),
21611                                    null, DumpHeapActivity.JAVA_URI,
21612                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21613                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21614                                    UserHandle.myUserId());
21615                            ParcelFileDescriptor fd = null;
21616                            try {
21617                                heapdumpFile.delete();
21618                                fd = ParcelFileDescriptor.open(heapdumpFile,
21619                                        ParcelFileDescriptor.MODE_CREATE |
21620                                                ParcelFileDescriptor.MODE_TRUNCATE |
21621                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21622                                                ParcelFileDescriptor.MODE_APPEND);
21623                                IApplicationThread thread = myProc.thread;
21624                                if (thread != null) {
21625                                    try {
21626                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21627                                                "Requesting dump heap from "
21628                                                + myProc + " to " + heapdumpFile);
21629                                        thread.dumpHeap(/* managed= */ true,
21630                                                /* mallocInfo= */ false, /* runGc= */ false,
21631                                                heapdumpFile.toString(), fd);
21632                                    } catch (RemoteException e) {
21633                                    }
21634                                }
21635                            } catch (FileNotFoundException e) {
21636                                e.printStackTrace();
21637                            } finally {
21638                                if (fd != null) {
21639                                    try {
21640                                        fd.close();
21641                                    } catch (IOException e) {
21642                                    }
21643                                }
21644                            }
21645                        }
21646                    });
21647                } else {
21648                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21649                            + ", but debugging not enabled");
21650                }
21651            }
21652        }
21653    }
21654
21655    /**
21656     * Schedule PSS collection of a process.
21657     */
21658    void requestPssLocked(ProcessRecord proc, int procState) {
21659        if (mPendingPssProcesses.contains(proc)) {
21660            return;
21661        }
21662        if (mPendingPssProcesses.size() == 0) {
21663            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21664        }
21665        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21666        proc.pssProcState = procState;
21667        mPendingPssProcesses.add(proc);
21668    }
21669
21670    /**
21671     * Schedule PSS collection of all processes.
21672     */
21673    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21674        if (!always) {
21675            if (now < (mLastFullPssTime +
21676                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21677                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
21678                return;
21679            }
21680        }
21681        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21682        mLastFullPssTime = now;
21683        mFullPssPending = true;
21684        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21685        mPendingPssProcesses.clear();
21686        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21687            ProcessRecord app = mLruProcesses.get(i);
21688            if (app.thread == null
21689                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21690                continue;
21691            }
21692            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21693                app.pssProcState = app.setProcState;
21694                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21695                        mTestPssMode, isSleepingLocked(), now);
21696                mPendingPssProcesses.add(app);
21697            }
21698        }
21699        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21700    }
21701
21702    public void setTestPssMode(boolean enabled) {
21703        synchronized (this) {
21704            mTestPssMode = enabled;
21705            if (enabled) {
21706                // Whenever we enable the mode, we want to take a snapshot all of current
21707                // process mem use.
21708                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21709            }
21710        }
21711    }
21712
21713    /**
21714     * Ask a given process to GC right now.
21715     */
21716    final void performAppGcLocked(ProcessRecord app) {
21717        try {
21718            app.lastRequestedGc = SystemClock.uptimeMillis();
21719            if (app.thread != null) {
21720                if (app.reportLowMemory) {
21721                    app.reportLowMemory = false;
21722                    app.thread.scheduleLowMemory();
21723                } else {
21724                    app.thread.processInBackground();
21725                }
21726            }
21727        } catch (Exception e) {
21728            // whatever.
21729        }
21730    }
21731
21732    /**
21733     * Returns true if things are idle enough to perform GCs.
21734     */
21735    private final boolean canGcNowLocked() {
21736        boolean processingBroadcasts = false;
21737        for (BroadcastQueue q : mBroadcastQueues) {
21738            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21739                processingBroadcasts = true;
21740            }
21741        }
21742        return !processingBroadcasts
21743                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21744    }
21745
21746    /**
21747     * Perform GCs on all processes that are waiting for it, but only
21748     * if things are idle.
21749     */
21750    final void performAppGcsLocked() {
21751        final int N = mProcessesToGc.size();
21752        if (N <= 0) {
21753            return;
21754        }
21755        if (canGcNowLocked()) {
21756            while (mProcessesToGc.size() > 0) {
21757                ProcessRecord proc = mProcessesToGc.remove(0);
21758                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21759                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21760                            <= SystemClock.uptimeMillis()) {
21761                        // To avoid spamming the system, we will GC processes one
21762                        // at a time, waiting a few seconds between each.
21763                        performAppGcLocked(proc);
21764                        scheduleAppGcsLocked();
21765                        return;
21766                    } else {
21767                        // It hasn't been long enough since we last GCed this
21768                        // process...  put it in the list to wait for its time.
21769                        addProcessToGcListLocked(proc);
21770                        break;
21771                    }
21772                }
21773            }
21774
21775            scheduleAppGcsLocked();
21776        }
21777    }
21778
21779    /**
21780     * If all looks good, perform GCs on all processes waiting for them.
21781     */
21782    final void performAppGcsIfAppropriateLocked() {
21783        if (canGcNowLocked()) {
21784            performAppGcsLocked();
21785            return;
21786        }
21787        // Still not idle, wait some more.
21788        scheduleAppGcsLocked();
21789    }
21790
21791    /**
21792     * Schedule the execution of all pending app GCs.
21793     */
21794    final void scheduleAppGcsLocked() {
21795        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21796
21797        if (mProcessesToGc.size() > 0) {
21798            // Schedule a GC for the time to the next process.
21799            ProcessRecord proc = mProcessesToGc.get(0);
21800            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21801
21802            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21803            long now = SystemClock.uptimeMillis();
21804            if (when < (now+mConstants.GC_TIMEOUT)) {
21805                when = now + mConstants.GC_TIMEOUT;
21806            }
21807            mHandler.sendMessageAtTime(msg, when);
21808        }
21809    }
21810
21811    /**
21812     * Add a process to the array of processes waiting to be GCed.  Keeps the
21813     * list in sorted order by the last GC time.  The process can't already be
21814     * on the list.
21815     */
21816    final void addProcessToGcListLocked(ProcessRecord proc) {
21817        boolean added = false;
21818        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21819            if (mProcessesToGc.get(i).lastRequestedGc <
21820                    proc.lastRequestedGc) {
21821                added = true;
21822                mProcessesToGc.add(i+1, proc);
21823                break;
21824            }
21825        }
21826        if (!added) {
21827            mProcessesToGc.add(0, proc);
21828        }
21829    }
21830
21831    /**
21832     * Set up to ask a process to GC itself.  This will either do it
21833     * immediately, or put it on the list of processes to gc the next
21834     * time things are idle.
21835     */
21836    final void scheduleAppGcLocked(ProcessRecord app) {
21837        long now = SystemClock.uptimeMillis();
21838        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21839            return;
21840        }
21841        if (!mProcessesToGc.contains(app)) {
21842            addProcessToGcListLocked(app);
21843            scheduleAppGcsLocked();
21844        }
21845    }
21846
21847    final void checkExcessivePowerUsageLocked() {
21848        updateCpuStatsNow();
21849
21850        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21851        boolean doCpuKills = true;
21852        if (mLastPowerCheckUptime == 0) {
21853            doCpuKills = false;
21854        }
21855        final long curUptime = SystemClock.uptimeMillis();
21856        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21857        mLastPowerCheckUptime = curUptime;
21858        int i = mLruProcesses.size();
21859        while (i > 0) {
21860            i--;
21861            ProcessRecord app = mLruProcesses.get(i);
21862            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21863                if (app.lastCpuTime <= 0) {
21864                    continue;
21865                }
21866                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21867                if (DEBUG_POWER) {
21868                    StringBuilder sb = new StringBuilder(128);
21869                    sb.append("CPU for ");
21870                    app.toShortString(sb);
21871                    sb.append(": over ");
21872                    TimeUtils.formatDuration(uptimeSince, sb);
21873                    sb.append(" used ");
21874                    TimeUtils.formatDuration(cputimeUsed, sb);
21875                    sb.append(" (");
21876                    sb.append((cputimeUsed*100)/uptimeSince);
21877                    sb.append("%)");
21878                    Slog.i(TAG_POWER, sb.toString());
21879                }
21880                // If the process has used too much CPU over the last duration, the
21881                // user probably doesn't want this, so kill!
21882                if (doCpuKills && uptimeSince > 0) {
21883                    // What is the limit for this process?
21884                    int cpuLimit;
21885                    long checkDur = curUptime - app.whenUnimportant;
21886                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21887                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21888                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21889                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21890                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21891                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21892                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21893                    } else {
21894                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21895                    }
21896                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21897                        synchronized (stats) {
21898                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21899                                    uptimeSince, cputimeUsed);
21900                        }
21901                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
21902                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
21903                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21904                    }
21905                }
21906                app.lastCpuTime = app.curCpuTime;
21907            }
21908        }
21909    }
21910
21911    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21912            long nowElapsed) {
21913        boolean success = true;
21914
21915        if (app.curRawAdj != app.setRawAdj) {
21916            app.setRawAdj = app.curRawAdj;
21917        }
21918
21919        int changes = 0;
21920
21921        if (app.curAdj != app.setAdj) {
21922            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
21923            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
21924                String msg = "Set " + app.pid + " " + app.processName + " adj "
21925                        + app.curAdj + ": " + app.adjType;
21926                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
21927            }
21928            app.setAdj = app.curAdj;
21929            app.verifiedAdj = ProcessList.INVALID_ADJ;
21930        }
21931
21932        if (app.setSchedGroup != app.curSchedGroup) {
21933            int oldSchedGroup = app.setSchedGroup;
21934            app.setSchedGroup = app.curSchedGroup;
21935            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
21936                String msg = "Setting sched group of " + app.processName
21937                        + " to " + app.curSchedGroup;
21938                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
21939            }
21940            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21941                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21942                app.kill(app.waitingToKill, true);
21943                success = false;
21944            } else {
21945                int processGroup;
21946                switch (app.curSchedGroup) {
21947                    case ProcessList.SCHED_GROUP_BACKGROUND:
21948                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21949                        break;
21950                    case ProcessList.SCHED_GROUP_TOP_APP:
21951                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21952                        processGroup = THREAD_GROUP_TOP_APP;
21953                        break;
21954                    default:
21955                        processGroup = THREAD_GROUP_DEFAULT;
21956                        break;
21957                }
21958                long oldId = Binder.clearCallingIdentity();
21959                try {
21960                    setProcessGroup(app.pid, processGroup);
21961                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21962                        // do nothing if we already switched to RT
21963                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21964                            mVrController.onTopProcChangedLocked(app);
21965                            if (mUseFifoUiScheduling) {
21966                                // Switch UI pipeline for app to SCHED_FIFO
21967                                app.savedPriority = Process.getThreadPriority(app.pid);
21968                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
21969                                if (app.renderThreadTid != 0) {
21970                                    scheduleAsFifoPriority(app.renderThreadTid,
21971                                        /* suppressLogs */true);
21972                                    if (DEBUG_OOM_ADJ) {
21973                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
21974                                            app.renderThreadTid + ") to FIFO");
21975                                    }
21976                                } else {
21977                                    if (DEBUG_OOM_ADJ) {
21978                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
21979                                    }
21980                                }
21981                            } else {
21982                                // Boost priority for top app UI and render threads
21983                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
21984                                if (app.renderThreadTid != 0) {
21985                                    try {
21986                                        setThreadPriority(app.renderThreadTid,
21987                                                TOP_APP_PRIORITY_BOOST);
21988                                    } catch (IllegalArgumentException e) {
21989                                        // thread died, ignore
21990                                    }
21991                                }
21992                            }
21993                        }
21994                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21995                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21996                        mVrController.onTopProcChangedLocked(app);
21997                        if (mUseFifoUiScheduling) {
21998                            try {
21999                                // Reset UI pipeline to SCHED_OTHER
22000                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
22001                                setThreadPriority(app.pid, app.savedPriority);
22002                                if (app.renderThreadTid != 0) {
22003                                    setThreadScheduler(app.renderThreadTid,
22004                                        SCHED_OTHER, 0);
22005                                    setThreadPriority(app.renderThreadTid, -4);
22006                                }
22007                            } catch (IllegalArgumentException e) {
22008                                Slog.w(TAG,
22009                                        "Failed to set scheduling policy, thread does not exist:\n"
22010                                                + e);
22011                            } catch (SecurityException e) {
22012                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22013                            }
22014                        } else {
22015                            // Reset priority for top app UI and render threads
22016                            setThreadPriority(app.pid, 0);
22017                            if (app.renderThreadTid != 0) {
22018                                setThreadPriority(app.renderThreadTid, 0);
22019                            }
22020                        }
22021                    }
22022                } catch (Exception e) {
22023                    if (false) {
22024                        Slog.w(TAG, "Failed setting process group of " + app.pid
22025                                + " to " + app.curSchedGroup);
22026                        Slog.w(TAG, "at location", e);
22027                    }
22028                } finally {
22029                    Binder.restoreCallingIdentity(oldId);
22030                }
22031            }
22032        }
22033        if (app.repForegroundActivities != app.foregroundActivities) {
22034            app.repForegroundActivities = app.foregroundActivities;
22035            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22036        }
22037        if (app.repProcState != app.curProcState) {
22038            app.repProcState = app.curProcState;
22039            if (app.thread != null) {
22040                try {
22041                    if (false) {
22042                        //RuntimeException h = new RuntimeException("here");
22043                        Slog.i(TAG, "Sending new process state " + app.repProcState
22044                                + " to " + app /*, h*/);
22045                    }
22046                    app.thread.setProcessState(app.repProcState);
22047                } catch (RemoteException e) {
22048                }
22049            }
22050        }
22051        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22052                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22053            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22054                // Experimental code to more aggressively collect pss while
22055                // running test...  the problem is that this tends to collect
22056                // the data right when a process is transitioning between process
22057                // states, which well tend to give noisy data.
22058                long start = SystemClock.uptimeMillis();
22059                long pss = Debug.getPss(app.pid, mTmpLong, null);
22060                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22061                mPendingPssProcesses.remove(app);
22062                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22063                        + " to " + app.curProcState + ": "
22064                        + (SystemClock.uptimeMillis()-start) + "ms");
22065            }
22066            app.lastStateTime = now;
22067            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22068                    mTestPssMode, isSleepingLocked(), now);
22069            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22070                    + ProcessList.makeProcStateString(app.setProcState) + " to "
22071                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22072                    + (app.nextPssTime-now) + ": " + app);
22073        } else {
22074            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22075                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22076                    mTestPssMode)))) {
22077                requestPssLocked(app, app.setProcState);
22078                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22079                        mTestPssMode, isSleepingLocked(), now);
22080            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22081                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22082        }
22083        if (app.setProcState != app.curProcState) {
22084            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22085                String msg = "Proc state change of " + app.processName
22086                        + " to " + app.curProcState;
22087                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22088            }
22089            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22090            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22091            if (setImportant && !curImportant) {
22092                // This app is no longer something we consider important enough to allow to
22093                // use arbitrary amounts of battery power.  Note
22094                // its current CPU time to later know to kill it if
22095                // it is not behaving well.
22096                app.whenUnimportant = now;
22097                app.lastCpuTime = 0;
22098            }
22099            // Inform UsageStats of important process state change
22100            // Must be called before updating setProcState
22101            maybeUpdateUsageStatsLocked(app, nowElapsed);
22102
22103            app.setProcState = app.curProcState;
22104            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22105                app.notCachedSinceIdle = false;
22106            }
22107            if (!doingAll) {
22108                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22109            } else {
22110                app.procStateChanged = true;
22111            }
22112        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22113                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22114            // For apps that sit around for a long time in the interactive state, we need
22115            // to report this at least once a day so they don't go idle.
22116            maybeUpdateUsageStatsLocked(app, nowElapsed);
22117        }
22118
22119        if (changes != 0) {
22120            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22121                    "Changes in " + app + ": " + changes);
22122            int i = mPendingProcessChanges.size()-1;
22123            ProcessChangeItem item = null;
22124            while (i >= 0) {
22125                item = mPendingProcessChanges.get(i);
22126                if (item.pid == app.pid) {
22127                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22128                            "Re-using existing item: " + item);
22129                    break;
22130                }
22131                i--;
22132            }
22133            if (i < 0) {
22134                // No existing item in pending changes; need a new one.
22135                final int NA = mAvailProcessChanges.size();
22136                if (NA > 0) {
22137                    item = mAvailProcessChanges.remove(NA-1);
22138                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22139                            "Retrieving available item: " + item);
22140                } else {
22141                    item = new ProcessChangeItem();
22142                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22143                            "Allocating new item: " + item);
22144                }
22145                item.changes = 0;
22146                item.pid = app.pid;
22147                item.uid = app.info.uid;
22148                if (mPendingProcessChanges.size() == 0) {
22149                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22150                            "*** Enqueueing dispatch processes changed!");
22151                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22152                }
22153                mPendingProcessChanges.add(item);
22154            }
22155            item.changes |= changes;
22156            item.foregroundActivities = app.repForegroundActivities;
22157            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22158                    "Item " + Integer.toHexString(System.identityHashCode(item))
22159                    + " " + app.toShortString() + ": changes=" + item.changes
22160                    + " foreground=" + item.foregroundActivities
22161                    + " type=" + app.adjType + " source=" + app.adjSource
22162                    + " target=" + app.adjTarget);
22163        }
22164
22165        return success;
22166    }
22167
22168    private boolean isEphemeralLocked(int uid) {
22169        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22170        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22171            return false;
22172        }
22173        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22174                packages[0]);
22175    }
22176
22177    @VisibleForTesting
22178    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22179        final UidRecord.ChangeItem pendingChange;
22180        if (uidRec == null || uidRec.pendingChange == null) {
22181            if (mPendingUidChanges.size() == 0) {
22182                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22183                        "*** Enqueueing dispatch uid changed!");
22184                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22185            }
22186            final int NA = mAvailUidChanges.size();
22187            if (NA > 0) {
22188                pendingChange = mAvailUidChanges.remove(NA-1);
22189                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22190                        "Retrieving available item: " + pendingChange);
22191            } else {
22192                pendingChange = new UidRecord.ChangeItem();
22193                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22194                        "Allocating new item: " + pendingChange);
22195            }
22196            if (uidRec != null) {
22197                uidRec.pendingChange = pendingChange;
22198                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22199                    // If this uid is going away, and we haven't yet reported it is gone,
22200                    // then do so now.
22201                    change |= UidRecord.CHANGE_IDLE;
22202                }
22203            } else if (uid < 0) {
22204                throw new IllegalArgumentException("No UidRecord or uid");
22205            }
22206            pendingChange.uidRecord = uidRec;
22207            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22208            mPendingUidChanges.add(pendingChange);
22209        } else {
22210            pendingChange = uidRec.pendingChange;
22211            // If there is no change in idle or active state, then keep whatever was pending.
22212            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22213                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22214                        | UidRecord.CHANGE_ACTIVE));
22215            }
22216            // If there is no change in cached or uncached state, then keep whatever was pending.
22217            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22218                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22219                        | UidRecord.CHANGE_UNCACHED));
22220            }
22221            // If this is a report of the UID being gone, then we shouldn't keep any previous
22222            // report of it being active or cached.  (That is, a gone uid is never active,
22223            // and never cached.)
22224            if ((change & UidRecord.CHANGE_GONE) != 0) {
22225                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22226                if (!uidRec.idle) {
22227                    // If this uid is going away, and we haven't yet reported it is gone,
22228                    // then do so now.
22229                    change |= UidRecord.CHANGE_IDLE;
22230                }
22231            }
22232        }
22233        pendingChange.change = change;
22234        pendingChange.processState = uidRec != null
22235                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22236        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22237        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22238        if (uidRec != null) {
22239            uidRec.lastReportedChange = change;
22240            uidRec.updateLastDispatchedProcStateSeq(change);
22241        }
22242
22243        // Directly update the power manager, since we sit on top of it and it is critical
22244        // it be kept in sync (so wake locks will be held as soon as appropriate).
22245        if (mLocalPowerManager != null) {
22246            // TO DO: dispatch cached/uncached changes here, so we don't need to report
22247            // all proc state changes.
22248            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22249                mLocalPowerManager.uidActive(pendingChange.uid);
22250            }
22251            if ((change & UidRecord.CHANGE_IDLE) != 0) {
22252                mLocalPowerManager.uidIdle(pendingChange.uid);
22253            }
22254            if ((change & UidRecord.CHANGE_GONE) != 0) {
22255                mLocalPowerManager.uidGone(pendingChange.uid);
22256            } else {
22257                mLocalPowerManager.updateUidProcState(pendingChange.uid,
22258                        pendingChange.processState);
22259            }
22260        }
22261    }
22262
22263    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22264            String authority) {
22265        if (app == null) return;
22266        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22267            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22268            if (userState == null) return;
22269            final long now = SystemClock.elapsedRealtime();
22270            Long lastReported = userState.mProviderLastReportedFg.get(authority);
22271            if (lastReported == null || lastReported < now - 60 * 1000L) {
22272                if (mSystemReady) {
22273                    // Cannot touch the user stats if not system ready
22274                    mUsageStatsService.reportContentProviderUsage(
22275                            authority, providerPkgName, app.userId);
22276                }
22277                userState.mProviderLastReportedFg.put(authority, now);
22278            }
22279        }
22280    }
22281
22282    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22283        if (DEBUG_USAGE_STATS) {
22284            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22285                    + "] state changes: old = " + app.setProcState + ", new = "
22286                    + app.curProcState);
22287        }
22288        if (mUsageStatsService == null) {
22289            return;
22290        }
22291        boolean isInteraction;
22292        // To avoid some abuse patterns, we are going to be careful about what we consider
22293        // to be an app interaction.  Being the top activity doesn't count while the display
22294        // is sleeping, nor do short foreground services.
22295        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22296            isInteraction = true;
22297            app.fgInteractionTime = 0;
22298        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22299            if (app.fgInteractionTime == 0) {
22300                app.fgInteractionTime = nowElapsed;
22301                isInteraction = false;
22302            } else {
22303                isInteraction = nowElapsed > app.fgInteractionTime
22304                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22305            }
22306        } else {
22307            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22308            app.fgInteractionTime = 0;
22309        }
22310        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22311                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22312            app.interactionEventTime = nowElapsed;
22313            String[] packages = app.getPackageList();
22314            if (packages != null) {
22315                for (int i = 0; i < packages.length; i++) {
22316                    mUsageStatsService.reportEvent(packages[i], app.userId,
22317                            UsageEvents.Event.SYSTEM_INTERACTION);
22318                }
22319            }
22320        }
22321        app.reportedInteraction = isInteraction;
22322        if (!isInteraction) {
22323            app.interactionEventTime = 0;
22324        }
22325    }
22326
22327    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22328        if (proc.thread != null) {
22329            if (proc.baseProcessTracker != null) {
22330                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22331            }
22332        }
22333    }
22334
22335    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22336            ProcessRecord TOP_APP, boolean doingAll, long now) {
22337        if (app.thread == null) {
22338            return false;
22339        }
22340
22341        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22342
22343        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22344    }
22345
22346    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22347            boolean oomAdj) {
22348        if (isForeground != proc.foregroundServices) {
22349            proc.foregroundServices = isForeground;
22350            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22351                    proc.info.uid);
22352            if (isForeground) {
22353                if (curProcs == null) {
22354                    curProcs = new ArrayList<ProcessRecord>();
22355                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22356                }
22357                if (!curProcs.contains(proc)) {
22358                    curProcs.add(proc);
22359                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22360                            proc.info.packageName, proc.info.uid);
22361                }
22362            } else {
22363                if (curProcs != null) {
22364                    if (curProcs.remove(proc)) {
22365                        mBatteryStatsService.noteEvent(
22366                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22367                                proc.info.packageName, proc.info.uid);
22368                        if (curProcs.size() <= 0) {
22369                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22370                        }
22371                    }
22372                }
22373            }
22374            if (oomAdj) {
22375                updateOomAdjLocked();
22376            }
22377        }
22378    }
22379
22380    private final ActivityRecord resumedAppLocked() {
22381        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22382        String pkg;
22383        int uid;
22384        if (act != null) {
22385            pkg = act.packageName;
22386            uid = act.info.applicationInfo.uid;
22387        } else {
22388            pkg = null;
22389            uid = -1;
22390        }
22391        // Has the UID or resumed package name changed?
22392        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22393                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22394            if (mCurResumedPackage != null) {
22395                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22396                        mCurResumedPackage, mCurResumedUid);
22397            }
22398            mCurResumedPackage = pkg;
22399            mCurResumedUid = uid;
22400            if (mCurResumedPackage != null) {
22401                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22402                        mCurResumedPackage, mCurResumedUid);
22403            }
22404        }
22405        return act;
22406    }
22407
22408    /**
22409     * Update OomAdj for a specific process.
22410     * @param app The process to update
22411     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22412     *                  if necessary, or skip.
22413     * @return whether updateOomAdjLocked(app) was successful.
22414     */
22415    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22416        final ActivityRecord TOP_ACT = resumedAppLocked();
22417        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22418        final boolean wasCached = app.cached;
22419
22420        mAdjSeq++;
22421
22422        // This is the desired cached adjusment we want to tell it to use.
22423        // If our app is currently cached, we know it, and that is it.  Otherwise,
22424        // we don't know it yet, and it needs to now be cached we will then
22425        // need to do a complete oom adj.
22426        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22427                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22428        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22429                SystemClock.uptimeMillis());
22430        if (oomAdjAll
22431                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22432            // Changed to/from cached state, so apps after it in the LRU
22433            // list may also be changed.
22434            updateOomAdjLocked();
22435        }
22436        return success;
22437    }
22438
22439    final void updateOomAdjLocked() {
22440        final ActivityRecord TOP_ACT = resumedAppLocked();
22441        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22442        final long now = SystemClock.uptimeMillis();
22443        final long nowElapsed = SystemClock.elapsedRealtime();
22444        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22445        final int N = mLruProcesses.size();
22446
22447        if (false) {
22448            RuntimeException e = new RuntimeException();
22449            e.fillInStackTrace();
22450            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22451        }
22452
22453        // Reset state in all uid records.
22454        for (int i=mActiveUids.size()-1; i>=0; i--) {
22455            final UidRecord uidRec = mActiveUids.valueAt(i);
22456            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22457                    "Starting update of " + uidRec);
22458            uidRec.reset();
22459        }
22460
22461        mStackSupervisor.rankTaskLayersIfNeeded();
22462
22463        mAdjSeq++;
22464        mNewNumServiceProcs = 0;
22465        mNewNumAServiceProcs = 0;
22466
22467        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22468        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22469
22470        // Let's determine how many processes we have running vs.
22471        // how many slots we have for background processes; we may want
22472        // to put multiple processes in a slot of there are enough of
22473        // them.
22474        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22475                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22476        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22477        if (numEmptyProcs > cachedProcessLimit) {
22478            // If there are more empty processes than our limit on cached
22479            // processes, then use the cached process limit for the factor.
22480            // This ensures that the really old empty processes get pushed
22481            // down to the bottom, so if we are running low on memory we will
22482            // have a better chance at keeping around more cached processes
22483            // instead of a gazillion empty processes.
22484            numEmptyProcs = cachedProcessLimit;
22485        }
22486        int emptyFactor = numEmptyProcs/numSlots;
22487        if (emptyFactor < 1) emptyFactor = 1;
22488        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22489        if (cachedFactor < 1) cachedFactor = 1;
22490        int stepCached = 0;
22491        int stepEmpty = 0;
22492        int numCached = 0;
22493        int numEmpty = 0;
22494        int numTrimming = 0;
22495
22496        mNumNonCachedProcs = 0;
22497        mNumCachedHiddenProcs = 0;
22498
22499        // First update the OOM adjustment for each of the
22500        // application processes based on their current state.
22501        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22502        int nextCachedAdj = curCachedAdj+1;
22503        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22504        int nextEmptyAdj = curEmptyAdj+2;
22505        for (int i=N-1; i>=0; i--) {
22506            ProcessRecord app = mLruProcesses.get(i);
22507            if (!app.killedByAm && app.thread != null) {
22508                app.procStateChanged = false;
22509                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22510
22511                // If we haven't yet assigned the final cached adj
22512                // to the process, do that now.
22513                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22514                    switch (app.curProcState) {
22515                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22516                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22517                            // This process is a cached process holding activities...
22518                            // assign it the next cached value for that type, and then
22519                            // step that cached level.
22520                            app.curRawAdj = curCachedAdj;
22521                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22522                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22523                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22524                                    + ")");
22525                            if (curCachedAdj != nextCachedAdj) {
22526                                stepCached++;
22527                                if (stepCached >= cachedFactor) {
22528                                    stepCached = 0;
22529                                    curCachedAdj = nextCachedAdj;
22530                                    nextCachedAdj += 2;
22531                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22532                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22533                                    }
22534                                }
22535                            }
22536                            break;
22537                        default:
22538                            // For everything else, assign next empty cached process
22539                            // level and bump that up.  Note that this means that
22540                            // long-running services that have dropped down to the
22541                            // cached level will be treated as empty (since their process
22542                            // state is still as a service), which is what we want.
22543                            app.curRawAdj = curEmptyAdj;
22544                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22545                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22546                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22547                                    + ")");
22548                            if (curEmptyAdj != nextEmptyAdj) {
22549                                stepEmpty++;
22550                                if (stepEmpty >= emptyFactor) {
22551                                    stepEmpty = 0;
22552                                    curEmptyAdj = nextEmptyAdj;
22553                                    nextEmptyAdj += 2;
22554                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22555                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22556                                    }
22557                                }
22558                            }
22559                            break;
22560                    }
22561                }
22562
22563                applyOomAdjLocked(app, true, now, nowElapsed);
22564
22565                // Count the number of process types.
22566                switch (app.curProcState) {
22567                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22568                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22569                        mNumCachedHiddenProcs++;
22570                        numCached++;
22571                        if (numCached > cachedProcessLimit) {
22572                            app.kill("cached #" + numCached, true);
22573                        }
22574                        break;
22575                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22576                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22577                                && app.lastActivityTime < oldTime) {
22578                            app.kill("empty for "
22579                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22580                                    / 1000) + "s", true);
22581                        } else {
22582                            numEmpty++;
22583                            if (numEmpty > emptyProcessLimit) {
22584                                app.kill("empty #" + numEmpty, true);
22585                            }
22586                        }
22587                        break;
22588                    default:
22589                        mNumNonCachedProcs++;
22590                        break;
22591                }
22592
22593                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
22594                    // If this is an isolated process, there are no services
22595                    // running in it, and it's not a special process with a
22596                    // custom entry point, then the process is no longer
22597                    // needed.  We agressively kill these because we can by
22598                    // definition not re-use the same process again, and it is
22599                    // good to avoid having whatever code was running in them
22600                    // left sitting around after no longer needed.
22601                    app.kill("isolated not needed", true);
22602                } else {
22603                    // Keeping this process, update its uid.
22604                    final UidRecord uidRec = app.uidRecord;
22605                    if (uidRec != null) {
22606                        uidRec.ephemeral = app.info.isInstantApp();
22607                        if (uidRec.curProcState > app.curProcState) {
22608                            uidRec.curProcState = app.curProcState;
22609                        }
22610                        if (app.foregroundServices) {
22611                            uidRec.foregroundServices = true;
22612                        }
22613                    }
22614                }
22615
22616                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22617                        && !app.killedByAm) {
22618                    numTrimming++;
22619                }
22620            }
22621        }
22622
22623        incrementProcStateSeqAndNotifyAppsLocked();
22624
22625        mNumServiceProcs = mNewNumServiceProcs;
22626
22627        // Now determine the memory trimming level of background processes.
22628        // Unfortunately we need to start at the back of the list to do this
22629        // properly.  We only do this if the number of background apps we
22630        // are managing to keep around is less than half the maximum we desire;
22631        // if we are keeping a good number around, we'll let them use whatever
22632        // memory they want.
22633        final int numCachedAndEmpty = numCached + numEmpty;
22634        int memFactor;
22635        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22636                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22637            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22638                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22639            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22640                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22641            } else {
22642                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22643            }
22644        } else {
22645            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22646        }
22647        // We always allow the memory level to go up (better).  We only allow it to go
22648        // down if we are in a state where that is allowed, *and* the total number of processes
22649        // has gone down since last time.
22650        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22651                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22652                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22653        if (memFactor > mLastMemoryLevel) {
22654            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22655                memFactor = mLastMemoryLevel;
22656                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22657            }
22658        }
22659        if (memFactor != mLastMemoryLevel) {
22660            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22661        }
22662        mLastMemoryLevel = memFactor;
22663        mLastNumProcesses = mLruProcesses.size();
22664        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22665        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22666        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22667            if (mLowRamStartTime == 0) {
22668                mLowRamStartTime = now;
22669            }
22670            int step = 0;
22671            int fgTrimLevel;
22672            switch (memFactor) {
22673                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22674                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22675                    break;
22676                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22677                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22678                    break;
22679                default:
22680                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22681                    break;
22682            }
22683            int factor = numTrimming/3;
22684            int minFactor = 2;
22685            if (mHomeProcess != null) minFactor++;
22686            if (mPreviousProcess != null) minFactor++;
22687            if (factor < minFactor) factor = minFactor;
22688            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22689            for (int i=N-1; i>=0; i--) {
22690                ProcessRecord app = mLruProcesses.get(i);
22691                if (allChanged || app.procStateChanged) {
22692                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22693                    app.procStateChanged = false;
22694                }
22695                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22696                        && !app.killedByAm) {
22697                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22698                        try {
22699                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22700                                    "Trimming memory of " + app.processName + " to " + curLevel);
22701                            app.thread.scheduleTrimMemory(curLevel);
22702                        } catch (RemoteException e) {
22703                        }
22704                        if (false) {
22705                            // For now we won't do this; our memory trimming seems
22706                            // to be good enough at this point that destroying
22707                            // activities causes more harm than good.
22708                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22709                                    && app != mHomeProcess && app != mPreviousProcess) {
22710                                // Need to do this on its own message because the stack may not
22711                                // be in a consistent state at this point.
22712                                // For these apps we will also finish their activities
22713                                // to help them free memory.
22714                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22715                            }
22716                        }
22717                    }
22718                    app.trimMemoryLevel = curLevel;
22719                    step++;
22720                    if (step >= factor) {
22721                        step = 0;
22722                        switch (curLevel) {
22723                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22724                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22725                                break;
22726                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22727                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22728                                break;
22729                        }
22730                    }
22731                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22732                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22733                            && app.thread != null) {
22734                        try {
22735                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22736                                    "Trimming memory of heavy-weight " + app.processName
22737                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22738                            app.thread.scheduleTrimMemory(
22739                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22740                        } catch (RemoteException e) {
22741                        }
22742                    }
22743                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22744                } else {
22745                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22746                            || app.systemNoUi) && app.pendingUiClean) {
22747                        // If this application is now in the background and it
22748                        // had done UI, then give it the special trim level to
22749                        // have it free UI resources.
22750                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22751                        if (app.trimMemoryLevel < level && app.thread != null) {
22752                            try {
22753                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22754                                        "Trimming memory of bg-ui " + app.processName
22755                                        + " to " + level);
22756                                app.thread.scheduleTrimMemory(level);
22757                            } catch (RemoteException e) {
22758                            }
22759                        }
22760                        app.pendingUiClean = false;
22761                    }
22762                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22763                        try {
22764                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22765                                    "Trimming memory of fg " + app.processName
22766                                    + " to " + fgTrimLevel);
22767                            app.thread.scheduleTrimMemory(fgTrimLevel);
22768                        } catch (RemoteException e) {
22769                        }
22770                    }
22771                    app.trimMemoryLevel = fgTrimLevel;
22772                }
22773            }
22774        } else {
22775            if (mLowRamStartTime != 0) {
22776                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22777                mLowRamStartTime = 0;
22778            }
22779            for (int i=N-1; i>=0; i--) {
22780                ProcessRecord app = mLruProcesses.get(i);
22781                if (allChanged || app.procStateChanged) {
22782                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22783                    app.procStateChanged = false;
22784                }
22785                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22786                        || app.systemNoUi) && app.pendingUiClean) {
22787                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22788                            && app.thread != null) {
22789                        try {
22790                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22791                                    "Trimming memory of ui hidden " + app.processName
22792                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22793                            app.thread.scheduleTrimMemory(
22794                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22795                        } catch (RemoteException e) {
22796                        }
22797                    }
22798                    app.pendingUiClean = false;
22799                }
22800                app.trimMemoryLevel = 0;
22801            }
22802        }
22803
22804        if (mAlwaysFinishActivities) {
22805            // Need to do this on its own message because the stack may not
22806            // be in a consistent state at this point.
22807            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22808        }
22809
22810        if (allChanged) {
22811            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22812        }
22813
22814        ArrayList<UidRecord> becameIdle = null;
22815
22816        // Update from any uid changes.
22817        if (mLocalPowerManager != null) {
22818            mLocalPowerManager.startUidChanges();
22819        }
22820        for (int i=mActiveUids.size()-1; i>=0; i--) {
22821            final UidRecord uidRec = mActiveUids.valueAt(i);
22822            int uidChange = UidRecord.CHANGE_PROCSTATE;
22823            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22824                    && (uidRec.setProcState != uidRec.curProcState
22825                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
22826                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22827                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22828                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22829                        + " to " + uidRec.curWhitelist);
22830                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22831                        && !uidRec.curWhitelist) {
22832                    // UID is now in the background (and not on the temp whitelist).  Was it
22833                    // previously in the foreground (or on the temp whitelist)?
22834                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22835                            || uidRec.setWhitelist) {
22836                        uidRec.lastBackgroundTime = nowElapsed;
22837                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22838                            // Note: the background settle time is in elapsed realtime, while
22839                            // the handler time base is uptime.  All this means is that we may
22840                            // stop background uids later than we had intended, but that only
22841                            // happens because the device was sleeping so we are okay anyway.
22842                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22843                                    mConstants.BACKGROUND_SETTLE_TIME);
22844                        }
22845                    }
22846                    if (uidRec.idle && !uidRec.setIdle) {
22847                        uidChange = UidRecord.CHANGE_IDLE;
22848                        if (becameIdle == null) {
22849                            becameIdle = new ArrayList<>();
22850                        }
22851                        becameIdle.add(uidRec);
22852                    }
22853                } else {
22854                    if (uidRec.idle) {
22855                        uidChange = UidRecord.CHANGE_ACTIVE;
22856                        EventLogTags.writeAmUidActive(uidRec.uid);
22857                        uidRec.idle = false;
22858                    }
22859                    uidRec.lastBackgroundTime = 0;
22860                }
22861                final boolean wasCached = uidRec.setProcState
22862                        > ActivityManager.PROCESS_STATE_RECEIVER;
22863                final boolean isCached = uidRec.curProcState
22864                        > ActivityManager.PROCESS_STATE_RECEIVER;
22865                if (wasCached != isCached ||
22866                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22867                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22868                }
22869                uidRec.setProcState = uidRec.curProcState;
22870                uidRec.setWhitelist = uidRec.curWhitelist;
22871                uidRec.setIdle = uidRec.idle;
22872                enqueueUidChangeLocked(uidRec, -1, uidChange);
22873                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22874                if (uidRec.foregroundServices) {
22875                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
22876                }
22877            }
22878        }
22879        if (mLocalPowerManager != null) {
22880            mLocalPowerManager.finishUidChanges();
22881        }
22882
22883        if (becameIdle != null) {
22884            // If we have any new uids that became idle this time, we need to make sure
22885            // they aren't left with running services.
22886            for (int i = becameIdle.size() - 1; i >= 0; i--) {
22887                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22888            }
22889        }
22890
22891        if (mProcessStats.shouldWriteNowLocked(now)) {
22892            mHandler.post(new Runnable() {
22893                @Override public void run() {
22894                    synchronized (ActivityManagerService.this) {
22895                        mProcessStats.writeStateAsyncLocked();
22896                    }
22897                }
22898            });
22899        }
22900
22901        if (DEBUG_OOM_ADJ) {
22902            final long duration = SystemClock.uptimeMillis() - now;
22903            if (false) {
22904                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22905                        new RuntimeException("here").fillInStackTrace());
22906            } else {
22907                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22908            }
22909        }
22910    }
22911
22912    @Override
22913    public void makePackageIdle(String packageName, int userId) {
22914        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22915                != PackageManager.PERMISSION_GRANTED) {
22916            String msg = "Permission Denial: makePackageIdle() from pid="
22917                    + Binder.getCallingPid()
22918                    + ", uid=" + Binder.getCallingUid()
22919                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22920            Slog.w(TAG, msg);
22921            throw new SecurityException(msg);
22922        }
22923        final int callingPid = Binder.getCallingPid();
22924        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22925                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22926        long callingId = Binder.clearCallingIdentity();
22927        synchronized(this) {
22928            try {
22929                IPackageManager pm = AppGlobals.getPackageManager();
22930                int pkgUid = -1;
22931                try {
22932                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22933                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22934                } catch (RemoteException e) {
22935                }
22936                if (pkgUid == -1) {
22937                    throw new IllegalArgumentException("Unknown package name " + packageName);
22938                }
22939
22940                if (mLocalPowerManager != null) {
22941                    mLocalPowerManager.startUidChanges();
22942                }
22943                final int appId = UserHandle.getAppId(pkgUid);
22944                final int N = mActiveUids.size();
22945                for (int i=N-1; i>=0; i--) {
22946                    final UidRecord uidRec = mActiveUids.valueAt(i);
22947                    final long bgTime = uidRec.lastBackgroundTime;
22948                    if (bgTime > 0 && !uidRec.idle) {
22949                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22950                            if (userId == UserHandle.USER_ALL ||
22951                                    userId == UserHandle.getUserId(uidRec.uid)) {
22952                                EventLogTags.writeAmUidIdle(uidRec.uid);
22953                                uidRec.idle = true;
22954                                uidRec.setIdle = true;
22955                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22956                                        + " from package " + packageName + " user " + userId);
22957                                doStopUidLocked(uidRec.uid, uidRec);
22958                            }
22959                        }
22960                    }
22961                }
22962            } finally {
22963                if (mLocalPowerManager != null) {
22964                    mLocalPowerManager.finishUidChanges();
22965                }
22966                Binder.restoreCallingIdentity(callingId);
22967            }
22968        }
22969    }
22970
22971    final void idleUids() {
22972        synchronized (this) {
22973            final int N = mActiveUids.size();
22974            if (N <= 0) {
22975                return;
22976            }
22977            final long nowElapsed = SystemClock.elapsedRealtime();
22978            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22979            long nextTime = 0;
22980            if (mLocalPowerManager != null) {
22981                mLocalPowerManager.startUidChanges();
22982            }
22983            for (int i=N-1; i>=0; i--) {
22984                final UidRecord uidRec = mActiveUids.valueAt(i);
22985                final long bgTime = uidRec.lastBackgroundTime;
22986                if (bgTime > 0 && !uidRec.idle) {
22987                    if (bgTime <= maxBgTime) {
22988                        EventLogTags.writeAmUidIdle(uidRec.uid);
22989                        uidRec.idle = true;
22990                        uidRec.setIdle = true;
22991                        doStopUidLocked(uidRec.uid, uidRec);
22992                    } else {
22993                        if (nextTime == 0 || nextTime > bgTime) {
22994                            nextTime = bgTime;
22995                        }
22996                    }
22997                }
22998            }
22999            if (mLocalPowerManager != null) {
23000                mLocalPowerManager.finishUidChanges();
23001            }
23002            if (nextTime > 0) {
23003                mHandler.removeMessages(IDLE_UIDS_MSG);
23004                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23005                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23006            }
23007        }
23008    }
23009
23010    /**
23011     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23012     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23013     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23014     */
23015    @VisibleForTesting
23016    @GuardedBy("this")
23017    void incrementProcStateSeqAndNotifyAppsLocked() {
23018        if (mWaitForNetworkTimeoutMs <= 0) {
23019            return;
23020        }
23021        // Used for identifying which uids need to block for network.
23022        ArrayList<Integer> blockingUids = null;
23023        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23024            final UidRecord uidRec = mActiveUids.valueAt(i);
23025            // If the network is not restricted for uid, then nothing to do here.
23026            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23027                continue;
23028            }
23029            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23030                continue;
23031            }
23032            // If process state is not changed, then there's nothing to do.
23033            if (uidRec.setProcState == uidRec.curProcState) {
23034                continue;
23035            }
23036            final int blockState = getBlockStateForUid(uidRec);
23037            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23038            // there's nothing the app needs to do in this scenario.
23039            if (blockState == NETWORK_STATE_NO_CHANGE) {
23040                continue;
23041            }
23042            synchronized (uidRec.networkStateLock) {
23043                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23044                if (blockState == NETWORK_STATE_BLOCK) {
23045                    if (blockingUids == null) {
23046                        blockingUids = new ArrayList<>();
23047                    }
23048                    blockingUids.add(uidRec.uid);
23049                } else {
23050                    if (DEBUG_NETWORK) {
23051                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23052                                + " threads for uid: " + uidRec);
23053                    }
23054                    if (uidRec.waitingForNetwork) {
23055                        uidRec.networkStateLock.notifyAll();
23056                    }
23057                }
23058            }
23059        }
23060
23061        // There are no uids that need to block, so nothing more to do.
23062        if (blockingUids == null) {
23063            return;
23064        }
23065
23066        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23067            final ProcessRecord app = mLruProcesses.get(i);
23068            if (!blockingUids.contains(app.uid)) {
23069                continue;
23070            }
23071            if (!app.killedByAm && app.thread != null) {
23072                final UidRecord uidRec = mActiveUids.get(app.uid);
23073                try {
23074                    if (DEBUG_NETWORK) {
23075                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23076                                + uidRec);
23077                    }
23078                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23079                } catch (RemoteException ignored) {
23080                }
23081            }
23082        }
23083    }
23084
23085    /**
23086     * Checks if the uid is coming from background to foreground or vice versa and returns
23087     * appropriate block state based on this.
23088     *
23089     * @return blockState based on whether the uid is coming from background to foreground or
23090     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23091     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23092     *         {@link #NETWORK_STATE_NO_CHANGE}.
23093     */
23094    @VisibleForTesting
23095    int getBlockStateForUid(UidRecord uidRec) {
23096        // Denotes whether uid's process state is currently allowed network access.
23097        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23098                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23099        // Denotes whether uid's process state was previously allowed network access.
23100        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23101                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23102
23103        // When the uid is coming to foreground, AMS should inform the app thread that it should
23104        // block for the network rules to get updated before launching an activity.
23105        if (!wasAllowed && isAllowed) {
23106            return NETWORK_STATE_BLOCK;
23107        }
23108        // When the uid is going to background, AMS should inform the app thread that if an
23109        // activity launch is blocked for the network rules to get updated, it should be unblocked.
23110        if (wasAllowed && !isAllowed) {
23111            return NETWORK_STATE_UNBLOCK;
23112        }
23113        return NETWORK_STATE_NO_CHANGE;
23114    }
23115
23116    final void runInBackgroundDisabled(int uid) {
23117        synchronized (this) {
23118            UidRecord uidRec = mActiveUids.get(uid);
23119            if (uidRec != null) {
23120                // This uid is actually running...  should it be considered background now?
23121                if (uidRec.idle) {
23122                    doStopUidLocked(uidRec.uid, uidRec);
23123                }
23124            } else {
23125                // This uid isn't actually running...  still send a report about it being "stopped".
23126                doStopUidLocked(uid, null);
23127            }
23128        }
23129    }
23130
23131    final void doStopUidLocked(int uid, final UidRecord uidRec) {
23132        mServices.stopInBackgroundLocked(uid);
23133        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23134    }
23135
23136    /**
23137     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23138     */
23139    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23140            long duration, String tag) {
23141        if (DEBUG_WHITELISTS) {
23142            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23143                    + targetUid + ", " + duration + ")");
23144        }
23145
23146        synchronized (mPidsSelfLocked) {
23147            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23148            if (pr == null) {
23149                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23150                        + callerPid);
23151                return;
23152            }
23153            if (!pr.whitelistManager) {
23154                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23155                        != PackageManager.PERMISSION_GRANTED) {
23156                    if (DEBUG_WHITELISTS) {
23157                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23158                                + ": pid " + callerPid + " is not allowed");
23159                    }
23160                    return;
23161                }
23162            }
23163        }
23164
23165        tempWhitelistUidLocked(targetUid, duration, tag);
23166    }
23167
23168    /**
23169     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23170     */
23171    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23172        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23173        setUidTempWhitelistStateLocked(targetUid, true);
23174        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23175    }
23176
23177    void pushTempWhitelist() {
23178        final int N;
23179        final PendingTempWhitelist[] list;
23180
23181        // First copy out the pending changes...  we need to leave them in the map for now,
23182        // in case someone needs to check what is coming up while we don't have the lock held.
23183        synchronized(this) {
23184            N = mPendingTempWhitelist.size();
23185            list = new PendingTempWhitelist[N];
23186            for (int i = 0; i < N; i++) {
23187                list[i] = mPendingTempWhitelist.valueAt(i);
23188            }
23189        }
23190
23191        // Now safely dispatch changes to device idle controller.
23192        for (int i = 0; i < N; i++) {
23193            PendingTempWhitelist ptw = list[i];
23194            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23195                    ptw.duration, true, ptw.tag);
23196        }
23197
23198        // And now we can safely remove them from the map.
23199        synchronized(this) {
23200            for (int i = 0; i < N; i++) {
23201                PendingTempWhitelist ptw = list[i];
23202                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23203                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23204                    mPendingTempWhitelist.removeAt(index);
23205                }
23206            }
23207        }
23208    }
23209
23210    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23211        boolean changed = false;
23212        for (int i=mActiveUids.size()-1; i>=0; i--) {
23213            final UidRecord uidRec = mActiveUids.valueAt(i);
23214            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23215                uidRec.curWhitelist = onWhitelist;
23216                changed = true;
23217            }
23218        }
23219        if (changed) {
23220            updateOomAdjLocked();
23221        }
23222    }
23223
23224    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23225        boolean changed = false;
23226        final UidRecord uidRec = mActiveUids.get(uid);
23227        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23228            uidRec.curWhitelist = onWhitelist;
23229            updateOomAdjLocked();
23230        }
23231    }
23232
23233    final void trimApplications() {
23234        synchronized (this) {
23235            int i;
23236
23237            // First remove any unused application processes whose package
23238            // has been removed.
23239            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23240                final ProcessRecord app = mRemovedProcesses.get(i);
23241                if (app.activities.size() == 0
23242                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
23243                    Slog.i(
23244                        TAG, "Exiting empty application process "
23245                        + app.toShortString() + " ("
23246                        + (app.thread != null ? app.thread.asBinder() : null)
23247                        + ")\n");
23248                    if (app.pid > 0 && app.pid != MY_PID) {
23249                        app.kill("empty", false);
23250                    } else {
23251                        try {
23252                            app.thread.scheduleExit();
23253                        } catch (Exception e) {
23254                            // Ignore exceptions.
23255                        }
23256                    }
23257                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23258                    mRemovedProcesses.remove(i);
23259
23260                    if (app.persistent) {
23261                        addAppLocked(app.info, null, false, null /* ABI override */);
23262                    }
23263                }
23264            }
23265
23266            // Now update the oom adj for all processes.
23267            updateOomAdjLocked();
23268        }
23269    }
23270
23271    /** This method sends the specified signal to each of the persistent apps */
23272    public void signalPersistentProcesses(int sig) throws RemoteException {
23273        if (sig != SIGNAL_USR1) {
23274            throw new SecurityException("Only SIGNAL_USR1 is allowed");
23275        }
23276
23277        synchronized (this) {
23278            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23279                    != PackageManager.PERMISSION_GRANTED) {
23280                throw new SecurityException("Requires permission "
23281                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23282            }
23283
23284            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23285                ProcessRecord r = mLruProcesses.get(i);
23286                if (r.thread != null && r.persistent) {
23287                    sendSignal(r.pid, sig);
23288                }
23289            }
23290        }
23291    }
23292
23293    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23294        if (proc == null || proc == mProfileProc) {
23295            proc = mProfileProc;
23296            profileType = mProfileType;
23297            clearProfilerLocked();
23298        }
23299        if (proc == null) {
23300            return;
23301        }
23302        try {
23303            proc.thread.profilerControl(false, null, profileType);
23304        } catch (RemoteException e) {
23305            throw new IllegalStateException("Process disappeared");
23306        }
23307    }
23308
23309    private void clearProfilerLocked() {
23310        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23311            try {
23312                mProfilerInfo.profileFd.close();
23313            } catch (IOException e) {
23314            }
23315        }
23316        mProfileApp = null;
23317        mProfileProc = null;
23318        mProfilerInfo = null;
23319    }
23320
23321    public boolean profileControl(String process, int userId, boolean start,
23322            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23323
23324        try {
23325            synchronized (this) {
23326                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23327                // its own permission.
23328                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23329                        != PackageManager.PERMISSION_GRANTED) {
23330                    throw new SecurityException("Requires permission "
23331                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23332                }
23333
23334                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23335                    throw new IllegalArgumentException("null profile info or fd");
23336                }
23337
23338                ProcessRecord proc = null;
23339                if (process != null) {
23340                    proc = findProcessLocked(process, userId, "profileControl");
23341                }
23342
23343                if (start && (proc == null || proc.thread == null)) {
23344                    throw new IllegalArgumentException("Unknown process: " + process);
23345                }
23346
23347                if (start) {
23348                    stopProfilerLocked(null, 0);
23349                    setProfileApp(proc.info, proc.processName, profilerInfo);
23350                    mProfileProc = proc;
23351                    mProfileType = profileType;
23352                    ParcelFileDescriptor fd = profilerInfo.profileFd;
23353                    try {
23354                        fd = fd.dup();
23355                    } catch (IOException e) {
23356                        fd = null;
23357                    }
23358                    profilerInfo.profileFd = fd;
23359                    proc.thread.profilerControl(start, profilerInfo, profileType);
23360                    fd = null;
23361                    try {
23362                        mProfilerInfo.profileFd.close();
23363                    } catch (IOException e) {
23364                    }
23365                    mProfilerInfo.profileFd = null;
23366                } else {
23367                    stopProfilerLocked(proc, profileType);
23368                    if (profilerInfo != null && profilerInfo.profileFd != null) {
23369                        try {
23370                            profilerInfo.profileFd.close();
23371                        } catch (IOException e) {
23372                        }
23373                    }
23374                }
23375
23376                return true;
23377            }
23378        } catch (RemoteException e) {
23379            throw new IllegalStateException("Process disappeared");
23380        } finally {
23381            if (profilerInfo != null && profilerInfo.profileFd != null) {
23382                try {
23383                    profilerInfo.profileFd.close();
23384                } catch (IOException e) {
23385                }
23386            }
23387        }
23388    }
23389
23390    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23391        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23392                userId, true, ALLOW_FULL_ONLY, callName, null);
23393        ProcessRecord proc = null;
23394        try {
23395            int pid = Integer.parseInt(process);
23396            synchronized (mPidsSelfLocked) {
23397                proc = mPidsSelfLocked.get(pid);
23398            }
23399        } catch (NumberFormatException e) {
23400        }
23401
23402        if (proc == null) {
23403            ArrayMap<String, SparseArray<ProcessRecord>> all
23404                    = mProcessNames.getMap();
23405            SparseArray<ProcessRecord> procs = all.get(process);
23406            if (procs != null && procs.size() > 0) {
23407                proc = procs.valueAt(0);
23408                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23409                    for (int i=1; i<procs.size(); i++) {
23410                        ProcessRecord thisProc = procs.valueAt(i);
23411                        if (thisProc.userId == userId) {
23412                            proc = thisProc;
23413                            break;
23414                        }
23415                    }
23416                }
23417            }
23418        }
23419
23420        return proc;
23421    }
23422
23423    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23424            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23425
23426        try {
23427            synchronized (this) {
23428                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23429                // its own permission (same as profileControl).
23430                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23431                        != PackageManager.PERMISSION_GRANTED) {
23432                    throw new SecurityException("Requires permission "
23433                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23434                }
23435
23436                if (fd == null) {
23437                    throw new IllegalArgumentException("null fd");
23438                }
23439
23440                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23441                if (proc == null || proc.thread == null) {
23442                    throw new IllegalArgumentException("Unknown process: " + process);
23443                }
23444
23445                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23446                if (!isDebuggable) {
23447                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23448                        throw new SecurityException("Process not debuggable: " + proc);
23449                    }
23450                }
23451
23452                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23453                fd = null;
23454                return true;
23455            }
23456        } catch (RemoteException e) {
23457            throw new IllegalStateException("Process disappeared");
23458        } finally {
23459            if (fd != null) {
23460                try {
23461                    fd.close();
23462                } catch (IOException e) {
23463                }
23464            }
23465        }
23466    }
23467
23468    @Override
23469    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23470            String reportPackage) {
23471        if (processName != null) {
23472            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23473                    "setDumpHeapDebugLimit()");
23474        } else {
23475            synchronized (mPidsSelfLocked) {
23476                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23477                if (proc == null) {
23478                    throw new SecurityException("No process found for calling pid "
23479                            + Binder.getCallingPid());
23480                }
23481                if (!Build.IS_DEBUGGABLE
23482                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23483                    throw new SecurityException("Not running a debuggable build");
23484                }
23485                processName = proc.processName;
23486                uid = proc.uid;
23487                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23488                    throw new SecurityException("Package " + reportPackage + " is not running in "
23489                            + proc);
23490                }
23491            }
23492        }
23493        synchronized (this) {
23494            if (maxMemSize > 0) {
23495                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23496            } else {
23497                if (uid != 0) {
23498                    mMemWatchProcesses.remove(processName, uid);
23499                } else {
23500                    mMemWatchProcesses.getMap().remove(processName);
23501                }
23502            }
23503        }
23504    }
23505
23506    @Override
23507    public void dumpHeapFinished(String path) {
23508        synchronized (this) {
23509            if (Binder.getCallingPid() != mMemWatchDumpPid) {
23510                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23511                        + " does not match last pid " + mMemWatchDumpPid);
23512                return;
23513            }
23514            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23515                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23516                        + " does not match last path " + mMemWatchDumpFile);
23517                return;
23518            }
23519            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23520            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23521
23522            // Forced gc to clean up the remnant hprof fd.
23523            Runtime.getRuntime().gc();
23524        }
23525    }
23526
23527    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23528    public void monitor() {
23529        synchronized (this) { }
23530    }
23531
23532    void onCoreSettingsChange(Bundle settings) {
23533        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23534            ProcessRecord processRecord = mLruProcesses.get(i);
23535            try {
23536                if (processRecord.thread != null) {
23537                    processRecord.thread.setCoreSettings(settings);
23538                }
23539            } catch (RemoteException re) {
23540                /* ignore */
23541            }
23542        }
23543    }
23544
23545    // Multi-user methods
23546
23547    /**
23548     * Start user, if its not already running, but don't bring it to foreground.
23549     */
23550    @Override
23551    public boolean startUserInBackground(final int userId) {
23552        return mUserController.startUser(userId, /* foreground */ false);
23553    }
23554
23555    @Override
23556    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23557        return mUserController.unlockUser(userId, token, secret, listener);
23558    }
23559
23560    @Override
23561    public boolean switchUser(final int targetUserId) {
23562        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23563        int currentUserId;
23564        UserInfo targetUserInfo;
23565        synchronized (this) {
23566            currentUserId = mUserController.getCurrentUserIdLocked();
23567            targetUserInfo = mUserController.getUserInfo(targetUserId);
23568            if (targetUserId == currentUserId) {
23569                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23570                return true;
23571            }
23572            if (targetUserInfo == null) {
23573                Slog.w(TAG, "No user info for user #" + targetUserId);
23574                return false;
23575            }
23576            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23577                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23578                        + " when device is in demo mode");
23579                return false;
23580            }
23581            if (!targetUserInfo.supportsSwitchTo()) {
23582                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23583                return false;
23584            }
23585            if (targetUserInfo.isManagedProfile()) {
23586                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23587                return false;
23588            }
23589            mUserController.setTargetUserIdLocked(targetUserId);
23590        }
23591        if (mUserController.mUserSwitchUiEnabled) {
23592            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23593            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23594            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23595            mUiHandler.sendMessage(mHandler.obtainMessage(
23596                    START_USER_SWITCH_UI_MSG, userNames));
23597        } else {
23598            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23599            mHandler.sendMessage(mHandler.obtainMessage(
23600                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
23601        }
23602        return true;
23603    }
23604
23605    void scheduleStartProfilesLocked() {
23606        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23607            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23608                    DateUtils.SECOND_IN_MILLIS);
23609        }
23610    }
23611
23612    @Override
23613    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23614        return mUserController.stopUser(userId, force, callback);
23615    }
23616
23617    @Override
23618    public UserInfo getCurrentUser() {
23619        return mUserController.getCurrentUser();
23620    }
23621
23622    String getStartedUserState(int userId) {
23623        synchronized (this) {
23624            final UserState userState = mUserController.getStartedUserStateLocked(userId);
23625            return UserState.stateToString(userState.state);
23626        }
23627    }
23628
23629    @Override
23630    public boolean isUserRunning(int userId, int flags) {
23631        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23632                && checkCallingPermission(INTERACT_ACROSS_USERS)
23633                    != PackageManager.PERMISSION_GRANTED) {
23634            String msg = "Permission Denial: isUserRunning() from pid="
23635                    + Binder.getCallingPid()
23636                    + ", uid=" + Binder.getCallingUid()
23637                    + " requires " + INTERACT_ACROSS_USERS;
23638            Slog.w(TAG, msg);
23639            throw new SecurityException(msg);
23640        }
23641        synchronized (this) {
23642            return mUserController.isUserRunningLocked(userId, flags);
23643        }
23644    }
23645
23646    @Override
23647    public int[] getRunningUserIds() {
23648        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23649                != PackageManager.PERMISSION_GRANTED) {
23650            String msg = "Permission Denial: isUserRunning() from pid="
23651                    + Binder.getCallingPid()
23652                    + ", uid=" + Binder.getCallingUid()
23653                    + " requires " + INTERACT_ACROSS_USERS;
23654            Slog.w(TAG, msg);
23655            throw new SecurityException(msg);
23656        }
23657        synchronized (this) {
23658            return mUserController.getStartedUserArrayLocked();
23659        }
23660    }
23661
23662    @Override
23663    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23664        mUserController.registerUserSwitchObserver(observer, name);
23665    }
23666
23667    @Override
23668    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23669        mUserController.unregisterUserSwitchObserver(observer);
23670    }
23671
23672    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23673        if (info == null) return null;
23674        ApplicationInfo newInfo = new ApplicationInfo(info);
23675        newInfo.initForUser(userId);
23676        return newInfo;
23677    }
23678
23679    public boolean isUserStopped(int userId) {
23680        synchronized (this) {
23681            return mUserController.getStartedUserStateLocked(userId) == null;
23682        }
23683    }
23684
23685    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23686        if (aInfo == null
23687                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23688            return aInfo;
23689        }
23690
23691        ActivityInfo info = new ActivityInfo(aInfo);
23692        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23693        return info;
23694    }
23695
23696    private boolean processSanityChecksLocked(ProcessRecord process) {
23697        if (process == null || process.thread == null) {
23698            return false;
23699        }
23700
23701        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23702        if (!isDebuggable) {
23703            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23704                return false;
23705            }
23706        }
23707
23708        return true;
23709    }
23710
23711    public boolean startBinderTracking() throws RemoteException {
23712        synchronized (this) {
23713            mBinderTransactionTrackingEnabled = true;
23714            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23715            // permission (same as profileControl).
23716            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23717                    != PackageManager.PERMISSION_GRANTED) {
23718                throw new SecurityException("Requires permission "
23719                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23720            }
23721
23722            for (int i = 0; i < mLruProcesses.size(); i++) {
23723                ProcessRecord process = mLruProcesses.get(i);
23724                if (!processSanityChecksLocked(process)) {
23725                    continue;
23726                }
23727                try {
23728                    process.thread.startBinderTracking();
23729                } catch (RemoteException e) {
23730                    Log.v(TAG, "Process disappared");
23731                }
23732            }
23733            return true;
23734        }
23735    }
23736
23737    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23738        try {
23739            synchronized (this) {
23740                mBinderTransactionTrackingEnabled = false;
23741                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23742                // permission (same as profileControl).
23743                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23744                        != PackageManager.PERMISSION_GRANTED) {
23745                    throw new SecurityException("Requires permission "
23746                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23747                }
23748
23749                if (fd == null) {
23750                    throw new IllegalArgumentException("null fd");
23751                }
23752
23753                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23754                pw.println("Binder transaction traces for all processes.\n");
23755                for (ProcessRecord process : mLruProcesses) {
23756                    if (!processSanityChecksLocked(process)) {
23757                        continue;
23758                    }
23759
23760                    pw.println("Traces for process: " + process.processName);
23761                    pw.flush();
23762                    try {
23763                        TransferPipe tp = new TransferPipe();
23764                        try {
23765                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23766                            tp.go(fd.getFileDescriptor());
23767                        } finally {
23768                            tp.kill();
23769                        }
23770                    } catch (IOException e) {
23771                        pw.println("Failure while dumping IPC traces from " + process +
23772                                ".  Exception: " + e);
23773                        pw.flush();
23774                    } catch (RemoteException e) {
23775                        pw.println("Got a RemoteException while dumping IPC traces from " +
23776                                process + ".  Exception: " + e);
23777                        pw.flush();
23778                    }
23779                }
23780                fd = null;
23781                return true;
23782            }
23783        } finally {
23784            if (fd != null) {
23785                try {
23786                    fd.close();
23787                } catch (IOException e) {
23788                }
23789            }
23790        }
23791    }
23792
23793    @VisibleForTesting
23794    final class LocalService extends ActivityManagerInternal {
23795        @Override
23796        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23797                int targetUserId) {
23798            synchronized (ActivityManagerService.this) {
23799                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23800                        targetPkg, intent, null, targetUserId);
23801            }
23802        }
23803
23804        @Override
23805        public String checkContentProviderAccess(String authority, int userId) {
23806            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23807        }
23808
23809        @Override
23810        public void onWakefulnessChanged(int wakefulness) {
23811            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23812        }
23813
23814        @Override
23815        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23816                String processName, String abiOverride, int uid, Runnable crashHandler) {
23817            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23818                    processName, abiOverride, uid, crashHandler);
23819        }
23820
23821        @Override
23822        public SleepToken acquireSleepToken(String tag, int displayId) {
23823            Preconditions.checkNotNull(tag);
23824            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23825        }
23826
23827        @Override
23828        public ComponentName getHomeActivityForUser(int userId) {
23829            synchronized (ActivityManagerService.this) {
23830                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23831                return homeActivity == null ? null : homeActivity.realActivity;
23832            }
23833        }
23834
23835        @Override
23836        public void onUserRemoved(int userId) {
23837            synchronized (ActivityManagerService.this) {
23838                ActivityManagerService.this.onUserStoppedLocked(userId);
23839            }
23840            mBatteryStatsService.onUserRemoved(userId);
23841        }
23842
23843        @Override
23844        public void onLocalVoiceInteractionStarted(IBinder activity,
23845                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23846            synchronized (ActivityManagerService.this) {
23847                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23848                        voiceSession, voiceInteractor);
23849            }
23850        }
23851
23852        @Override
23853        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23854            synchronized (ActivityManagerService.this) {
23855                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23856                        reasons, timestamp);
23857            }
23858        }
23859
23860        @Override
23861        public void notifyAppTransitionFinished() {
23862            synchronized (ActivityManagerService.this) {
23863                mStackSupervisor.notifyAppTransitionDone();
23864            }
23865        }
23866
23867        @Override
23868        public void notifyAppTransitionCancelled() {
23869            synchronized (ActivityManagerService.this) {
23870                mStackSupervisor.notifyAppTransitionDone();
23871            }
23872        }
23873
23874        @Override
23875        public List<IBinder> getTopVisibleActivities() {
23876            synchronized (ActivityManagerService.this) {
23877                return mStackSupervisor.getTopVisibleActivities();
23878            }
23879        }
23880
23881        @Override
23882        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23883            synchronized (ActivityManagerService.this) {
23884                mStackSupervisor.setDockedStackMinimized(minimized);
23885            }
23886        }
23887
23888        @Override
23889        public void killForegroundAppsForUser(int userHandle) {
23890            synchronized (ActivityManagerService.this) {
23891                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23892                final int NP = mProcessNames.getMap().size();
23893                for (int ip = 0; ip < NP; ip++) {
23894                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23895                    final int NA = apps.size();
23896                    for (int ia = 0; ia < NA; ia++) {
23897                        final ProcessRecord app = apps.valueAt(ia);
23898                        if (app.persistent) {
23899                            // We don't kill persistent processes.
23900                            continue;
23901                        }
23902                        if (app.removed) {
23903                            procs.add(app);
23904                        } else if (app.userId == userHandle && app.foregroundActivities) {
23905                            app.removed = true;
23906                            procs.add(app);
23907                        }
23908                    }
23909                }
23910
23911                final int N = procs.size();
23912                for (int i = 0; i < N; i++) {
23913                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
23914                }
23915            }
23916        }
23917
23918        @Override
23919        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23920                long duration) {
23921            if (!(target instanceof PendingIntentRecord)) {
23922                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23923                return;
23924            }
23925            synchronized (ActivityManagerService.this) {
23926                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23927            }
23928        }
23929
23930        @Override
23931        public void setDeviceIdleWhitelist(int[] appids) {
23932            synchronized (ActivityManagerService.this) {
23933                mDeviceIdleWhitelist = appids;
23934            }
23935        }
23936
23937        @Override
23938        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23939            synchronized (ActivityManagerService.this) {
23940                mDeviceIdleTempWhitelist = appids;
23941                setAppIdTempWhitelistStateLocked(changingAppId, adding);
23942            }
23943        }
23944
23945        @Override
23946        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23947                int userId) {
23948            Preconditions.checkNotNull(values, "Configuration must not be null");
23949            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23950            synchronized (ActivityManagerService.this) {
23951                updateConfigurationLocked(values, null, false, true, userId,
23952                        false /* deferResume */);
23953            }
23954        }
23955
23956        @Override
23957        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23958                Bundle bOptions) {
23959            Preconditions.checkNotNull(intents, "intents");
23960            final String[] resolvedTypes = new String[intents.length];
23961            for (int i = 0; i < intents.length; i++) {
23962                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23963            }
23964
23965            // UID of the package on user userId.
23966            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23967            // packageUid may not be initialized.
23968            int packageUid = 0;
23969            try {
23970                packageUid = AppGlobals.getPackageManager().getPackageUid(
23971                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23972            } catch (RemoteException e) {
23973                // Shouldn't happen.
23974            }
23975
23976            synchronized (ActivityManagerService.this) {
23977                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23978                        /*resultTo*/ null, bOptions, userId);
23979            }
23980        }
23981
23982        @Override
23983        public int getUidProcessState(int uid) {
23984            return getUidState(uid);
23985        }
23986
23987        @Override
23988        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23989            synchronized (ActivityManagerService.this) {
23990
23991                // We might change the visibilities here, so prepare an empty app transition which
23992                // might be overridden later if we actually change visibilities.
23993                final boolean wasTransitionSet =
23994                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
23995                if (!wasTransitionSet) {
23996                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
23997                            false /* alwaysKeepCurrent */);
23998                }
23999                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24000
24001                // If there was a transition set already we don't want to interfere with it as we
24002                // might be starting it too early.
24003                if (!wasTransitionSet) {
24004                    mWindowManager.executeAppTransition();
24005                }
24006            }
24007            if (callback != null) {
24008                callback.run();
24009            }
24010        }
24011
24012        @Override
24013        public boolean isSystemReady() {
24014            // no need to synchronize(this) just to read & return the value
24015            return mSystemReady;
24016        }
24017
24018        @Override
24019        public void notifyKeyguardTrustedChanged() {
24020            synchronized (ActivityManagerService.this) {
24021                if (mKeyguardController.isKeyguardShowing()) {
24022                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24023                }
24024            }
24025        }
24026
24027        /**
24028         * Sets if the given pid has an overlay UI or not.
24029         *
24030         * @param pid The pid we are setting overlay UI for.
24031         * @param hasOverlayUi True if the process has overlay UI.
24032         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24033         */
24034        @Override
24035        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24036            synchronized (ActivityManagerService.this) {
24037                final ProcessRecord pr;
24038                synchronized (mPidsSelfLocked) {
24039                    pr = mPidsSelfLocked.get(pid);
24040                    if (pr == null) {
24041                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24042                        return;
24043                    }
24044                }
24045                if (pr.hasOverlayUi == hasOverlayUi) {
24046                    return;
24047                }
24048                pr.hasOverlayUi = hasOverlayUi;
24049                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24050                updateOomAdjLocked(pr, true);
24051            }
24052        }
24053
24054        /**
24055         * Called after the network policy rules are updated by
24056         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24057         * and {@param procStateSeq}.
24058         */
24059        @Override
24060        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24061            if (DEBUG_NETWORK) {
24062                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24063                        + uid + " seq: " + procStateSeq);
24064            }
24065            UidRecord record;
24066            synchronized (ActivityManagerService.this) {
24067                record = mActiveUids.get(uid);
24068                if (record == null) {
24069                    if (DEBUG_NETWORK) {
24070                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24071                                + " procStateSeq: " + procStateSeq);
24072                    }
24073                    return;
24074                }
24075            }
24076            synchronized (record.networkStateLock) {
24077                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24078                    if (DEBUG_NETWORK) {
24079                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24080                                + " been handled for uid: " + uid);
24081                    }
24082                    return;
24083                }
24084                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24085                if (record.curProcStateSeq > procStateSeq) {
24086                    if (DEBUG_NETWORK) {
24087                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24088                                + ", curProcstateSeq: " + record.curProcStateSeq
24089                                + ", procStateSeq: " + procStateSeq);
24090                    }
24091                    return;
24092                }
24093                if (record.waitingForNetwork) {
24094                    if (DEBUG_NETWORK) {
24095                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24096                                + ", procStateSeq: " + procStateSeq);
24097                    }
24098                    record.networkStateLock.notifyAll();
24099                }
24100            }
24101        }
24102
24103        /**
24104         * Called after virtual display Id is updated by
24105         * {@link com.android.server.vr.Vr2dDisplay} with a specific
24106         * {@param vrVr2dDisplayId}.
24107         */
24108        @Override
24109        public void setVr2dDisplayId(int vr2dDisplayId) {
24110            if (DEBUG_STACK) {
24111                Slog.d(TAG, "setVr2dDisplayId called for: " +
24112                        vr2dDisplayId);
24113            }
24114            synchronized (ActivityManagerService.this) {
24115                mVr2dDisplayId = vr2dDisplayId;
24116            }
24117        }
24118
24119        @Override
24120        public void saveANRState(String reason) {
24121            synchronized (ActivityManagerService.this) {
24122                final StringWriter sw = new StringWriter();
24123                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24124                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24125                if (reason != null) {
24126                    pw.println("  Reason: " + reason);
24127                }
24128                pw.println();
24129                mActivityStarter.dump(pw, "  ", null);
24130                pw.println();
24131                pw.println("-------------------------------------------------------------------------------");
24132                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24133                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24134                        "" /* header */);
24135                pw.println();
24136                pw.close();
24137
24138                mLastANRState = sw.toString();
24139            }
24140        }
24141
24142        @Override
24143        public void clearSavedANRState() {
24144            synchronized (ActivityManagerService.this) {
24145                mLastANRState = null;
24146            }
24147        }
24148
24149        @Override
24150        public void setFocusedActivity(IBinder token) {
24151            synchronized (ActivityManagerService.this) {
24152                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24153                if (r == null) {
24154                    throw new IllegalArgumentException(
24155                            "setFocusedActivity: No activity record matching token=" + token);
24156                }
24157                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24158                        r, "setFocusedActivity")) {
24159                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
24160                }
24161            }
24162        }
24163    }
24164
24165    /**
24166     * Called by app main thread to wait for the network policy rules to get updated.
24167     *
24168     * @param procStateSeq The sequence number indicating the process state change that the main
24169     *                     thread is interested in.
24170     */
24171    @Override
24172    public void waitForNetworkStateUpdate(long procStateSeq) {
24173        final int callingUid = Binder.getCallingUid();
24174        if (DEBUG_NETWORK) {
24175            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24176        }
24177        UidRecord record;
24178        synchronized (this) {
24179            record = mActiveUids.get(callingUid);
24180            if (record == null) {
24181                return;
24182            }
24183        }
24184        synchronized (record.networkStateLock) {
24185            if (record.lastDispatchedProcStateSeq < procStateSeq) {
24186                if (DEBUG_NETWORK) {
24187                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24188                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24189                            + " lastProcStateSeqDispatchedToObservers: "
24190                            + record.lastDispatchedProcStateSeq);
24191                }
24192                return;
24193            }
24194            if (record.curProcStateSeq > procStateSeq) {
24195                if (DEBUG_NETWORK) {
24196                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24197                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24198                            + ", procStateSeq: " + procStateSeq);
24199                }
24200                return;
24201            }
24202            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24203                if (DEBUG_NETWORK) {
24204                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24205                            + procStateSeq + ", so no need to wait. Uid: "
24206                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24207                            + record.lastNetworkUpdatedProcStateSeq);
24208                }
24209                return;
24210            }
24211            try {
24212                if (DEBUG_NETWORK) {
24213                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24214                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24215                }
24216                final long startTime = SystemClock.uptimeMillis();
24217                record.waitingForNetwork = true;
24218                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24219                record.waitingForNetwork = false;
24220                final long totalTime = SystemClock.uptimeMillis() - startTime;
24221                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24222                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24223                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24224                            + procStateSeq + " UidRec: " + record
24225                            + " validateUidRec: " + mValidateUids.get(callingUid));
24226                }
24227            } catch (InterruptedException e) {
24228                Thread.currentThread().interrupt();
24229            }
24230        }
24231    }
24232
24233    public void waitForBroadcastIdle(PrintWriter pw) {
24234        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24235        while (true) {
24236            boolean idle = true;
24237            synchronized (this) {
24238                for (BroadcastQueue queue : mBroadcastQueues) {
24239                    if (!queue.isIdle()) {
24240                        final String msg = "Waiting for queue " + queue + " to become idle...";
24241                        pw.println(msg);
24242                        pw.flush();
24243                        Slog.v(TAG, msg);
24244                        idle = false;
24245                    }
24246                }
24247            }
24248
24249            if (idle) {
24250                final String msg = "All broadcast queues are idle!";
24251                pw.println(msg);
24252                pw.flush();
24253                Slog.v(TAG, msg);
24254                return;
24255            } else {
24256                SystemClock.sleep(1000);
24257            }
24258        }
24259    }
24260
24261    /**
24262     * Return the user id of the last resumed activity.
24263     */
24264    @Override
24265    public @UserIdInt int getLastResumedActivityUserId() {
24266        enforceCallingPermission(
24267                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24268        synchronized (this) {
24269            if (mLastResumedActivity == null) {
24270                return mUserController.getCurrentUserIdLocked();
24271            }
24272            return mLastResumedActivity.userId;
24273        }
24274    }
24275
24276    /**
24277     * An implementation of IAppTask, that allows an app to manage its own tasks via
24278     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24279     * only the process that calls getAppTasks() can call the AppTask methods.
24280     */
24281    class AppTaskImpl extends IAppTask.Stub {
24282        private int mTaskId;
24283        private int mCallingUid;
24284
24285        public AppTaskImpl(int taskId, int callingUid) {
24286            mTaskId = taskId;
24287            mCallingUid = callingUid;
24288        }
24289
24290        private void checkCaller() {
24291            if (mCallingUid != Binder.getCallingUid()) {
24292                throw new SecurityException("Caller " + mCallingUid
24293                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24294            }
24295        }
24296
24297        @Override
24298        public void finishAndRemoveTask() {
24299            checkCaller();
24300
24301            synchronized (ActivityManagerService.this) {
24302                long origId = Binder.clearCallingIdentity();
24303                try {
24304                    // We remove the task from recents to preserve backwards
24305                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24306                            REMOVE_FROM_RECENTS)) {
24307                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24308                    }
24309                } finally {
24310                    Binder.restoreCallingIdentity(origId);
24311                }
24312            }
24313        }
24314
24315        @Override
24316        public ActivityManager.RecentTaskInfo getTaskInfo() {
24317            checkCaller();
24318
24319            synchronized (ActivityManagerService.this) {
24320                long origId = Binder.clearCallingIdentity();
24321                try {
24322                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24323                    if (tr == null) {
24324                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24325                    }
24326                    return createRecentTaskInfoFromTaskRecord(tr);
24327                } finally {
24328                    Binder.restoreCallingIdentity(origId);
24329                }
24330            }
24331        }
24332
24333        @Override
24334        public void moveToFront() {
24335            checkCaller();
24336            // Will bring task to front if it already has a root activity.
24337            final long origId = Binder.clearCallingIdentity();
24338            try {
24339                synchronized (this) {
24340                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24341                }
24342            } finally {
24343                Binder.restoreCallingIdentity(origId);
24344            }
24345        }
24346
24347        @Override
24348        public int startActivity(IBinder whoThread, String callingPackage,
24349                Intent intent, String resolvedType, Bundle bOptions) {
24350            checkCaller();
24351
24352            int callingUser = UserHandle.getCallingUserId();
24353            TaskRecord tr;
24354            IApplicationThread appThread;
24355            synchronized (ActivityManagerService.this) {
24356                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24357                if (tr == null) {
24358                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24359                }
24360                appThread = IApplicationThread.Stub.asInterface(whoThread);
24361                if (appThread == null) {
24362                    throw new IllegalArgumentException("Bad app thread " + appThread);
24363                }
24364            }
24365            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24366                    resolvedType, null, null, null, null, 0, 0, null, null,
24367                    null, bOptions, false, callingUser, tr, "AppTaskImpl");
24368        }
24369
24370        @Override
24371        public void setExcludeFromRecents(boolean exclude) {
24372            checkCaller();
24373
24374            synchronized (ActivityManagerService.this) {
24375                long origId = Binder.clearCallingIdentity();
24376                try {
24377                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24378                    if (tr == null) {
24379                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24380                    }
24381                    Intent intent = tr.getBaseIntent();
24382                    if (exclude) {
24383                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24384                    } else {
24385                        intent.setFlags(intent.getFlags()
24386                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24387                    }
24388                } finally {
24389                    Binder.restoreCallingIdentity(origId);
24390                }
24391            }
24392        }
24393    }
24394
24395    /**
24396     * Kill processes for the user with id userId and that depend on the package named packageName
24397     */
24398    @Override
24399    public void killPackageDependents(String packageName, int userId) {
24400        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24401        if (packageName == null) {
24402            throw new NullPointerException(
24403                    "Cannot kill the dependents of a package without its name.");
24404        }
24405
24406        long callingId = Binder.clearCallingIdentity();
24407        IPackageManager pm = AppGlobals.getPackageManager();
24408        int pkgUid = -1;
24409        try {
24410            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24411        } catch (RemoteException e) {
24412        }
24413        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24414            throw new IllegalArgumentException(
24415                    "Cannot kill dependents of non-existing package " + packageName);
24416        }
24417        try {
24418            synchronized(this) {
24419                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24420                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24421                        "dep: " + packageName);
24422            }
24423        } finally {
24424            Binder.restoreCallingIdentity(callingId);
24425        }
24426    }
24427
24428    @Override
24429    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24430            throws RemoteException {
24431        final long callingId = Binder.clearCallingIdentity();
24432        try {
24433            mKeyguardController.dismissKeyguard(token, callback);
24434        } finally {
24435            Binder.restoreCallingIdentity(callingId);
24436        }
24437    }
24438
24439    @Override
24440    public int restartUserInBackground(final int userId) {
24441        return mUserController.restartUser(userId, /* foreground */ false);
24442    }
24443
24444    @Override
24445    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24446        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24447                "scheduleApplicationInfoChanged()");
24448
24449        synchronized (this) {
24450            final long origId = Binder.clearCallingIdentity();
24451            try {
24452                updateApplicationInfoLocked(packageNames, userId);
24453            } finally {
24454                Binder.restoreCallingIdentity(origId);
24455            }
24456        }
24457    }
24458
24459    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24460        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24461        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24462            final ProcessRecord app = mLruProcesses.get(i);
24463            if (app.thread == null) {
24464                continue;
24465            }
24466
24467            if (userId != UserHandle.USER_ALL && app.userId != userId) {
24468                continue;
24469            }
24470
24471            final int packageCount = app.pkgList.size();
24472            for (int j = 0; j < packageCount; j++) {
24473                final String packageName = app.pkgList.keyAt(j);
24474                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24475                    try {
24476                        final ApplicationInfo ai = AppGlobals.getPackageManager()
24477                                .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
24478                        if (ai != null) {
24479                            app.thread.scheduleApplicationInfoChanged(ai);
24480                        }
24481                    } catch (RemoteException e) {
24482                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24483                                    packageName, app));
24484                    }
24485                }
24486            }
24487        }
24488    }
24489
24490    /**
24491     * Attach an agent to the specified process (proces name or PID)
24492     */
24493    public void attachAgent(String process, String path) {
24494        try {
24495            synchronized (this) {
24496                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24497                if (proc == null || proc.thread == null) {
24498                    throw new IllegalArgumentException("Unknown process: " + process);
24499                }
24500
24501                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24502                if (!isDebuggable) {
24503                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24504                        throw new SecurityException("Process not debuggable: " + proc);
24505                    }
24506                }
24507
24508                proc.thread.attachAgent(path);
24509            }
24510        } catch (RemoteException e) {
24511            throw new IllegalStateException("Process disappeared");
24512        }
24513    }
24514
24515    @VisibleForTesting
24516    public static class Injector {
24517        private NetworkManagementInternal mNmi;
24518
24519        public Context getContext() {
24520            return null;
24521        }
24522
24523        public AppOpsService getAppOpsService(File file, Handler handler) {
24524            return new AppOpsService(file, handler);
24525        }
24526
24527        public Handler getUiHandler(ActivityManagerService service) {
24528            return service.new UiHandler();
24529        }
24530
24531        public boolean isNetworkRestrictedForUid(int uid) {
24532            if (ensureHasNetworkManagementInternal()) {
24533                return mNmi.isNetworkRestrictedForUid(uid);
24534            }
24535            return false;
24536        }
24537
24538        private boolean ensureHasNetworkManagementInternal() {
24539            if (mNmi == null) {
24540                mNmi = LocalServices.getService(NetworkManagementInternal.class);
24541            }
24542            return mNmi != null;
24543        }
24544    }
24545
24546    @Override
24547    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24548            throws RemoteException {
24549        synchronized (this) {
24550            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24551            if (r == null) {
24552                return;
24553            }
24554            final long origId = Binder.clearCallingIdentity();
24555            try {
24556                r.setShowWhenLocked(showWhenLocked);
24557            } finally {
24558                Binder.restoreCallingIdentity(origId);
24559            }
24560        }
24561    }
24562
24563    @Override
24564    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24565        synchronized (this) {
24566            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24567            if (r == null) {
24568                return;
24569            }
24570            final long origId = Binder.clearCallingIdentity();
24571            try {
24572                r.setTurnScreenOn(turnScreenOn);
24573            } finally {
24574                Binder.restoreCallingIdentity(origId);
24575            }
24576        }
24577    }
24578}
24579