ActivityManagerService.java revision 13df994243994a38d0ca80b98f325a59cab114a1
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.MANAGE_ACTIVITY_STACKS;
24import static android.Manifest.permission.READ_FRAME_BUFFER;
25import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
26import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
27import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
28import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
29import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
30import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
31import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
32import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
33import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
34import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
35import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
36import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
37import static android.content.pm.PackageManager.GET_PROVIDERS;
38import static android.content.pm.PackageManager.MATCH_ANY_USER;
39import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
40import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
41import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
42import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
43import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
44import static android.content.pm.PackageManager.PERMISSION_GRANTED;
45import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
46import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
47import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
48import static android.os.Build.VERSION_CODES.N;
49import static android.os.Process.BLUETOOTH_UID;
50import static android.os.Process.FIRST_APPLICATION_UID;
51import static android.os.Process.FIRST_ISOLATED_UID;
52import static android.os.Process.LAST_ISOLATED_UID;
53import static android.os.Process.NFC_UID;
54import static android.os.Process.PHONE_UID;
55import static android.os.Process.PROC_CHAR;
56import static android.os.Process.PROC_OUT_LONG;
57import static android.os.Process.PROC_PARENS;
58import static android.os.Process.PROC_SPACE_TERM;
59import static android.os.Process.ProcessStartResult;
60import static android.os.Process.ROOT_UID;
61import static android.os.Process.SCHED_FIFO;
62import static android.os.Process.SCHED_OTHER;
63import static android.os.Process.SCHED_RESET_ON_FORK;
64import static android.os.Process.SHELL_UID;
65import static android.os.Process.SIGNAL_QUIT;
66import static android.os.Process.SIGNAL_USR1;
67import static android.os.Process.SYSTEM_UID;
68import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
69import static android.os.Process.THREAD_GROUP_DEFAULT;
70import static android.os.Process.THREAD_GROUP_TOP_APP;
71import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
72import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
73import static android.os.Process.getFreeMemory;
74import static android.os.Process.getTotalMemory;
75import static android.os.Process.isThreadInProcess;
76import static android.os.Process.killProcess;
77import static android.os.Process.killProcessQuiet;
78import static android.os.Process.myPid;
79import static android.os.Process.myUid;
80import static android.os.Process.readProcFile;
81import static android.os.Process.removeAllProcessGroups;
82import static android.os.Process.sendSignal;
83import static android.os.Process.setProcessGroup;
84import static android.os.Process.setThreadPriority;
85import static android.os.Process.setThreadScheduler;
86import static android.os.Process.startWebView;
87import static android.os.Process.zygoteProcess;
88import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
89import static android.provider.Settings.Global.DEBUG_APP;
90import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
91import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
92import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
93import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
94import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
95import static android.provider.Settings.System.FONT_SCALE;
96import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
97import static android.view.Display.DEFAULT_DISPLAY;
98import static android.view.Display.INVALID_DISPLAY;
99import static com.android.internal.util.XmlUtils.readBooleanAttribute;
100import static com.android.internal.util.XmlUtils.readIntAttribute;
101import static com.android.internal.util.XmlUtils.readLongAttribute;
102import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
103import static com.android.internal.util.XmlUtils.writeIntAttribute;
104import static com.android.internal.util.XmlUtils.writeLongAttribute;
105import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
106import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
107import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
108import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
109import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
110import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
111import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
112import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
113import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
114import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
115import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
116import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
117import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
118import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
119import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
120import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
121import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
122import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
123import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
124import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
125import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
126import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
127import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
139import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
140import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
141import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
152import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
153import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
154import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
155import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
156import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
157import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
158import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
159import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
160import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
161import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
162import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
163import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
164import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
165import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
166import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
167import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
168import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
169import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
170import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
171import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
172import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
173import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
174import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
175import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
176import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
177import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
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.ActivityManager.TaskThumbnailInfo;
201import android.app.ActivityManagerInternal;
202import android.app.ActivityManagerInternal.SleepToken;
203import android.app.ActivityOptions;
204import android.app.ActivityThread;
205import android.app.AlertDialog;
206import android.app.AppGlobals;
207import android.app.AppOpsManager;
208import android.app.ApplicationErrorReport;
209import android.app.ApplicationThreadConstants;
210import android.app.BroadcastOptions;
211import android.app.ContentProviderHolder;
212import android.app.Dialog;
213import android.app.IActivityContainer;
214import android.app.IActivityContainerCallback;
215import android.app.IActivityController;
216import android.app.IActivityManager;
217import android.app.IAppTask;
218import android.app.IApplicationThread;
219import android.app.IInstrumentationWatcher;
220import android.app.INotificationManager;
221import android.app.IProcessObserver;
222import android.app.IServiceConnection;
223import android.app.IStopUserCallback;
224import android.app.ITaskStackListener;
225import android.app.IUiAutomationConnection;
226import android.app.IUidObserver;
227import android.app.IUserSwitchObserver;
228import android.app.Instrumentation;
229import android.app.Notification;
230import android.app.NotificationManager;
231import android.app.PendingIntent;
232import android.app.PictureInPictureParams;
233import android.app.ProfilerInfo;
234import android.app.RemoteAction;
235import android.app.WaitResult;
236import android.app.admin.DevicePolicyManager;
237import android.app.assist.AssistContent;
238import android.app.assist.AssistStructure;
239import android.app.backup.IBackupManager;
240import android.app.usage.UsageEvents;
241import android.app.usage.UsageStatsManagerInternal;
242import android.appwidget.AppWidgetManager;
243import android.content.ActivityNotFoundException;
244import android.content.BroadcastReceiver;
245import android.content.ClipData;
246import android.content.ComponentCallbacks2;
247import android.content.ComponentName;
248import android.content.ContentProvider;
249import android.content.ContentResolver;
250import android.content.Context;
251import android.content.DialogInterface;
252import android.content.IContentProvider;
253import android.content.IIntentReceiver;
254import android.content.IIntentSender;
255import android.content.Intent;
256import android.content.IntentFilter;
257import android.content.IntentSender;
258import android.content.pm.ActivityInfo;
259import android.content.pm.ApplicationInfo;
260import android.content.pm.ConfigurationInfo;
261import android.content.pm.IPackageDataObserver;
262import android.content.pm.IPackageManager;
263import android.content.pm.InstrumentationInfo;
264import android.content.pm.PackageInfo;
265import android.content.pm.PackageManager;
266import android.content.pm.PackageManager.NameNotFoundException;
267import android.content.pm.PackageManagerInternal;
268import android.content.pm.ParceledListSlice;
269import android.content.pm.PathPermission;
270import android.content.pm.PermissionInfo;
271import android.content.pm.ProviderInfo;
272import android.content.pm.ResolveInfo;
273import android.content.pm.SELinuxUtil;
274import android.content.pm.ServiceInfo;
275import android.content.pm.UserInfo;
276import android.content.res.CompatibilityInfo;
277import android.content.res.Configuration;
278import android.content.res.Resources;
279import android.database.ContentObserver;
280import android.graphics.Bitmap;
281import android.graphics.Point;
282import android.graphics.Rect;
283import android.location.LocationManager;
284import android.media.audiofx.AudioEffect;
285import android.metrics.LogMaker;
286import android.net.Proxy;
287import android.net.ProxyInfo;
288import android.net.Uri;
289import android.os.BatteryStats;
290import android.os.Binder;
291import android.os.Build;
292import android.os.Bundle;
293import android.os.Debug;
294import android.os.DropBoxManager;
295import android.os.Environment;
296import android.os.FactoryTest;
297import android.os.FileObserver;
298import android.os.FileUtils;
299import android.os.Handler;
300import android.os.IBinder;
301import android.os.IDeviceIdentifiersPolicyService;
302import android.os.IPermissionController;
303import android.os.IProcessInfoService;
304import android.os.IProgressListener;
305import android.os.LocaleList;
306import android.os.Looper;
307import android.os.Message;
308import android.os.Parcel;
309import android.os.ParcelFileDescriptor;
310import android.os.PersistableBundle;
311import android.os.PowerManager;
312import android.os.PowerManagerInternal;
313import android.os.Process;
314import android.os.RemoteCallbackList;
315import android.os.RemoteException;
316import android.os.ResultReceiver;
317import android.os.ServiceManager;
318import android.os.ShellCallback;
319import android.os.StrictMode;
320import android.os.SystemClock;
321import android.os.SystemProperties;
322import android.os.Trace;
323import android.os.TransactionTooLargeException;
324import android.os.UpdateLock;
325import android.os.UserHandle;
326import android.os.UserManager;
327import android.os.WorkSource;
328import android.os.storage.IStorageManager;
329import android.os.storage.StorageManager;
330import android.os.storage.StorageManagerInternal;
331import android.provider.Downloads;
332import android.provider.Settings;
333import android.service.voice.IVoiceInteractionSession;
334import android.service.voice.VoiceInteractionManagerInternal;
335import android.service.voice.VoiceInteractionSession;
336import android.telecom.TelecomManager;
337import android.text.TextUtils;
338import android.text.format.DateUtils;
339import android.text.format.Time;
340import android.text.style.SuggestionSpan;
341import android.util.ArrayMap;
342import android.util.ArraySet;
343import android.util.AtomicFile;
344import android.util.BootTimingsTraceLog;
345import android.util.DebugUtils;
346import android.util.DisplayMetrics;
347import android.util.EventLog;
348import android.util.Log;
349import android.util.Pair;
350import android.util.PrintWriterPrinter;
351import android.util.Slog;
352import android.util.SparseArray;
353import android.util.SparseIntArray;
354import android.util.TimeUtils;
355import android.util.Xml;
356import android.view.Gravity;
357import android.view.LayoutInflater;
358import android.view.View;
359import android.view.WindowManager;
360
361import com.android.server.job.JobSchedulerInternal;
362import com.google.android.collect.Lists;
363import com.google.android.collect.Maps;
364
365import com.android.internal.R;
366import com.android.internal.annotations.GuardedBy;
367import com.android.internal.annotations.VisibleForTesting;
368import com.android.internal.app.AssistUtils;
369import com.android.internal.app.DumpHeapActivity;
370import com.android.internal.app.IAppOpsCallback;
371import com.android.internal.app.IAppOpsService;
372import com.android.internal.app.IVoiceInteractor;
373import com.android.internal.app.ProcessMap;
374import com.android.internal.app.SystemUserHomeActivity;
375import com.android.internal.app.procstats.ProcessStats;
376import com.android.internal.logging.MetricsLogger;
377import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
378import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
379import com.android.internal.notification.SystemNotificationChannels;
380import com.android.internal.os.BackgroundThread;
381import com.android.internal.os.BatteryStatsImpl;
382import com.android.internal.os.IResultReceiver;
383import com.android.internal.os.ProcessCpuTracker;
384import com.android.internal.os.TransferPipe;
385import com.android.internal.os.Zygote;
386import com.android.internal.policy.IKeyguardDismissCallback;
387import com.android.internal.telephony.TelephonyIntents;
388import com.android.internal.util.ArrayUtils;
389import com.android.internal.util.DumpUtils;
390import com.android.internal.util.FastPrintWriter;
391import com.android.internal.util.FastXmlSerializer;
392import com.android.internal.util.MemInfoReader;
393import com.android.internal.util.Preconditions;
394import com.android.server.AppOpsService;
395import com.android.server.AttributeCache;
396import com.android.server.DeviceIdleController;
397import com.android.server.IntentResolver;
398import com.android.server.LocalServices;
399import com.android.server.LockGuard;
400import com.android.server.NetworkManagementInternal;
401import com.android.server.RescueParty;
402import com.android.server.ServiceThread;
403import com.android.server.SystemConfig;
404import com.android.server.SystemService;
405import com.android.server.SystemServiceManager;
406import com.android.server.ThreadPriorityBooster;
407import com.android.server.Watchdog;
408import com.android.server.am.ActivityStack.ActivityState;
409import com.android.server.firewall.IntentFirewall;
410import com.android.server.pm.Installer;
411import com.android.server.pm.Installer.InstallerException;
412import com.android.server.statusbar.StatusBarManagerInternal;
413import com.android.server.vr.VrManagerInternal;
414import com.android.server.wm.PinnedStackWindowController;
415import com.android.server.wm.WindowManagerService;
416
417import org.xmlpull.v1.XmlPullParser;
418import org.xmlpull.v1.XmlPullParserException;
419import org.xmlpull.v1.XmlSerializer;
420
421import java.io.File;
422import java.io.FileDescriptor;
423import java.io.FileInputStream;
424import java.io.FileNotFoundException;
425import java.io.FileOutputStream;
426import java.io.IOException;
427import java.io.InputStreamReader;
428import java.io.PrintWriter;
429import java.io.StringWriter;
430import java.io.UnsupportedEncodingException;
431import java.lang.ref.WeakReference;
432import java.nio.charset.StandardCharsets;
433import java.text.DateFormat;
434import java.util.ArrayList;
435import java.util.Arrays;
436import java.util.Collections;
437import java.util.Comparator;
438import java.util.Date;
439import java.util.HashMap;
440import java.util.HashSet;
441import java.util.Iterator;
442import java.util.List;
443import java.util.Locale;
444import java.util.Map;
445import java.util.Objects;
446import java.util.Set;
447import java.util.concurrent.CountDownLatch;
448import java.util.concurrent.atomic.AtomicBoolean;
449import java.util.concurrent.atomic.AtomicLong;
450
451import dalvik.system.VMRuntime;
452import libcore.io.IoUtils;
453import libcore.util.EmptyArray;
454
455public class ActivityManagerService extends IActivityManager.Stub
456        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
457
458    /**
459     * Priority we boost main thread and RT of top app to.
460     */
461    public static final int TOP_APP_PRIORITY_BOOST = -10;
462
463    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
464    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
465    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
466    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
467    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
468    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
469    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
470    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
471    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
472    private static final String TAG_LRU = TAG + POSTFIX_LRU;
473    private static final String TAG_MU = TAG + POSTFIX_MU;
474    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
475    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
476    private static final String TAG_POWER = TAG + POSTFIX_POWER;
477    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
478    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
479    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
480    private static final String TAG_PSS = TAG + POSTFIX_PSS;
481    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
482    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
483    private static final String TAG_STACK = TAG + POSTFIX_STACK;
484    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
485    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
486    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
487    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
488    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
489
490    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
491    // here so that while the job scheduler can depend on AMS, the other way around
492    // need not be the case.
493    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
494
495    /** Control over CPU and battery monitoring */
496    // write battery stats every 30 minutes.
497    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
498    static final boolean MONITOR_CPU_USAGE = true;
499    // don't sample cpu less than every 5 seconds.
500    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
501    // wait possibly forever for next cpu sample.
502    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
503    static final boolean MONITOR_THREAD_CPU_USAGE = false;
504
505    // The flags that are set for all calls we make to the package manager.
506    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
507
508    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
509
510    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
511
512    // Amount of time after a call to stopAppSwitches() during which we will
513    // prevent further untrusted switches from happening.
514    static final long APP_SWITCH_DELAY_TIME = 5*1000;
515
516    // How long we wait for a launched process to attach to the activity manager
517    // before we decide it's never going to come up for real.
518    static final int PROC_START_TIMEOUT = 10*1000;
519    // How long we wait for an attached process to publish its content providers
520    // before we decide it must be hung.
521    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
522
523    // How long we wait for a launched process to attach to the activity manager
524    // before we decide it's never going to come up for real, when the process was
525    // started with a wrapper for instrumentation (such as Valgrind) because it
526    // could take much longer than usual.
527    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
528
529    // How long we allow a receiver to run before giving up on it.
530    static final int BROADCAST_FG_TIMEOUT = 10*1000;
531    static final int BROADCAST_BG_TIMEOUT = 60*1000;
532
533    // How long we wait until we timeout on key dispatching.
534    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
535
536    // How long we wait until we timeout on key dispatching during instrumentation.
537    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
538
539    // How long to wait in getAssistContextExtras for the activity and foreground services
540    // to respond with the result.
541    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
542
543    // How long top wait when going through the modern assist (which doesn't need to block
544    // on getting this result before starting to launch its UI).
545    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
546
547    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
548    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
549
550    // Maximum number of persisted Uri grants a package is allowed
551    static final int MAX_PERSISTED_URI_GRANTS = 128;
552
553    static final int MY_PID = myPid();
554
555    static final String[] EMPTY_STRING_ARRAY = new String[0];
556
557    // How many bytes to write into the dropbox log before truncating
558    static final int DROPBOX_MAX_SIZE = 192 * 1024;
559    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
560    // as one line, but close enough for now.
561    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
562
563    // Access modes for handleIncomingUser.
564    static final int ALLOW_NON_FULL = 0;
565    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
566    static final int ALLOW_FULL_ONLY = 2;
567
568    // Necessary ApplicationInfo flags to mark an app as persistent
569    private static final int PERSISTENT_MASK =
570            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
571
572    // Intent sent when remote bugreport collection has been completed
573    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
574            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
575
576    // Used to indicate that an app transition should be animated.
577    static final boolean ANIMATE = true;
578
579    // Determines whether to take full screen screenshots
580    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
581
582    /**
583     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
584     */
585    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
586
587    /**
588     * State indicating that there is no need for any blocking for network.
589     */
590    @VisibleForTesting
591    static final int NETWORK_STATE_NO_CHANGE = 0;
592
593    /**
594     * State indicating that the main thread needs to be informed about the network wait.
595     */
596    @VisibleForTesting
597    static final int NETWORK_STATE_BLOCK = 1;
598
599    /**
600     * State indicating that any threads waiting for network state to get updated can be unblocked.
601     */
602    @VisibleForTesting
603    static final int NETWORK_STATE_UNBLOCK = 2;
604
605    // Max character limit for a notification title. If the notification title is larger than this
606    // the notification will not be legible to the user.
607    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
608
609    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
610
611    /** All system services */
612    SystemServiceManager mSystemServiceManager;
613    AssistUtils mAssistUtils;
614
615    private Installer mInstaller;
616
617    /** Run all ActivityStacks through this */
618    final ActivityStackSupervisor mStackSupervisor;
619    private final KeyguardController mKeyguardController;
620
621    final ActivityStarter mActivityStarter;
622
623    final TaskChangeNotificationController mTaskChangeNotificationController;
624
625    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
626
627    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
628
629    public final IntentFirewall mIntentFirewall;
630
631    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
632    // default action automatically.  Important for devices without direct input
633    // devices.
634    private boolean mShowDialogs = true;
635
636    private final VrController mVrController;
637
638    // VR Vr2d Display Id.
639    int mVr2dDisplayId = INVALID_DISPLAY;
640
641    // Whether we should use SCHED_FIFO for UI and RenderThreads.
642    private boolean mUseFifoUiScheduling = false;
643
644    BroadcastQueue mFgBroadcastQueue;
645    BroadcastQueue mBgBroadcastQueue;
646    // Convenient for easy iteration over the queues. Foreground is first
647    // so that dispatch of foreground broadcasts gets precedence.
648    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
649
650    BroadcastStats mLastBroadcastStats;
651    BroadcastStats mCurBroadcastStats;
652
653    BroadcastQueue broadcastQueueForIntent(Intent intent) {
654        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
655        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
656                "Broadcast intent " + intent + " on "
657                + (isFg ? "foreground" : "background") + " queue");
658        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
659    }
660
661    /**
662     * The last resumed activity. This is identical to the current resumed activity most
663     * of the time but could be different when we're pausing one activity before we resume
664     * another activity.
665     */
666    private ActivityRecord mLastResumedActivity;
667
668    /**
669     * If non-null, we are tracking the time the user spends in the currently focused app.
670     */
671    private AppTimeTracker mCurAppTimeTracker;
672
673    /**
674     * List of intents that were used to start the most recent tasks.
675     */
676    final RecentTasks mRecentTasks;
677
678    /**
679     * For addAppTask: cached of the last activity component that was added.
680     */
681    ComponentName mLastAddedTaskComponent;
682
683    /**
684     * For addAppTask: cached of the last activity uid that was added.
685     */
686    int mLastAddedTaskUid;
687
688    /**
689     * For addAppTask: cached of the last ActivityInfo that was added.
690     */
691    ActivityInfo mLastAddedTaskActivity;
692
693    /**
694     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
695     */
696    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
697
698    /**
699     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
700     */
701    String mDeviceOwnerName;
702
703    final UserController mUserController;
704
705    final AppErrors mAppErrors;
706
707    /**
708     * Dump of the activity state at the time of the last ANR. Cleared after
709     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
710     */
711    String mLastANRState;
712
713    /**
714     * Indicates the maximum time spent waiting for the network rules to get updated.
715     */
716    @VisibleForTesting
717    long mWaitForNetworkTimeoutMs;
718
719    public boolean canShowErrorDialogs() {
720        return mShowDialogs && !mSleeping && !mShuttingDown
721                && !mKeyguardController.isKeyguardShowing();
722    }
723
724    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
725            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
726
727    static void boostPriorityForLockedSection() {
728        sThreadPriorityBooster.boost();
729    }
730
731    static void resetPriorityAfterLockedSection() {
732        sThreadPriorityBooster.reset();
733    }
734
735    public class PendingAssistExtras extends Binder implements Runnable {
736        public final ActivityRecord activity;
737        public boolean isHome;
738        public final Bundle extras;
739        public final Intent intent;
740        public final String hint;
741        public final IResultReceiver receiver;
742        public final int userHandle;
743        public boolean haveResult = false;
744        public Bundle result = null;
745        public AssistStructure structure = null;
746        public AssistContent content = null;
747        public Bundle receiverExtras;
748
749        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
750                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
751            activity = _activity;
752            extras = _extras;
753            intent = _intent;
754            hint = _hint;
755            receiver = _receiver;
756            receiverExtras = _receiverExtras;
757            userHandle = _userHandle;
758        }
759
760        @Override
761        public void run() {
762            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
763            synchronized (this) {
764                haveResult = true;
765                notifyAll();
766            }
767            pendingAssistExtrasTimedOut(this);
768        }
769    }
770
771    final ArrayList<PendingAssistExtras> mPendingAssistExtras
772            = new ArrayList<PendingAssistExtras>();
773
774    /**
775     * Process management.
776     */
777    final ProcessList mProcessList = new ProcessList();
778
779    /**
780     * All of the applications we currently have running organized by name.
781     * The keys are strings of the application package name (as
782     * returned by the package manager), and the keys are ApplicationRecord
783     * objects.
784     */
785    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
786
787    /**
788     * Tracking long-term execution of processes to look for abuse and other
789     * bad app behavior.
790     */
791    final ProcessStatsService mProcessStats;
792
793    /**
794     * The currently running isolated processes.
795     */
796    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
797
798    /**
799     * Counter for assigning isolated process uids, to avoid frequently reusing the
800     * same ones.
801     */
802    int mNextIsolatedProcessUid = 0;
803
804    /**
805     * The currently running heavy-weight process, if any.
806     */
807    ProcessRecord mHeavyWeightProcess = null;
808
809    /**
810     * Non-persistent appId whitelist for background restrictions
811     */
812    int[] mBackgroundAppIdWhitelist = new int[] {
813            BLUETOOTH_UID
814    };
815
816    /**
817     * Broadcast actions that will always be deliverable to unlaunched/background apps
818     */
819    ArraySet<String> mBackgroundLaunchBroadcasts;
820
821    /**
822     * All of the processes we currently have running organized by pid.
823     * The keys are the pid running the application.
824     *
825     * <p>NOTE: This object is protected by its own lock, NOT the global
826     * activity manager lock!
827     */
828    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
829
830    /**
831     * All of the processes that have been forced to be important.  The key
832     * is the pid of the caller who requested it (we hold a death
833     * link on it).
834     */
835    abstract class ImportanceToken implements IBinder.DeathRecipient {
836        final int pid;
837        final IBinder token;
838        final String reason;
839
840        ImportanceToken(int _pid, IBinder _token, String _reason) {
841            pid = _pid;
842            token = _token;
843            reason = _reason;
844        }
845
846        @Override
847        public String toString() {
848            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
849                    + " " + reason + " " + pid + " " + token + " }";
850        }
851    }
852    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
853
854    /**
855     * List of records for processes that someone had tried to start before the
856     * system was ready.  We don't start them at that point, but ensure they
857     * are started by the time booting is complete.
858     */
859    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
860
861    /**
862     * List of persistent applications that are in the process
863     * of being started.
864     */
865    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
866
867    /**
868     * Processes that are being forcibly torn down.
869     */
870    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
871
872    /**
873     * List of running applications, sorted by recent usage.
874     * The first entry in the list is the least recently used.
875     */
876    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
877
878    /**
879     * Where in mLruProcesses that the processes hosting activities start.
880     */
881    int mLruProcessActivityStart = 0;
882
883    /**
884     * Where in mLruProcesses that the processes hosting services start.
885     * This is after (lower index) than mLruProcessesActivityStart.
886     */
887    int mLruProcessServiceStart = 0;
888
889    /**
890     * List of processes that should gc as soon as things are idle.
891     */
892    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
893
894    /**
895     * Processes we want to collect PSS data from.
896     */
897    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
898
899    private boolean mBinderTransactionTrackingEnabled = false;
900
901    /**
902     * Last time we requested PSS data of all processes.
903     */
904    long mLastFullPssTime = SystemClock.uptimeMillis();
905
906    /**
907     * If set, the next time we collect PSS data we should do a full collection
908     * with data from native processes and the kernel.
909     */
910    boolean mFullPssPending = false;
911
912    /**
913     * This is the process holding what we currently consider to be
914     * the "home" activity.
915     */
916    ProcessRecord mHomeProcess;
917
918    /**
919     * This is the process holding the activity the user last visited that
920     * is in a different process from the one they are currently in.
921     */
922    ProcessRecord mPreviousProcess;
923
924    /**
925     * The time at which the previous process was last visible.
926     */
927    long mPreviousProcessVisibleTime;
928
929    /**
930     * Track all uids that have actively running processes.
931     */
932    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
933
934    /**
935     * This is for verifying the UID report flow.
936     */
937    static final boolean VALIDATE_UID_STATES = true;
938    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
939
940    /**
941     * Packages that the user has asked to have run in screen size
942     * compatibility mode instead of filling the screen.
943     */
944    final CompatModePackages mCompatModePackages;
945
946    /**
947     * Set of IntentSenderRecord objects that are currently active.
948     */
949    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
950            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
951
952    /**
953     * Fingerprints (hashCode()) of stack traces that we've
954     * already logged DropBox entries for.  Guarded by itself.  If
955     * something (rogue user app) forces this over
956     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
957     */
958    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
959    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
960
961    /**
962     * Strict Mode background batched logging state.
963     *
964     * The string buffer is guarded by itself, and its lock is also
965     * used to determine if another batched write is already
966     * in-flight.
967     */
968    private final StringBuilder mStrictModeBuffer = new StringBuilder();
969
970    /**
971     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
972     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
973     */
974    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
975
976    /**
977     * Resolver for broadcast intents to registered receivers.
978     * Holds BroadcastFilter (subclass of IntentFilter).
979     */
980    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
981            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
982        @Override
983        protected boolean allowFilterResult(
984                BroadcastFilter filter, List<BroadcastFilter> dest) {
985            IBinder target = filter.receiverList.receiver.asBinder();
986            for (int i = dest.size() - 1; i >= 0; i--) {
987                if (dest.get(i).receiverList.receiver.asBinder() == target) {
988                    return false;
989                }
990            }
991            return true;
992        }
993
994        @Override
995        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
996            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
997                    || userId == filter.owningUserId) {
998                return super.newResult(filter, match, userId);
999            }
1000            return null;
1001        }
1002
1003        @Override
1004        protected BroadcastFilter[] newArray(int size) {
1005            return new BroadcastFilter[size];
1006        }
1007
1008        @Override
1009        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1010            return packageName.equals(filter.packageName);
1011        }
1012    };
1013
1014    /**
1015     * State of all active sticky broadcasts per user.  Keys are the action of the
1016     * sticky Intent, values are an ArrayList of all broadcasted intents with
1017     * that action (which should usually be one).  The SparseArray is keyed
1018     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1019     * for stickies that are sent to all users.
1020     */
1021    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1022            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1023
1024    final ActiveServices mServices;
1025
1026    final static class Association {
1027        final int mSourceUid;
1028        final String mSourceProcess;
1029        final int mTargetUid;
1030        final ComponentName mTargetComponent;
1031        final String mTargetProcess;
1032
1033        int mCount;
1034        long mTime;
1035
1036        int mNesting;
1037        long mStartTime;
1038
1039        // states of the source process when the bind occurred.
1040        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1041        long mLastStateUptime;
1042        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1043                - ActivityManager.MIN_PROCESS_STATE+1];
1044
1045        Association(int sourceUid, String sourceProcess, int targetUid,
1046                ComponentName targetComponent, String targetProcess) {
1047            mSourceUid = sourceUid;
1048            mSourceProcess = sourceProcess;
1049            mTargetUid = targetUid;
1050            mTargetComponent = targetComponent;
1051            mTargetProcess = targetProcess;
1052        }
1053    }
1054
1055    /**
1056     * When service association tracking is enabled, this is all of the associations we
1057     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1058     * -> association data.
1059     */
1060    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1061            mAssociations = new SparseArray<>();
1062    boolean mTrackingAssociations;
1063
1064    /**
1065     * Backup/restore process management
1066     */
1067    String mBackupAppName = null;
1068    BackupRecord mBackupTarget = null;
1069
1070    final ProviderMap mProviderMap;
1071
1072    /**
1073     * List of content providers who have clients waiting for them.  The
1074     * application is currently being launched and the provider will be
1075     * removed from this list once it is published.
1076     */
1077    final ArrayList<ContentProviderRecord> mLaunchingProviders
1078            = new ArrayList<ContentProviderRecord>();
1079
1080    /**
1081     * File storing persisted {@link #mGrantedUriPermissions}.
1082     */
1083    private final AtomicFile mGrantFile;
1084
1085    /** XML constants used in {@link #mGrantFile} */
1086    private static final String TAG_URI_GRANTS = "uri-grants";
1087    private static final String TAG_URI_GRANT = "uri-grant";
1088    private static final String ATTR_USER_HANDLE = "userHandle";
1089    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1090    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1091    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1092    private static final String ATTR_TARGET_PKG = "targetPkg";
1093    private static final String ATTR_URI = "uri";
1094    private static final String ATTR_MODE_FLAGS = "modeFlags";
1095    private static final String ATTR_CREATED_TIME = "createdTime";
1096    private static final String ATTR_PREFIX = "prefix";
1097
1098    /**
1099     * Global set of specific {@link Uri} permissions that have been granted.
1100     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1101     * to {@link UriPermission#uri} to {@link UriPermission}.
1102     */
1103    @GuardedBy("this")
1104    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1105            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1106
1107    public static class GrantUri {
1108        public final int sourceUserId;
1109        public final Uri uri;
1110        public boolean prefix;
1111
1112        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1113            this.sourceUserId = sourceUserId;
1114            this.uri = uri;
1115            this.prefix = prefix;
1116        }
1117
1118        @Override
1119        public int hashCode() {
1120            int hashCode = 1;
1121            hashCode = 31 * hashCode + sourceUserId;
1122            hashCode = 31 * hashCode + uri.hashCode();
1123            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1124            return hashCode;
1125        }
1126
1127        @Override
1128        public boolean equals(Object o) {
1129            if (o instanceof GrantUri) {
1130                GrantUri other = (GrantUri) o;
1131                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1132                        && prefix == other.prefix;
1133            }
1134            return false;
1135        }
1136
1137        @Override
1138        public String toString() {
1139            String result = uri.toString() + " [user " + sourceUserId + "]";
1140            if (prefix) result += " [prefix]";
1141            return result;
1142        }
1143
1144        public String toSafeString() {
1145            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1146            if (prefix) result += " [prefix]";
1147            return result;
1148        }
1149
1150        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1151            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1152                    ContentProvider.getUriWithoutUserId(uri), false);
1153        }
1154    }
1155
1156    CoreSettingsObserver mCoreSettingsObserver;
1157
1158    FontScaleSettingObserver mFontScaleSettingObserver;
1159
1160    private final class FontScaleSettingObserver extends ContentObserver {
1161        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1162
1163        public FontScaleSettingObserver() {
1164            super(mHandler);
1165            ContentResolver resolver = mContext.getContentResolver();
1166            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1167        }
1168
1169        @Override
1170        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1171            if (mFontScaleUri.equals(uri)) {
1172                updateFontScaleIfNeeded(userId);
1173            }
1174        }
1175    }
1176
1177    /**
1178     * Thread-local storage used to carry caller permissions over through
1179     * indirect content-provider access.
1180     */
1181    private class Identity {
1182        public final IBinder token;
1183        public final int pid;
1184        public final int uid;
1185
1186        Identity(IBinder _token, int _pid, int _uid) {
1187            token = _token;
1188            pid = _pid;
1189            uid = _uid;
1190        }
1191    }
1192
1193    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1194
1195    /**
1196     * All information we have collected about the runtime performance of
1197     * any user id that can impact battery performance.
1198     */
1199    final BatteryStatsService mBatteryStatsService;
1200
1201    /**
1202     * Information about component usage
1203     */
1204    UsageStatsManagerInternal mUsageStatsService;
1205
1206    /**
1207     * Access to DeviceIdleController service.
1208     */
1209    DeviceIdleController.LocalService mLocalDeviceIdleController;
1210
1211    /**
1212     * Set of app ids that are whitelisted for device idle and thus background check.
1213     */
1214    int[] mDeviceIdleWhitelist = new int[0];
1215
1216    /**
1217     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1218     */
1219    int[] mDeviceIdleTempWhitelist = new int[0];
1220
1221    static final class PendingTempWhitelist {
1222        final int targetUid;
1223        final long duration;
1224        final String tag;
1225
1226        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1227            targetUid = _targetUid;
1228            duration = _duration;
1229            tag = _tag;
1230        }
1231    }
1232
1233    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1234
1235    /**
1236     * Information about and control over application operations
1237     */
1238    final AppOpsService mAppOpsService;
1239
1240    /** Current sequencing integer of the configuration, for skipping old configurations. */
1241    private int mConfigurationSeq;
1242
1243    /**
1244     * Temp object used when global and/or display override configuration is updated. It is also
1245     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1246     * anyone...
1247     */
1248    private Configuration mTempConfig = new Configuration();
1249
1250    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1251            new UpdateConfigurationResult();
1252    private static final class UpdateConfigurationResult {
1253        // Configuration changes that were updated.
1254        int changes;
1255        // If the activity was relaunched to match the new configuration.
1256        boolean activityRelaunched;
1257
1258        void reset() {
1259            changes = 0;
1260            activityRelaunched = false;
1261        }
1262    }
1263
1264    boolean mSuppressResizeConfigChanges;
1265
1266    /**
1267     * Hardware-reported OpenGLES version.
1268     */
1269    final int GL_ES_VERSION;
1270
1271    /**
1272     * List of initialization arguments to pass to all processes when binding applications to them.
1273     * For example, references to the commonly used services.
1274     */
1275    HashMap<String, IBinder> mAppBindArgs;
1276    HashMap<String, IBinder> mIsolatedAppBindArgs;
1277
1278    /**
1279     * Temporary to avoid allocations.  Protected by main lock.
1280     */
1281    final StringBuilder mStringBuilder = new StringBuilder(256);
1282
1283    /**
1284     * Used to control how we initialize the service.
1285     */
1286    ComponentName mTopComponent;
1287    String mTopAction = Intent.ACTION_MAIN;
1288    String mTopData;
1289
1290    volatile boolean mProcessesReady = false;
1291    volatile boolean mSystemReady = false;
1292    volatile boolean mOnBattery = false;
1293    volatile int mFactoryTest;
1294
1295    @GuardedBy("this") boolean mBooting = false;
1296    @GuardedBy("this") boolean mCallFinishBooting = false;
1297    @GuardedBy("this") boolean mBootAnimationComplete = false;
1298    @GuardedBy("this") boolean mLaunchWarningShown = false;
1299    @GuardedBy("this") boolean mCheckedForSetup = false;
1300
1301    final Context mContext;
1302
1303    /**
1304     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1305     * change at runtime. Use mContext for non-UI purposes.
1306     */
1307    final Context mUiContext;
1308
1309    /**
1310     * The time at which we will allow normal application switches again,
1311     * after a call to {@link #stopAppSwitches()}.
1312     */
1313    long mAppSwitchesAllowedTime;
1314
1315    /**
1316     * This is set to true after the first switch after mAppSwitchesAllowedTime
1317     * is set; any switches after that will clear the time.
1318     */
1319    boolean mDidAppSwitch;
1320
1321    /**
1322     * Last time (in realtime) at which we checked for power usage.
1323     */
1324    long mLastPowerCheckRealtime;
1325
1326    /**
1327     * Last time (in uptime) at which we checked for power usage.
1328     */
1329    long mLastPowerCheckUptime;
1330
1331    /**
1332     * Set while we are wanting to sleep, to prevent any
1333     * activities from being started/resumed.
1334     *
1335     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1336     *
1337     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1338     * while in the sleep state until there is a pending transition out of sleep, in which case
1339     * mSleeping is set to false, and remains false while awake.
1340     *
1341     * Whether mSleeping can quickly toggled between true/false without the device actually
1342     * display changing states is undefined.
1343     */
1344    private boolean mSleeping = false;
1345
1346    /**
1347     * The process state used for processes that are running the top activities.
1348     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1349     */
1350    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1351
1352    /**
1353     * Set while we are running a voice interaction.  This overrides
1354     * sleeping while it is active.
1355     */
1356    private IVoiceInteractionSession mRunningVoice;
1357
1358    /**
1359     * For some direct access we need to power manager.
1360     */
1361    PowerManagerInternal mLocalPowerManager;
1362
1363    /**
1364     * We want to hold a wake lock while running a voice interaction session, since
1365     * this may happen with the screen off and we need to keep the CPU running to
1366     * be able to continue to interact with the user.
1367     */
1368    PowerManager.WakeLock mVoiceWakeLock;
1369
1370    /**
1371     * State of external calls telling us if the device is awake or asleep.
1372     */
1373    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1374
1375    /**
1376     * A list of tokens that cause the top activity to be put to sleep.
1377     * They are used by components that may hide and block interaction with underlying
1378     * activities.
1379     */
1380    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1381
1382    /**
1383     * Set if we are shutting down the system, similar to sleeping.
1384     */
1385    boolean mShuttingDown = false;
1386
1387    /**
1388     * Current sequence id for oom_adj computation traversal.
1389     */
1390    int mAdjSeq = 0;
1391
1392    /**
1393     * Current sequence id for process LRU updating.
1394     */
1395    int mLruSeq = 0;
1396
1397    /**
1398     * Keep track of the non-cached/empty process we last found, to help
1399     * determine how to distribute cached/empty processes next time.
1400     */
1401    int mNumNonCachedProcs = 0;
1402
1403    /**
1404     * Keep track of the number of cached hidden procs, to balance oom adj
1405     * distribution between those and empty procs.
1406     */
1407    int mNumCachedHiddenProcs = 0;
1408
1409    /**
1410     * Keep track of the number of service processes we last found, to
1411     * determine on the next iteration which should be B services.
1412     */
1413    int mNumServiceProcs = 0;
1414    int mNewNumAServiceProcs = 0;
1415    int mNewNumServiceProcs = 0;
1416
1417    /**
1418     * Allow the current computed overall memory level of the system to go down?
1419     * This is set to false when we are killing processes for reasons other than
1420     * memory management, so that the now smaller process list will not be taken as
1421     * an indication that memory is tighter.
1422     */
1423    boolean mAllowLowerMemLevel = false;
1424
1425    /**
1426     * The last computed memory level, for holding when we are in a state that
1427     * processes are going away for other reasons.
1428     */
1429    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1430
1431    /**
1432     * The last total number of process we have, to determine if changes actually look
1433     * like a shrinking number of process due to lower RAM.
1434     */
1435    int mLastNumProcesses;
1436
1437    /**
1438     * The uptime of the last time we performed idle maintenance.
1439     */
1440    long mLastIdleTime = SystemClock.uptimeMillis();
1441
1442    /**
1443     * Total time spent with RAM that has been added in the past since the last idle time.
1444     */
1445    long mLowRamTimeSinceLastIdle = 0;
1446
1447    /**
1448     * If RAM is currently low, when that horrible situation started.
1449     */
1450    long mLowRamStartTime = 0;
1451
1452    /**
1453     * For reporting to battery stats the current top application.
1454     */
1455    private String mCurResumedPackage = null;
1456    private int mCurResumedUid = -1;
1457
1458    /**
1459     * For reporting to battery stats the apps currently running foreground
1460     * service.  The ProcessMap is package/uid tuples; each of these contain
1461     * an array of the currently foreground processes.
1462     */
1463    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1464            = new ProcessMap<ArrayList<ProcessRecord>>();
1465
1466    /**
1467     * Set if the systemServer made a call to enterSafeMode.
1468     */
1469    boolean mSafeMode;
1470
1471    /**
1472     * If true, we are running under a test environment so will sample PSS from processes
1473     * much more rapidly to try to collect better data when the tests are rapidly
1474     * running through apps.
1475     */
1476    boolean mTestPssMode = false;
1477
1478    String mDebugApp = null;
1479    boolean mWaitForDebugger = false;
1480    boolean mDebugTransient = false;
1481    String mOrigDebugApp = null;
1482    boolean mOrigWaitForDebugger = false;
1483    boolean mAlwaysFinishActivities = false;
1484    boolean mForceResizableActivities;
1485    /**
1486     * Flag that indicates if multi-window is enabled.
1487     *
1488     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1489     * in {@link com.android.internal.R.bool.config_supportsMultiWindow} config or
1490     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1491     * At least one of the forms of multi-window must be enabled in order for this flag to be
1492     * initialized to 'true'.
1493     *
1494     * @see #mSupportsSplitScreenMultiWindow
1495     * @see #mSupportsFreeformWindowManagement
1496     * @see #mSupportsPictureInPicture
1497     * @see #mSupportsMultiDisplay
1498     */
1499    boolean mSupportsMultiWindow;
1500    boolean mSupportsSplitScreenMultiWindow;
1501    boolean mSupportsFreeformWindowManagement;
1502    boolean mSupportsPictureInPicture;
1503    boolean mSupportsMultiDisplay;
1504    boolean mSupportsLeanbackOnly;
1505    IActivityController mController = null;
1506    boolean mControllerIsAMonkey = false;
1507    String mProfileApp = null;
1508    ProcessRecord mProfileProc = null;
1509    String mProfileFile;
1510    ParcelFileDescriptor mProfileFd;
1511    int mSamplingInterval = 0;
1512    boolean mAutoStopProfiler = false;
1513    boolean mStreamingOutput = false;
1514    int mProfileType = 0;
1515    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1516    String mMemWatchDumpProcName;
1517    String mMemWatchDumpFile;
1518    int mMemWatchDumpPid;
1519    int mMemWatchDumpUid;
1520    String mTrackAllocationApp = null;
1521    String mNativeDebuggingApp = null;
1522
1523    final long[] mTmpLong = new long[2];
1524
1525    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1526
1527    /**
1528     * A global counter for generating sequence numbers.
1529     * This value will be used when incrementing sequence numbers in individual uidRecords.
1530     *
1531     * Having a global counter ensures that seq numbers are monotonically increasing for a
1532     * particular uid even when the uidRecord is re-created.
1533     */
1534    @GuardedBy("this")
1535    @VisibleForTesting
1536    long mProcStateSeqCounter = 0;
1537
1538    private final Injector mInjector;
1539
1540    static final class ProcessChangeItem {
1541        static final int CHANGE_ACTIVITIES = 1<<0;
1542        int changes;
1543        int uid;
1544        int pid;
1545        int processState;
1546        boolean foregroundActivities;
1547    }
1548
1549    static final class UidObserverRegistration {
1550        final int uid;
1551        final String pkg;
1552        final int which;
1553        final int cutpoint;
1554
1555        final SparseIntArray lastProcStates;
1556
1557        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1558            uid = _uid;
1559            pkg = _pkg;
1560            which = _which;
1561            cutpoint = _cutpoint;
1562            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1563                lastProcStates = new SparseIntArray();
1564            } else {
1565                lastProcStates = null;
1566            }
1567        }
1568    }
1569
1570    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1571    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1572
1573    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1574    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1575
1576    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1577    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1578
1579    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1580    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1581
1582    /**
1583     * Runtime CPU use collection thread.  This object's lock is used to
1584     * perform synchronization with the thread (notifying it to run).
1585     */
1586    final Thread mProcessCpuThread;
1587
1588    /**
1589     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1590     * Must acquire this object's lock when accessing it.
1591     * NOTE: this lock will be held while doing long operations (trawling
1592     * through all processes in /proc), so it should never be acquired by
1593     * any critical paths such as when holding the main activity manager lock.
1594     */
1595    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1596            MONITOR_THREAD_CPU_USAGE);
1597    final AtomicLong mLastCpuTime = new AtomicLong(0);
1598    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1599    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1600
1601    long mLastWriteTime = 0;
1602
1603    /**
1604     * Used to retain an update lock when the foreground activity is in
1605     * immersive mode.
1606     */
1607    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1608
1609    /**
1610     * Set to true after the system has finished booting.
1611     */
1612    boolean mBooted = false;
1613
1614    WindowManagerService mWindowManager;
1615    final ActivityThread mSystemThread;
1616
1617    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1618        final ProcessRecord mApp;
1619        final int mPid;
1620        final IApplicationThread mAppThread;
1621
1622        AppDeathRecipient(ProcessRecord app, int pid,
1623                IApplicationThread thread) {
1624            if (DEBUG_ALL) Slog.v(
1625                TAG, "New death recipient " + this
1626                + " for thread " + thread.asBinder());
1627            mApp = app;
1628            mPid = pid;
1629            mAppThread = thread;
1630        }
1631
1632        @Override
1633        public void binderDied() {
1634            if (DEBUG_ALL) Slog.v(
1635                TAG, "Death received in " + this
1636                + " for thread " + mAppThread.asBinder());
1637            synchronized(ActivityManagerService.this) {
1638                appDiedLocked(mApp, mPid, mAppThread, true);
1639            }
1640        }
1641    }
1642
1643    static final int SHOW_ERROR_UI_MSG = 1;
1644    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1645    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1646    static final int UPDATE_CONFIGURATION_MSG = 4;
1647    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1648    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1649    static final int SERVICE_TIMEOUT_MSG = 12;
1650    static final int UPDATE_TIME_ZONE = 13;
1651    static final int SHOW_UID_ERROR_UI_MSG = 14;
1652    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1653    static final int PROC_START_TIMEOUT_MSG = 20;
1654    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1655    static final int KILL_APPLICATION_MSG = 22;
1656    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1657    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1658    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1659    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1660    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1661    static final int CLEAR_DNS_CACHE_MSG = 28;
1662    static final int UPDATE_HTTP_PROXY_MSG = 29;
1663    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1664    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1665    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1666    static final int REPORT_MEM_USAGE_MSG = 33;
1667    static final int REPORT_USER_SWITCH_MSG = 34;
1668    static final int CONTINUE_USER_SWITCH_MSG = 35;
1669    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1670    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1671    static final int PERSIST_URI_GRANTS_MSG = 38;
1672    static final int REQUEST_ALL_PSS_MSG = 39;
1673    static final int START_PROFILES_MSG = 40;
1674    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1675    static final int SYSTEM_USER_START_MSG = 42;
1676    static final int SYSTEM_USER_CURRENT_MSG = 43;
1677    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1678    static final int FINISH_BOOTING_MSG = 45;
1679    static final int START_USER_SWITCH_UI_MSG = 46;
1680    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1681    static final int DISMISS_DIALOG_UI_MSG = 48;
1682    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1683    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1684    static final int DELETE_DUMPHEAP_MSG = 51;
1685    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1686    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1687    static final int REPORT_TIME_TRACKER_MSG = 54;
1688    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1689    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1690    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1691    static final int IDLE_UIDS_MSG = 58;
1692    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1693    static final int LOG_STACK_STATE = 60;
1694    static final int VR_MODE_CHANGE_MSG = 61;
1695    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1696    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1697    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1698    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1699    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1700    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1701    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1702    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1703    static final int START_USER_SWITCH_FG_MSG = 712;
1704
1705    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1706    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1707    static final int FIRST_COMPAT_MODE_MSG = 300;
1708    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1709
1710    static ServiceThread sKillThread = null;
1711    static KillHandler sKillHandler = null;
1712
1713    CompatModeDialog mCompatModeDialog;
1714    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1715    long mLastMemUsageReportTime = 0;
1716
1717    /**
1718     * Flag whether the current user is a "monkey", i.e. whether
1719     * the UI is driven by a UI automation tool.
1720     */
1721    private boolean mUserIsMonkey;
1722
1723    /** Flag whether the device has a Recents UI */
1724    boolean mHasRecents;
1725
1726    /** The dimensions of the thumbnails in the Recents UI. */
1727    int mThumbnailWidth;
1728    int mThumbnailHeight;
1729    float mFullscreenThumbnailScale;
1730
1731    final ServiceThread mHandlerThread;
1732    final MainHandler mHandler;
1733    final Handler mUiHandler;
1734
1735    final ActivityManagerConstants mConstants;
1736
1737    PackageManagerInternal mPackageManagerInt;
1738
1739    // VoiceInteraction session ID that changes for each new request except when
1740    // being called for multiwindow assist in a single session.
1741    private int mViSessionId = 1000;
1742
1743    final boolean mPermissionReviewRequired;
1744
1745    /**
1746     * Current global configuration information. Contains general settings for the entire system,
1747     * also corresponds to the merged configuration of the default display.
1748     */
1749    Configuration getGlobalConfiguration() {
1750        return mStackSupervisor.getConfiguration();
1751    }
1752
1753    final class KillHandler extends Handler {
1754        static final int KILL_PROCESS_GROUP_MSG = 4000;
1755
1756        public KillHandler(Looper looper) {
1757            super(looper, null, true);
1758        }
1759
1760        @Override
1761        public void handleMessage(Message msg) {
1762            switch (msg.what) {
1763                case KILL_PROCESS_GROUP_MSG:
1764                {
1765                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1766                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1767                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1768                }
1769                break;
1770
1771                default:
1772                    super.handleMessage(msg);
1773            }
1774        }
1775    }
1776
1777    final class UiHandler extends Handler {
1778        public UiHandler() {
1779            super(com.android.server.UiThread.get().getLooper(), null, true);
1780        }
1781
1782        @Override
1783        public void handleMessage(Message msg) {
1784            switch (msg.what) {
1785            case SHOW_ERROR_UI_MSG: {
1786                mAppErrors.handleShowAppErrorUi(msg);
1787                ensureBootCompleted();
1788            } break;
1789            case SHOW_NOT_RESPONDING_UI_MSG: {
1790                mAppErrors.handleShowAnrUi(msg);
1791                ensureBootCompleted();
1792            } break;
1793            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1794                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1795                synchronized (ActivityManagerService.this) {
1796                    ProcessRecord proc = (ProcessRecord) data.get("app");
1797                    if (proc == null) {
1798                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1799                        break;
1800                    }
1801                    if (proc.crashDialog != null) {
1802                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1803                        return;
1804                    }
1805                    AppErrorResult res = (AppErrorResult) data.get("result");
1806                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1807                        Dialog d = new StrictModeViolationDialog(mUiContext,
1808                                ActivityManagerService.this, res, proc);
1809                        d.show();
1810                        proc.crashDialog = d;
1811                    } else {
1812                        // The device is asleep, so just pretend that the user
1813                        // saw a crash dialog and hit "force quit".
1814                        res.set(0);
1815                    }
1816                }
1817                ensureBootCompleted();
1818            } break;
1819            case SHOW_FACTORY_ERROR_UI_MSG: {
1820                Dialog d = new FactoryErrorDialog(
1821                        mUiContext, msg.getData().getCharSequence("msg"));
1822                d.show();
1823                ensureBootCompleted();
1824            } break;
1825            case WAIT_FOR_DEBUGGER_UI_MSG: {
1826                synchronized (ActivityManagerService.this) {
1827                    ProcessRecord app = (ProcessRecord)msg.obj;
1828                    if (msg.arg1 != 0) {
1829                        if (!app.waitedForDebugger) {
1830                            Dialog d = new AppWaitingForDebuggerDialog(
1831                                    ActivityManagerService.this,
1832                                    mUiContext, app);
1833                            app.waitDialog = d;
1834                            app.waitedForDebugger = true;
1835                            d.show();
1836                        }
1837                    } else {
1838                        if (app.waitDialog != null) {
1839                            app.waitDialog.dismiss();
1840                            app.waitDialog = null;
1841                        }
1842                    }
1843                }
1844            } break;
1845            case SHOW_UID_ERROR_UI_MSG: {
1846                if (mShowDialogs) {
1847                    AlertDialog d = new BaseErrorDialog(mUiContext);
1848                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1849                    d.setCancelable(false);
1850                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1851                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1852                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1853                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1854                    d.show();
1855                }
1856            } break;
1857            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1858                if (mShowDialogs) {
1859                    AlertDialog d = new BaseErrorDialog(mUiContext);
1860                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1861                    d.setCancelable(false);
1862                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1863                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1864                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1865                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1866                    d.show();
1867                }
1868            } break;
1869            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1870                synchronized (ActivityManagerService.this) {
1871                    ActivityRecord ar = (ActivityRecord) msg.obj;
1872                    if (mCompatModeDialog != null) {
1873                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1874                                ar.info.applicationInfo.packageName)) {
1875                            return;
1876                        }
1877                        mCompatModeDialog.dismiss();
1878                        mCompatModeDialog = null;
1879                    }
1880                    if (ar != null && false) {
1881                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1882                                ar.packageName)) {
1883                            int mode = mCompatModePackages.computeCompatModeLocked(
1884                                    ar.info.applicationInfo);
1885                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1886                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1887                                mCompatModeDialog = new CompatModeDialog(
1888                                        ActivityManagerService.this, mUiContext,
1889                                        ar.info.applicationInfo);
1890                                mCompatModeDialog.show();
1891                            }
1892                        }
1893                    }
1894                }
1895                break;
1896            }
1897            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1898                synchronized (ActivityManagerService.this) {
1899                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1900                    if (mUnsupportedDisplaySizeDialog != null) {
1901                        mUnsupportedDisplaySizeDialog.dismiss();
1902                        mUnsupportedDisplaySizeDialog = null;
1903                    }
1904                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1905                            ar.packageName)) {
1906                        // TODO(multi-display): Show dialog on appropriate display.
1907                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1908                                ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1909                        mUnsupportedDisplaySizeDialog.show();
1910                    }
1911                }
1912                break;
1913            }
1914            case START_USER_SWITCH_UI_MSG: {
1915                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1916                break;
1917            }
1918            case DISMISS_DIALOG_UI_MSG: {
1919                final Dialog d = (Dialog) msg.obj;
1920                d.dismiss();
1921                break;
1922            }
1923            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1924                dispatchProcessesChanged();
1925                break;
1926            }
1927            case DISPATCH_PROCESS_DIED_UI_MSG: {
1928                final int pid = msg.arg1;
1929                final int uid = msg.arg2;
1930                dispatchProcessDied(pid, uid);
1931                break;
1932            }
1933            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1934                dispatchUidsChanged();
1935            } break;
1936            case PUSH_TEMP_WHITELIST_UI_MSG: {
1937                pushTempWhitelist();
1938            } break;
1939            }
1940        }
1941    }
1942
1943    final class MainHandler extends Handler {
1944        public MainHandler(Looper looper) {
1945            super(looper, null, true);
1946        }
1947
1948        @Override
1949        public void handleMessage(Message msg) {
1950            switch (msg.what) {
1951            case UPDATE_CONFIGURATION_MSG: {
1952                final ContentResolver resolver = mContext.getContentResolver();
1953                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1954                        msg.arg1);
1955            } break;
1956            case GC_BACKGROUND_PROCESSES_MSG: {
1957                synchronized (ActivityManagerService.this) {
1958                    performAppGcsIfAppropriateLocked();
1959                }
1960            } break;
1961            case SERVICE_TIMEOUT_MSG: {
1962                mServices.serviceTimeout((ProcessRecord)msg.obj);
1963            } break;
1964            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1965                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1966            } break;
1967            case SERVICE_FOREGROUND_CRASH_MSG: {
1968                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1969            } break;
1970            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1971                RemoteCallbackList<IResultReceiver> callbacks
1972                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
1973                int N = callbacks.beginBroadcast();
1974                for (int i = 0; i < N; i++) {
1975                    try {
1976                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1977                    } catch (RemoteException e) {
1978                    }
1979                }
1980                callbacks.finishBroadcast();
1981            } break;
1982            case UPDATE_TIME_ZONE: {
1983                synchronized (ActivityManagerService.this) {
1984                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1985                        ProcessRecord r = mLruProcesses.get(i);
1986                        if (r.thread != null) {
1987                            try {
1988                                r.thread.updateTimeZone();
1989                            } catch (RemoteException ex) {
1990                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1991                            }
1992                        }
1993                    }
1994                }
1995            } break;
1996            case CLEAR_DNS_CACHE_MSG: {
1997                synchronized (ActivityManagerService.this) {
1998                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1999                        ProcessRecord r = mLruProcesses.get(i);
2000                        if (r.thread != null) {
2001                            try {
2002                                r.thread.clearDnsCache();
2003                            } catch (RemoteException ex) {
2004                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2005                            }
2006                        }
2007                    }
2008                }
2009            } break;
2010            case UPDATE_HTTP_PROXY_MSG: {
2011                ProxyInfo proxy = (ProxyInfo)msg.obj;
2012                String host = "";
2013                String port = "";
2014                String exclList = "";
2015                Uri pacFileUrl = Uri.EMPTY;
2016                if (proxy != null) {
2017                    host = proxy.getHost();
2018                    port = Integer.toString(proxy.getPort());
2019                    exclList = proxy.getExclusionListAsString();
2020                    pacFileUrl = proxy.getPacFileUrl();
2021                }
2022                synchronized (ActivityManagerService.this) {
2023                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2024                        ProcessRecord r = mLruProcesses.get(i);
2025                        if (r.thread != null) {
2026                            try {
2027                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2028                            } catch (RemoteException ex) {
2029                                Slog.w(TAG, "Failed to update http proxy for: " +
2030                                        r.info.processName);
2031                            }
2032                        }
2033                    }
2034                }
2035            } break;
2036            case PROC_START_TIMEOUT_MSG: {
2037                ProcessRecord app = (ProcessRecord)msg.obj;
2038                synchronized (ActivityManagerService.this) {
2039                    processStartTimedOutLocked(app);
2040                }
2041            } break;
2042            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2043                ProcessRecord app = (ProcessRecord)msg.obj;
2044                synchronized (ActivityManagerService.this) {
2045                    processContentProviderPublishTimedOutLocked(app);
2046                }
2047            } break;
2048            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2049                synchronized (ActivityManagerService.this) {
2050                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2051                }
2052            } break;
2053            case KILL_APPLICATION_MSG: {
2054                synchronized (ActivityManagerService.this) {
2055                    final int appId = msg.arg1;
2056                    final int userId = msg.arg2;
2057                    Bundle bundle = (Bundle)msg.obj;
2058                    String pkg = bundle.getString("pkg");
2059                    String reason = bundle.getString("reason");
2060                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2061                            false, userId, reason);
2062                }
2063            } break;
2064            case FINALIZE_PENDING_INTENT_MSG: {
2065                ((PendingIntentRecord)msg.obj).completeFinalize();
2066            } break;
2067            case POST_HEAVY_NOTIFICATION_MSG: {
2068                INotificationManager inm = NotificationManager.getService();
2069                if (inm == null) {
2070                    return;
2071                }
2072
2073                ActivityRecord root = (ActivityRecord)msg.obj;
2074                ProcessRecord process = root.app;
2075                if (process == null) {
2076                    return;
2077                }
2078
2079                try {
2080                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2081                    String text = mContext.getString(R.string.heavy_weight_notification,
2082                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2083                    Notification notification =
2084                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2085                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2086                            .setWhen(0)
2087                            .setOngoing(true)
2088                            .setTicker(text)
2089                            .setColor(mContext.getColor(
2090                                    com.android.internal.R.color.system_notification_accent_color))
2091                            .setContentTitle(text)
2092                            .setContentText(
2093                                    mContext.getText(R.string.heavy_weight_notification_detail))
2094                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2095                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2096                                    new UserHandle(root.userId)))
2097                            .build();
2098                    try {
2099                        inm.enqueueNotificationWithTag("android", "android", null,
2100                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2101                                notification, root.userId);
2102                    } catch (RuntimeException e) {
2103                        Slog.w(ActivityManagerService.TAG,
2104                                "Error showing notification for heavy-weight app", e);
2105                    } catch (RemoteException e) {
2106                    }
2107                } catch (NameNotFoundException e) {
2108                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2109                }
2110            } break;
2111            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2112                INotificationManager inm = NotificationManager.getService();
2113                if (inm == null) {
2114                    return;
2115                }
2116                try {
2117                    inm.cancelNotificationWithTag("android", null,
2118                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2119                } catch (RuntimeException e) {
2120                    Slog.w(ActivityManagerService.TAG,
2121                            "Error canceling notification for service", e);
2122                } catch (RemoteException e) {
2123                }
2124            } break;
2125            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2126                synchronized (ActivityManagerService.this) {
2127                    checkExcessivePowerUsageLocked(true);
2128                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2129                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2130                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
2131                }
2132            } break;
2133            case REPORT_MEM_USAGE_MSG: {
2134                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2135                Thread thread = new Thread() {
2136                    @Override public void run() {
2137                        reportMemUsage(memInfos);
2138                    }
2139                };
2140                thread.start();
2141                break;
2142            }
2143            case START_USER_SWITCH_FG_MSG: {
2144                mUserController.startUserInForeground(msg.arg1);
2145                break;
2146            }
2147            case REPORT_USER_SWITCH_MSG: {
2148                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2149                break;
2150            }
2151            case CONTINUE_USER_SWITCH_MSG: {
2152                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2153                break;
2154            }
2155            case USER_SWITCH_TIMEOUT_MSG: {
2156                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2157                break;
2158            }
2159            case IMMERSIVE_MODE_LOCK_MSG: {
2160                final boolean nextState = (msg.arg1 != 0);
2161                if (mUpdateLock.isHeld() != nextState) {
2162                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2163                            "Applying new update lock state '" + nextState
2164                            + "' for " + (ActivityRecord)msg.obj);
2165                    if (nextState) {
2166                        mUpdateLock.acquire();
2167                    } else {
2168                        mUpdateLock.release();
2169                    }
2170                }
2171                break;
2172            }
2173            case PERSIST_URI_GRANTS_MSG: {
2174                writeGrantedUriPermissions();
2175                break;
2176            }
2177            case REQUEST_ALL_PSS_MSG: {
2178                synchronized (ActivityManagerService.this) {
2179                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2180                }
2181                break;
2182            }
2183            case START_PROFILES_MSG: {
2184                synchronized (ActivityManagerService.this) {
2185                    mUserController.startProfilesLocked();
2186                }
2187                break;
2188            }
2189            case UPDATE_TIME_PREFERENCE_MSG: {
2190                // The user's time format preference might have changed.
2191                // For convenience we re-use the Intent extra values.
2192                synchronized (ActivityManagerService.this) {
2193                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2194                        ProcessRecord r = mLruProcesses.get(i);
2195                        if (r.thread != null) {
2196                            try {
2197                                r.thread.updateTimePrefs(msg.arg1);
2198                            } catch (RemoteException ex) {
2199                                Slog.w(TAG, "Failed to update preferences for: "
2200                                        + r.info.processName);
2201                            }
2202                        }
2203                    }
2204                }
2205                break;
2206            }
2207            case SYSTEM_USER_START_MSG: {
2208                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2209                        Integer.toString(msg.arg1), msg.arg1);
2210                mSystemServiceManager.startUser(msg.arg1);
2211                break;
2212            }
2213            case SYSTEM_USER_UNLOCK_MSG: {
2214                final int userId = msg.arg1;
2215                mSystemServiceManager.unlockUser(userId);
2216                synchronized (ActivityManagerService.this) {
2217                    mRecentTasks.loadUserRecentsLocked(userId);
2218                }
2219                if (userId == UserHandle.USER_SYSTEM) {
2220                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2221                }
2222                installEncryptionUnawareProviders(userId);
2223                mUserController.finishUserUnlocked((UserState) msg.obj);
2224                break;
2225            }
2226            case SYSTEM_USER_CURRENT_MSG: {
2227                mBatteryStatsService.noteEvent(
2228                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2229                        Integer.toString(msg.arg2), msg.arg2);
2230                mBatteryStatsService.noteEvent(
2231                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2232                        Integer.toString(msg.arg1), msg.arg1);
2233                mSystemServiceManager.switchUser(msg.arg1);
2234                break;
2235            }
2236            case ENTER_ANIMATION_COMPLETE_MSG: {
2237                synchronized (ActivityManagerService.this) {
2238                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2239                    if (r != null && r.app != null && r.app.thread != null) {
2240                        try {
2241                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2242                        } catch (RemoteException e) {
2243                        }
2244                    }
2245                }
2246                break;
2247            }
2248            case FINISH_BOOTING_MSG: {
2249                if (msg.arg1 != 0) {
2250                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2251                    finishBooting();
2252                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2253                }
2254                if (msg.arg2 != 0) {
2255                    enableScreenAfterBoot();
2256                }
2257                break;
2258            }
2259            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2260                try {
2261                    Locale l = (Locale) msg.obj;
2262                    IBinder service = ServiceManager.getService("mount");
2263                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2264                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2265                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2266                } catch (RemoteException e) {
2267                    Log.e(TAG, "Error storing locale for decryption UI", e);
2268                }
2269                break;
2270            }
2271            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2272                final int uid = msg.arg1;
2273                final byte[] firstPacket = (byte[]) msg.obj;
2274
2275                synchronized (mPidsSelfLocked) {
2276                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2277                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2278                        if (p.uid == uid) {
2279                            try {
2280                                p.thread.notifyCleartextNetwork(firstPacket);
2281                            } catch (RemoteException ignored) {
2282                            }
2283                        }
2284                    }
2285                }
2286                break;
2287            }
2288            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2289                final String procName;
2290                final int uid;
2291                final long memLimit;
2292                final String reportPackage;
2293                synchronized (ActivityManagerService.this) {
2294                    procName = mMemWatchDumpProcName;
2295                    uid = mMemWatchDumpUid;
2296                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2297                    if (val == null) {
2298                        val = mMemWatchProcesses.get(procName, 0);
2299                    }
2300                    if (val != null) {
2301                        memLimit = val.first;
2302                        reportPackage = val.second;
2303                    } else {
2304                        memLimit = 0;
2305                        reportPackage = null;
2306                    }
2307                }
2308                if (procName == null) {
2309                    return;
2310                }
2311
2312                if (DEBUG_PSS) Slog.d(TAG_PSS,
2313                        "Showing dump heap notification from " + procName + "/" + uid);
2314
2315                INotificationManager inm = NotificationManager.getService();
2316                if (inm == null) {
2317                    return;
2318                }
2319
2320                String text = mContext.getString(R.string.dump_heap_notification, procName);
2321
2322
2323                Intent deleteIntent = new Intent();
2324                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2325                Intent intent = new Intent();
2326                intent.setClassName("android", DumpHeapActivity.class.getName());
2327                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2328                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2329                if (reportPackage != null) {
2330                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2331                }
2332                int userId = UserHandle.getUserId(uid);
2333                Notification notification =
2334                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2335                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2336                        .setWhen(0)
2337                        .setOngoing(true)
2338                        .setAutoCancel(true)
2339                        .setTicker(text)
2340                        .setColor(mContext.getColor(
2341                                com.android.internal.R.color.system_notification_accent_color))
2342                        .setContentTitle(text)
2343                        .setContentText(
2344                                mContext.getText(R.string.dump_heap_notification_detail))
2345                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2346                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2347                                new UserHandle(userId)))
2348                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2349                                deleteIntent, 0, UserHandle.SYSTEM))
2350                        .build();
2351
2352                try {
2353                    inm.enqueueNotificationWithTag("android", "android", null,
2354                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2355                            notification, userId);
2356                } catch (RuntimeException e) {
2357                    Slog.w(ActivityManagerService.TAG,
2358                            "Error showing notification for dump heap", e);
2359                } catch (RemoteException e) {
2360                }
2361            } break;
2362            case DELETE_DUMPHEAP_MSG: {
2363                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2364                        null, DumpHeapActivity.JAVA_URI,
2365                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2366                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2367                        UserHandle.myUserId());
2368                synchronized (ActivityManagerService.this) {
2369                    mMemWatchDumpFile = null;
2370                    mMemWatchDumpProcName = null;
2371                    mMemWatchDumpPid = -1;
2372                    mMemWatchDumpUid = -1;
2373                }
2374            } break;
2375            case FOREGROUND_PROFILE_CHANGED_MSG: {
2376                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2377            } break;
2378            case REPORT_TIME_TRACKER_MSG: {
2379                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2380                tracker.deliverResult(mContext);
2381            } break;
2382            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2383                mUserController.dispatchUserSwitchComplete(msg.arg1);
2384            } break;
2385            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2386                mUserController.dispatchLockedBootComplete(msg.arg1);
2387            } break;
2388            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2389                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2390                try {
2391                    connection.shutdown();
2392                } catch (RemoteException e) {
2393                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2394                }
2395                // Only a UiAutomation can set this flag and now that
2396                // it is finished we make sure it is reset to its default.
2397                mUserIsMonkey = false;
2398            } break;
2399            case IDLE_UIDS_MSG: {
2400                idleUids();
2401            } break;
2402            case VR_MODE_CHANGE_MSG: {
2403                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2404                    return;
2405                }
2406                synchronized (ActivityManagerService.this) {
2407                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2408                    mWindowManager.disableNonVrUi(disableNonVrUi);
2409                    if (disableNonVrUi) {
2410                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2411                        // then remove the pinned stack.
2412                        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2413                                PINNED_STACK_ID);
2414                        if (pinnedStack != null) {
2415                            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2416                        }
2417                    }
2418                }
2419            } break;
2420            case NOTIFY_VR_SLEEPING_MSG: {
2421                notifyVrManagerOfSleepState(msg.arg1 != 0);
2422            } break;
2423            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2424                synchronized (ActivityManagerService.this) {
2425                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2426                        ProcessRecord r = mLruProcesses.get(i);
2427                        if (r.thread != null) {
2428                            try {
2429                                r.thread.handleTrustStorageUpdate();
2430                            } catch (RemoteException ex) {
2431                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2432                                        r.info.processName);
2433                            }
2434                        }
2435                    }
2436                }
2437            } break;
2438            }
2439        }
2440    };
2441
2442    static final int COLLECT_PSS_BG_MSG = 1;
2443
2444    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2445        @Override
2446        public void handleMessage(Message msg) {
2447            switch (msg.what) {
2448            case COLLECT_PSS_BG_MSG: {
2449                long start = SystemClock.uptimeMillis();
2450                MemInfoReader memInfo = null;
2451                synchronized (ActivityManagerService.this) {
2452                    if (mFullPssPending) {
2453                        mFullPssPending = false;
2454                        memInfo = new MemInfoReader();
2455                    }
2456                }
2457                if (memInfo != null) {
2458                    updateCpuStatsNow();
2459                    long nativeTotalPss = 0;
2460                    final List<ProcessCpuTracker.Stats> stats;
2461                    synchronized (mProcessCpuTracker) {
2462                        stats = mProcessCpuTracker.getStats( (st)-> {
2463                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2464                        });
2465                    }
2466                    final int N = stats.size();
2467                    for (int j = 0; j < N; j++) {
2468                        synchronized (mPidsSelfLocked) {
2469                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2470                                // This is one of our own processes; skip it.
2471                                continue;
2472                            }
2473                        }
2474                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2475                    }
2476                    memInfo.readMemInfo();
2477                    synchronized (ActivityManagerService.this) {
2478                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2479                                + (SystemClock.uptimeMillis()-start) + "ms");
2480                        final long cachedKb = memInfo.getCachedSizeKb();
2481                        final long freeKb = memInfo.getFreeSizeKb();
2482                        final long zramKb = memInfo.getZramTotalSizeKb();
2483                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2484                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2485                                kernelKb*1024, nativeTotalPss*1024);
2486                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2487                                nativeTotalPss);
2488                    }
2489                }
2490
2491                int num = 0;
2492                long[] tmp = new long[2];
2493                do {
2494                    ProcessRecord proc;
2495                    int procState;
2496                    int pid;
2497                    long lastPssTime;
2498                    synchronized (ActivityManagerService.this) {
2499                        if (mPendingPssProcesses.size() <= 0) {
2500                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2501                                    "Collected PSS of " + num + " processes in "
2502                                    + (SystemClock.uptimeMillis() - start) + "ms");
2503                            mPendingPssProcesses.clear();
2504                            return;
2505                        }
2506                        proc = mPendingPssProcesses.remove(0);
2507                        procState = proc.pssProcState;
2508                        lastPssTime = proc.lastPssTime;
2509                        if (proc.thread != null && procState == proc.setProcState
2510                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2511                                        < SystemClock.uptimeMillis()) {
2512                            pid = proc.pid;
2513                        } else {
2514                            proc = null;
2515                            pid = 0;
2516                        }
2517                    }
2518                    if (proc != null) {
2519                        long pss = Debug.getPss(pid, tmp, null);
2520                        synchronized (ActivityManagerService.this) {
2521                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2522                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2523                                num++;
2524                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2525                                        SystemClock.uptimeMillis());
2526                            }
2527                        }
2528                    }
2529                } while (true);
2530            }
2531            }
2532        }
2533    };
2534
2535    public void setSystemProcess() {
2536        try {
2537            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2538            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2539            ServiceManager.addService("meminfo", new MemBinder(this));
2540            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2541            ServiceManager.addService("dbinfo", new DbBinder(this));
2542            if (MONITOR_CPU_USAGE) {
2543                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2544            }
2545            ServiceManager.addService("permission", new PermissionController(this));
2546            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2547
2548            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2549                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2550            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2551
2552            synchronized (this) {
2553                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2554                app.persistent = true;
2555                app.pid = MY_PID;
2556                app.maxAdj = ProcessList.SYSTEM_ADJ;
2557                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2558                synchronized (mPidsSelfLocked) {
2559                    mPidsSelfLocked.put(app.pid, app);
2560                }
2561                updateLruProcessLocked(app, false, null);
2562                updateOomAdjLocked();
2563            }
2564        } catch (PackageManager.NameNotFoundException e) {
2565            throw new RuntimeException(
2566                    "Unable to find android system package", e);
2567        }
2568    }
2569
2570    public void setWindowManager(WindowManagerService wm) {
2571        mWindowManager = wm;
2572        mStackSupervisor.setWindowManager(wm);
2573        mActivityStarter.setWindowManager(wm);
2574    }
2575
2576    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2577        mUsageStatsService = usageStatsManager;
2578    }
2579
2580    public void startObservingNativeCrashes() {
2581        final NativeCrashListener ncl = new NativeCrashListener(this);
2582        ncl.start();
2583    }
2584
2585    public IAppOpsService getAppOpsService() {
2586        return mAppOpsService;
2587    }
2588
2589    static class MemBinder extends Binder {
2590        ActivityManagerService mActivityManagerService;
2591        MemBinder(ActivityManagerService activityManagerService) {
2592            mActivityManagerService = activityManagerService;
2593        }
2594
2595        @Override
2596        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2597            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2598                    "meminfo", pw)) return;
2599            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2600        }
2601    }
2602
2603    static class GraphicsBinder extends Binder {
2604        ActivityManagerService mActivityManagerService;
2605        GraphicsBinder(ActivityManagerService activityManagerService) {
2606            mActivityManagerService = activityManagerService;
2607        }
2608
2609        @Override
2610        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2611            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2612                    "gfxinfo", pw)) return;
2613            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2614        }
2615    }
2616
2617    static class DbBinder extends Binder {
2618        ActivityManagerService mActivityManagerService;
2619        DbBinder(ActivityManagerService activityManagerService) {
2620            mActivityManagerService = activityManagerService;
2621        }
2622
2623        @Override
2624        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2625            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2626                    "dbinfo", pw)) return;
2627            mActivityManagerService.dumpDbInfo(fd, pw, args);
2628        }
2629    }
2630
2631    static class CpuBinder extends Binder {
2632        ActivityManagerService mActivityManagerService;
2633        CpuBinder(ActivityManagerService activityManagerService) {
2634            mActivityManagerService = activityManagerService;
2635        }
2636
2637        @Override
2638        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2639            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2640                    "cpuinfo", pw)) return;
2641            synchronized (mActivityManagerService.mProcessCpuTracker) {
2642                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2643                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2644                        SystemClock.uptimeMillis()));
2645            }
2646        }
2647    }
2648
2649    public static final class Lifecycle extends SystemService {
2650        private final ActivityManagerService mService;
2651
2652        public Lifecycle(Context context) {
2653            super(context);
2654            mService = new ActivityManagerService(context);
2655        }
2656
2657        @Override
2658        public void onStart() {
2659            mService.start();
2660        }
2661
2662        public ActivityManagerService getService() {
2663            return mService;
2664        }
2665    }
2666
2667    @VisibleForTesting
2668    public ActivityManagerService(Injector injector) {
2669        mInjector = injector;
2670        mContext = mInjector.getContext();
2671        mUiContext = null;
2672        GL_ES_VERSION = 0;
2673        mActivityStarter = null;
2674        mAppErrors = null;
2675        mAppOpsService = mInjector.getAppOpsService(null, null);
2676        mBatteryStatsService = null;
2677        mCompatModePackages = null;
2678        mConstants = null;
2679        mGrantFile = null;
2680        mHandler = null;
2681        mHandlerThread = null;
2682        mIntentFirewall = null;
2683        mKeyguardController = null;
2684        mPermissionReviewRequired = false;
2685        mProcessCpuThread = null;
2686        mProcessStats = null;
2687        mProviderMap = null;
2688        mRecentTasks = null;
2689        mServices = null;
2690        mStackSupervisor = null;
2691        mSystemThread = null;
2692        mTaskChangeNotificationController = null;
2693        mUiHandler = injector.getUiHandler(null);
2694        mUserController = null;
2695        mVrController = null;
2696    }
2697
2698    // Note: This method is invoked on the main thread but may need to attach various
2699    // handlers to other threads.  So take care to be explicit about the looper.
2700    public ActivityManagerService(Context systemContext) {
2701        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2702        mInjector = new Injector();
2703        mContext = systemContext;
2704
2705        mFactoryTest = FactoryTest.getMode();
2706        mSystemThread = ActivityThread.currentActivityThread();
2707        mUiContext = mSystemThread.getSystemUiContext();
2708
2709        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2710
2711        mPermissionReviewRequired = mContext.getResources().getBoolean(
2712                com.android.internal.R.bool.config_permissionReviewRequired);
2713
2714        mHandlerThread = new ServiceThread(TAG,
2715                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2716        mHandlerThread.start();
2717        mHandler = new MainHandler(mHandlerThread.getLooper());
2718        mUiHandler = mInjector.getUiHandler(this);
2719
2720        mConstants = new ActivityManagerConstants(this, mHandler);
2721
2722        /* static; one-time init here */
2723        if (sKillHandler == null) {
2724            sKillThread = new ServiceThread(TAG + ":kill",
2725                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2726            sKillThread.start();
2727            sKillHandler = new KillHandler(sKillThread.getLooper());
2728        }
2729
2730        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2731                "foreground", BROADCAST_FG_TIMEOUT, false);
2732        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2733                "background", BROADCAST_BG_TIMEOUT, true);
2734        mBroadcastQueues[0] = mFgBroadcastQueue;
2735        mBroadcastQueues[1] = mBgBroadcastQueue;
2736
2737        mServices = new ActiveServices(this);
2738        mProviderMap = new ProviderMap(this);
2739        mAppErrors = new AppErrors(mUiContext, this);
2740
2741        // TODO: Move creation of battery stats service outside of activity manager service.
2742        File dataDir = Environment.getDataDirectory();
2743        File systemDir = new File(dataDir, "system");
2744        systemDir.mkdirs();
2745        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2746        mBatteryStatsService.getActiveStatistics().readLocked();
2747        mBatteryStatsService.scheduleWriteToDisk();
2748        mOnBattery = DEBUG_POWER ? true
2749                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2750        mBatteryStatsService.getActiveStatistics().setCallback(this);
2751
2752        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2753
2754        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2755        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2756                new IAppOpsCallback.Stub() {
2757                    @Override public void opChanged(int op, int uid, String packageName) {
2758                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2759                            if (mAppOpsService.checkOperation(op, uid, packageName)
2760                                    != AppOpsManager.MODE_ALLOWED) {
2761                                runInBackgroundDisabled(uid);
2762                            }
2763                        }
2764                    }
2765                });
2766
2767        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2768
2769        mUserController = new UserController(this);
2770
2771        mVrController = new VrController(this);
2772
2773        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2774            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2775
2776        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2777            mUseFifoUiScheduling = true;
2778        }
2779
2780        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2781        mTempConfig.setToDefaults();
2782        mTempConfig.setLocales(LocaleList.getDefault());
2783        mConfigurationSeq = mTempConfig.seq = 1;
2784        mStackSupervisor = createStackSupervisor();
2785        mStackSupervisor.onConfigurationChanged(mTempConfig);
2786        mKeyguardController = mStackSupervisor.mKeyguardController;
2787        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2788        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2789        mTaskChangeNotificationController =
2790                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2791        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2792        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2793
2794        mProcessCpuThread = new Thread("CpuTracker") {
2795            @Override
2796            public void run() {
2797                synchronized (mProcessCpuTracker) {
2798                    mProcessCpuInitLatch.countDown();
2799                    mProcessCpuTracker.init();
2800                }
2801                while (true) {
2802                    try {
2803                        try {
2804                            synchronized(this) {
2805                                final long now = SystemClock.uptimeMillis();
2806                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2807                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2808                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2809                                //        + ", write delay=" + nextWriteDelay);
2810                                if (nextWriteDelay < nextCpuDelay) {
2811                                    nextCpuDelay = nextWriteDelay;
2812                                }
2813                                if (nextCpuDelay > 0) {
2814                                    mProcessCpuMutexFree.set(true);
2815                                    this.wait(nextCpuDelay);
2816                                }
2817                            }
2818                        } catch (InterruptedException e) {
2819                        }
2820                        updateCpuStatsNow();
2821                    } catch (Exception e) {
2822                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2823                    }
2824                }
2825            }
2826        };
2827
2828        Watchdog.getInstance().addMonitor(this);
2829        Watchdog.getInstance().addThread(mHandler);
2830    }
2831
2832    protected ActivityStackSupervisor createStackSupervisor() {
2833        return new ActivityStackSupervisor(this, mHandler.getLooper());
2834    }
2835
2836    public void setSystemServiceManager(SystemServiceManager mgr) {
2837        mSystemServiceManager = mgr;
2838    }
2839
2840    public void setInstaller(Installer installer) {
2841        mInstaller = installer;
2842    }
2843
2844    private void start() {
2845        removeAllProcessGroups();
2846        mProcessCpuThread.start();
2847
2848        mBatteryStatsService.publish(mContext);
2849        mAppOpsService.publish(mContext);
2850        Slog.d("AppOps", "AppOpsService published");
2851        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2852        // Wait for the synchronized block started in mProcessCpuThread,
2853        // so that any other acccess to mProcessCpuTracker from main thread
2854        // will be blocked during mProcessCpuTracker initialization.
2855        try {
2856            mProcessCpuInitLatch.await();
2857        } catch (InterruptedException e) {
2858            Slog.wtf(TAG, "Interrupted wait during start", e);
2859            Thread.currentThread().interrupt();
2860            throw new IllegalStateException("Interrupted wait during start");
2861        }
2862    }
2863
2864    void onUserStoppedLocked(int userId) {
2865        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2866    }
2867
2868    public void initPowerManagement() {
2869        mStackSupervisor.initPowerManagement();
2870        mBatteryStatsService.initPowerManagement();
2871        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2872        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2873        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2874        mVoiceWakeLock.setReferenceCounted(false);
2875    }
2876
2877    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2878        if (mBackgroundLaunchBroadcasts == null) {
2879            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2880        }
2881        return mBackgroundLaunchBroadcasts;
2882    }
2883
2884    @Override
2885    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2886            throws RemoteException {
2887        if (code == SYSPROPS_TRANSACTION) {
2888            // We need to tell all apps about the system property change.
2889            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2890            synchronized(this) {
2891                final int NP = mProcessNames.getMap().size();
2892                for (int ip=0; ip<NP; ip++) {
2893                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2894                    final int NA = apps.size();
2895                    for (int ia=0; ia<NA; ia++) {
2896                        ProcessRecord app = apps.valueAt(ia);
2897                        if (app.thread != null) {
2898                            procs.add(app.thread.asBinder());
2899                        }
2900                    }
2901                }
2902            }
2903
2904            int N = procs.size();
2905            for (int i=0; i<N; i++) {
2906                Parcel data2 = Parcel.obtain();
2907                try {
2908                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2909                            Binder.FLAG_ONEWAY);
2910                } catch (RemoteException e) {
2911                }
2912                data2.recycle();
2913            }
2914        }
2915        try {
2916            return super.onTransact(code, data, reply, flags);
2917        } catch (RuntimeException e) {
2918            // The activity manager only throws security exceptions, so let's
2919            // log all others.
2920            if (!(e instanceof SecurityException)) {
2921                Slog.wtf(TAG, "Activity Manager Crash."
2922                        + " UID:" + Binder.getCallingUid()
2923                        + " PID:" + Binder.getCallingPid()
2924                        + " TRANS:" + code, e);
2925            }
2926            throw e;
2927        }
2928    }
2929
2930    void updateCpuStats() {
2931        final long now = SystemClock.uptimeMillis();
2932        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2933            return;
2934        }
2935        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2936            synchronized (mProcessCpuThread) {
2937                mProcessCpuThread.notify();
2938            }
2939        }
2940    }
2941
2942    void updateCpuStatsNow() {
2943        synchronized (mProcessCpuTracker) {
2944            mProcessCpuMutexFree.set(false);
2945            final long now = SystemClock.uptimeMillis();
2946            boolean haveNewCpuStats = false;
2947
2948            if (MONITOR_CPU_USAGE &&
2949                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2950                mLastCpuTime.set(now);
2951                mProcessCpuTracker.update();
2952                if (mProcessCpuTracker.hasGoodLastStats()) {
2953                    haveNewCpuStats = true;
2954                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2955                    //Slog.i(TAG, "Total CPU usage: "
2956                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2957
2958                    // Slog the cpu usage if the property is set.
2959                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2960                        int user = mProcessCpuTracker.getLastUserTime();
2961                        int system = mProcessCpuTracker.getLastSystemTime();
2962                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2963                        int irq = mProcessCpuTracker.getLastIrqTime();
2964                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2965                        int idle = mProcessCpuTracker.getLastIdleTime();
2966
2967                        int total = user + system + iowait + irq + softIrq + idle;
2968                        if (total == 0) total = 1;
2969
2970                        EventLog.writeEvent(EventLogTags.CPU,
2971                                ((user+system+iowait+irq+softIrq) * 100) / total,
2972                                (user * 100) / total,
2973                                (system * 100) / total,
2974                                (iowait * 100) / total,
2975                                (irq * 100) / total,
2976                                (softIrq * 100) / total);
2977                    }
2978                }
2979            }
2980
2981            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2982            synchronized(bstats) {
2983                synchronized(mPidsSelfLocked) {
2984                    if (haveNewCpuStats) {
2985                        if (bstats.startAddingCpuLocked()) {
2986                            int totalUTime = 0;
2987                            int totalSTime = 0;
2988                            final int N = mProcessCpuTracker.countStats();
2989                            for (int i=0; i<N; i++) {
2990                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2991                                if (!st.working) {
2992                                    continue;
2993                                }
2994                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2995                                totalUTime += st.rel_utime;
2996                                totalSTime += st.rel_stime;
2997                                if (pr != null) {
2998                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2999                                    if (ps == null || !ps.isActive()) {
3000                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3001                                                pr.info.uid, pr.processName);
3002                                    }
3003                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3004                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3005                                } else {
3006                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3007                                    if (ps == null || !ps.isActive()) {
3008                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3009                                                bstats.mapUid(st.uid), st.name);
3010                                    }
3011                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3012                                }
3013                            }
3014                            final int userTime = mProcessCpuTracker.getLastUserTime();
3015                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3016                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3017                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3018                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3019                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3020                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3021                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3022                        }
3023                    }
3024                }
3025
3026                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3027                    mLastWriteTime = now;
3028                    mBatteryStatsService.scheduleWriteToDisk();
3029                }
3030            }
3031        }
3032    }
3033
3034    @Override
3035    public void batteryNeedsCpuUpdate() {
3036        updateCpuStatsNow();
3037    }
3038
3039    @Override
3040    public void batteryPowerChanged(boolean onBattery) {
3041        // When plugging in, update the CPU stats first before changing
3042        // the plug state.
3043        updateCpuStatsNow();
3044        synchronized (this) {
3045            synchronized(mPidsSelfLocked) {
3046                mOnBattery = DEBUG_POWER ? true : onBattery;
3047            }
3048        }
3049    }
3050
3051    @Override
3052    public void batterySendBroadcast(Intent intent) {
3053        synchronized (this) {
3054            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3055                    AppOpsManager.OP_NONE, null, false, false,
3056                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3057        }
3058    }
3059
3060    /**
3061     * Initialize the application bind args. These are passed to each
3062     * process when the bindApplication() IPC is sent to the process. They're
3063     * lazily setup to make sure the services are running when they're asked for.
3064     */
3065    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3066        // Isolated processes won't get this optimization, so that we don't
3067        // violate the rules about which services they have access to.
3068        if (isolated) {
3069            if (mIsolatedAppBindArgs == null) {
3070                mIsolatedAppBindArgs = new HashMap<>();
3071                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3072            }
3073            return mIsolatedAppBindArgs;
3074        }
3075
3076        if (mAppBindArgs == null) {
3077            mAppBindArgs = new HashMap<>();
3078
3079            // Setup the application init args
3080            mAppBindArgs.put("package", ServiceManager.getService("package"));
3081            mAppBindArgs.put("window", ServiceManager.getService("window"));
3082            mAppBindArgs.put(Context.ALARM_SERVICE,
3083                    ServiceManager.getService(Context.ALARM_SERVICE));
3084        }
3085        return mAppBindArgs;
3086    }
3087
3088    /**
3089     * Update AMS states when an activity is resumed. This should only be called by
3090     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3091     */
3092    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3093        final TaskRecord task = r.getTask();
3094        if (task.isApplicationTask()) {
3095            if (mCurAppTimeTracker != r.appTimeTracker) {
3096                // We are switching app tracking.  Complete the current one.
3097                if (mCurAppTimeTracker != null) {
3098                    mCurAppTimeTracker.stop();
3099                    mHandler.obtainMessage(
3100                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3101                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3102                    mCurAppTimeTracker = null;
3103                }
3104                if (r.appTimeTracker != null) {
3105                    mCurAppTimeTracker = r.appTimeTracker;
3106                    startTimeTrackingFocusedActivityLocked();
3107                }
3108            } else {
3109                startTimeTrackingFocusedActivityLocked();
3110            }
3111        } else {
3112            r.appTimeTracker = null;
3113        }
3114        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3115        // TODO: Probably not, because we don't want to resume voice on switching
3116        // back to this activity
3117        if (task.voiceInteractor != null) {
3118            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3119        } else {
3120            finishRunningVoiceLocked();
3121
3122            if (mLastResumedActivity != null) {
3123                final IVoiceInteractionSession session;
3124
3125                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3126                if (lastResumedActivityTask != null
3127                        && lastResumedActivityTask.voiceSession != null) {
3128                    session = lastResumedActivityTask.voiceSession;
3129                } else {
3130                    session = mLastResumedActivity.voiceSession;
3131                }
3132
3133                if (session != null) {
3134                    // We had been in a voice interaction session, but now focused has
3135                    // move to something different.  Just finish the session, we can't
3136                    // return to it and retain the proper state and synchronization with
3137                    // the voice interaction service.
3138                    finishVoiceTask(session);
3139                }
3140            }
3141        }
3142
3143        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3144            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3145            mHandler.obtainMessage(
3146                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3147        }
3148        mLastResumedActivity = r;
3149
3150        mWindowManager.setFocusedApp(r.appToken, true);
3151
3152        applyUpdateLockStateLocked(r);
3153        applyUpdateVrModeLocked(r);
3154
3155        EventLogTags.writeAmSetResumedActivity(
3156                r == null ? -1 : r.userId,
3157                r == null ? "NULL" : r.shortComponentName,
3158                reason);
3159    }
3160
3161    @Override
3162    public void setFocusedStack(int stackId) {
3163        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3164        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3165        final long callingId = Binder.clearCallingIdentity();
3166        try {
3167            synchronized (this) {
3168                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3169                if (stack == null) {
3170                    return;
3171                }
3172                final ActivityRecord r = stack.topRunningActivityLocked();
3173                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3174                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3175                }
3176            }
3177        } finally {
3178            Binder.restoreCallingIdentity(callingId);
3179        }
3180    }
3181
3182    @Override
3183    public void setFocusedTask(int taskId) {
3184        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3185        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3186        final long callingId = Binder.clearCallingIdentity();
3187        try {
3188            synchronized (this) {
3189                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3190                if (task == null) {
3191                    return;
3192                }
3193                final ActivityRecord r = task.topRunningActivityLocked();
3194                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3195                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3196                }
3197            }
3198        } finally {
3199            Binder.restoreCallingIdentity(callingId);
3200        }
3201    }
3202
3203    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3204    @Override
3205    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3206        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3207        mTaskChangeNotificationController.registerTaskStackListener(listener);
3208    }
3209
3210    /**
3211     * Unregister a task stack listener so that it stops receiving callbacks.
3212     */
3213    @Override
3214    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3215         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3216         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3217     }
3218
3219    @Override
3220    public void notifyActivityDrawn(IBinder token) {
3221        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3222        synchronized (this) {
3223            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3224            if (r != null) {
3225                r.getStack().notifyActivityDrawnLocked(r);
3226            }
3227        }
3228    }
3229
3230    final void applyUpdateLockStateLocked(ActivityRecord r) {
3231        // Modifications to the UpdateLock state are done on our handler, outside
3232        // the activity manager's locks.  The new state is determined based on the
3233        // state *now* of the relevant activity record.  The object is passed to
3234        // the handler solely for logging detail, not to be consulted/modified.
3235        final boolean nextState = r != null && r.immersive;
3236        mHandler.sendMessage(
3237                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3238    }
3239
3240    final void applyUpdateVrModeLocked(ActivityRecord r) {
3241        mHandler.sendMessage(
3242                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3243    }
3244
3245    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3246        mHandler.sendMessage(
3247                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3248    }
3249
3250    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3251        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3252        if (vrService == null) {
3253            return;
3254        }
3255        vrService.onSleepStateChanged(isSleeping);
3256    }
3257
3258    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3259        Message msg = Message.obtain();
3260        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3261        msg.obj = r.getTask().askedCompatMode ? null : r;
3262        mUiHandler.sendMessage(msg);
3263    }
3264
3265    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3266        final Configuration globalConfig = getGlobalConfiguration();
3267        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3268                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3269            final Message msg = Message.obtain();
3270            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3271            msg.obj = r;
3272            mUiHandler.sendMessage(msg);
3273        }
3274    }
3275
3276    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3277            String what, Object obj, ProcessRecord srcApp) {
3278        app.lastActivityTime = now;
3279
3280        if (app.activities.size() > 0) {
3281            // Don't want to touch dependent processes that are hosting activities.
3282            return index;
3283        }
3284
3285        int lrui = mLruProcesses.lastIndexOf(app);
3286        if (lrui < 0) {
3287            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3288                    + what + " " + obj + " from " + srcApp);
3289            return index;
3290        }
3291
3292        if (lrui >= index) {
3293            // Don't want to cause this to move dependent processes *back* in the
3294            // list as if they were less frequently used.
3295            return index;
3296        }
3297
3298        if (lrui >= mLruProcessActivityStart) {
3299            // Don't want to touch dependent processes that are hosting activities.
3300            return index;
3301        }
3302
3303        mLruProcesses.remove(lrui);
3304        if (index > 0) {
3305            index--;
3306        }
3307        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3308                + " in LRU list: " + app);
3309        mLruProcesses.add(index, app);
3310        return index;
3311    }
3312
3313    static void killProcessGroup(int uid, int pid) {
3314        if (sKillHandler != null) {
3315            sKillHandler.sendMessage(
3316                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3317        } else {
3318            Slog.w(TAG, "Asked to kill process group before system bringup!");
3319            Process.killProcessGroup(uid, pid);
3320        }
3321    }
3322
3323    final void removeLruProcessLocked(ProcessRecord app) {
3324        int lrui = mLruProcesses.lastIndexOf(app);
3325        if (lrui >= 0) {
3326            if (!app.killed) {
3327                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3328                killProcessQuiet(app.pid);
3329                killProcessGroup(app.uid, app.pid);
3330            }
3331            if (lrui <= mLruProcessActivityStart) {
3332                mLruProcessActivityStart--;
3333            }
3334            if (lrui <= mLruProcessServiceStart) {
3335                mLruProcessServiceStart--;
3336            }
3337            mLruProcesses.remove(lrui);
3338        }
3339    }
3340
3341    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3342            ProcessRecord client) {
3343        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3344                || app.treatLikeActivity;
3345        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3346        if (!activityChange && hasActivity) {
3347            // The process has activities, so we are only allowing activity-based adjustments
3348            // to move it.  It should be kept in the front of the list with other
3349            // processes that have activities, and we don't want those to change their
3350            // order except due to activity operations.
3351            return;
3352        }
3353
3354        mLruSeq++;
3355        final long now = SystemClock.uptimeMillis();
3356        app.lastActivityTime = now;
3357
3358        // First a quick reject: if the app is already at the position we will
3359        // put it, then there is nothing to do.
3360        if (hasActivity) {
3361            final int N = mLruProcesses.size();
3362            if (N > 0 && mLruProcesses.get(N-1) == app) {
3363                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3364                return;
3365            }
3366        } else {
3367            if (mLruProcessServiceStart > 0
3368                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3369                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3370                return;
3371            }
3372        }
3373
3374        int lrui = mLruProcesses.lastIndexOf(app);
3375
3376        if (app.persistent && lrui >= 0) {
3377            // We don't care about the position of persistent processes, as long as
3378            // they are in the list.
3379            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3380            return;
3381        }
3382
3383        /* In progress: compute new position first, so we can avoid doing work
3384           if the process is not actually going to move.  Not yet working.
3385        int addIndex;
3386        int nextIndex;
3387        boolean inActivity = false, inService = false;
3388        if (hasActivity) {
3389            // Process has activities, put it at the very tipsy-top.
3390            addIndex = mLruProcesses.size();
3391            nextIndex = mLruProcessServiceStart;
3392            inActivity = true;
3393        } else if (hasService) {
3394            // Process has services, put it at the top of the service list.
3395            addIndex = mLruProcessActivityStart;
3396            nextIndex = mLruProcessServiceStart;
3397            inActivity = true;
3398            inService = true;
3399        } else  {
3400            // Process not otherwise of interest, it goes to the top of the non-service area.
3401            addIndex = mLruProcessServiceStart;
3402            if (client != null) {
3403                int clientIndex = mLruProcesses.lastIndexOf(client);
3404                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3405                        + app);
3406                if (clientIndex >= 0 && addIndex > clientIndex) {
3407                    addIndex = clientIndex;
3408                }
3409            }
3410            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3411        }
3412
3413        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3414                + mLruProcessActivityStart + "): " + app);
3415        */
3416
3417        if (lrui >= 0) {
3418            if (lrui < mLruProcessActivityStart) {
3419                mLruProcessActivityStart--;
3420            }
3421            if (lrui < mLruProcessServiceStart) {
3422                mLruProcessServiceStart--;
3423            }
3424            /*
3425            if (addIndex > lrui) {
3426                addIndex--;
3427            }
3428            if (nextIndex > lrui) {
3429                nextIndex--;
3430            }
3431            */
3432            mLruProcesses.remove(lrui);
3433        }
3434
3435        /*
3436        mLruProcesses.add(addIndex, app);
3437        if (inActivity) {
3438            mLruProcessActivityStart++;
3439        }
3440        if (inService) {
3441            mLruProcessActivityStart++;
3442        }
3443        */
3444
3445        int nextIndex;
3446        if (hasActivity) {
3447            final int N = mLruProcesses.size();
3448            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3449                // Process doesn't have activities, but has clients with
3450                // activities...  move it up, but one below the top (the top
3451                // should always have a real activity).
3452                if (DEBUG_LRU) Slog.d(TAG_LRU,
3453                        "Adding to second-top of LRU activity list: " + app);
3454                mLruProcesses.add(N - 1, app);
3455                // To keep it from spamming the LRU list (by making a bunch of clients),
3456                // we will push down any other entries owned by the app.
3457                final int uid = app.info.uid;
3458                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3459                    ProcessRecord subProc = mLruProcesses.get(i);
3460                    if (subProc.info.uid == uid) {
3461                        // We want to push this one down the list.  If the process after
3462                        // it is for the same uid, however, don't do so, because we don't
3463                        // want them internally to be re-ordered.
3464                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3465                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3466                                    "Pushing uid " + uid + " swapping at " + i + ": "
3467                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3468                            ProcessRecord tmp = mLruProcesses.get(i);
3469                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3470                            mLruProcesses.set(i - 1, tmp);
3471                            i--;
3472                        }
3473                    } else {
3474                        // A gap, we can stop here.
3475                        break;
3476                    }
3477                }
3478            } else {
3479                // Process has activities, put it at the very tipsy-top.
3480                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3481                mLruProcesses.add(app);
3482            }
3483            nextIndex = mLruProcessServiceStart;
3484        } else if (hasService) {
3485            // Process has services, put it at the top of the service list.
3486            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3487            mLruProcesses.add(mLruProcessActivityStart, app);
3488            nextIndex = mLruProcessServiceStart;
3489            mLruProcessActivityStart++;
3490        } else  {
3491            // Process not otherwise of interest, it goes to the top of the non-service area.
3492            int index = mLruProcessServiceStart;
3493            if (client != null) {
3494                // If there is a client, don't allow the process to be moved up higher
3495                // in the list than that client.
3496                int clientIndex = mLruProcesses.lastIndexOf(client);
3497                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3498                        + " when updating " + app);
3499                if (clientIndex <= lrui) {
3500                    // Don't allow the client index restriction to push it down farther in the
3501                    // list than it already is.
3502                    clientIndex = lrui;
3503                }
3504                if (clientIndex >= 0 && index > clientIndex) {
3505                    index = clientIndex;
3506                }
3507            }
3508            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3509            mLruProcesses.add(index, app);
3510            nextIndex = index-1;
3511            mLruProcessActivityStart++;
3512            mLruProcessServiceStart++;
3513        }
3514
3515        // If the app is currently using a content provider or service,
3516        // bump those processes as well.
3517        for (int j=app.connections.size()-1; j>=0; j--) {
3518            ConnectionRecord cr = app.connections.valueAt(j);
3519            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3520                    && cr.binding.service.app != null
3521                    && cr.binding.service.app.lruSeq != mLruSeq
3522                    && !cr.binding.service.app.persistent) {
3523                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3524                        "service connection", cr, app);
3525            }
3526        }
3527        for (int j=app.conProviders.size()-1; j>=0; j--) {
3528            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3529            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3530                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3531                        "provider reference", cpr, app);
3532            }
3533        }
3534    }
3535
3536    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3537        if (uid == SYSTEM_UID) {
3538            // The system gets to run in any process.  If there are multiple
3539            // processes with the same uid, just pick the first (this
3540            // should never happen).
3541            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3542            if (procs == null) return null;
3543            final int procCount = procs.size();
3544            for (int i = 0; i < procCount; i++) {
3545                final int procUid = procs.keyAt(i);
3546                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3547                    // Don't use an app process or different user process for system component.
3548                    continue;
3549                }
3550                return procs.valueAt(i);
3551            }
3552        }
3553        ProcessRecord proc = mProcessNames.get(processName, uid);
3554        if (false && proc != null && !keepIfLarge
3555                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3556                && proc.lastCachedPss >= 4000) {
3557            // Turn this condition on to cause killing to happen regularly, for testing.
3558            if (proc.baseProcessTracker != null) {
3559                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3560            }
3561            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3562        } else if (proc != null && !keepIfLarge
3563                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3564                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3565            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3566            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3567                if (proc.baseProcessTracker != null) {
3568                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3569                }
3570                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3571            }
3572        }
3573        return proc;
3574    }
3575
3576    void notifyPackageUse(String packageName, int reason) {
3577        IPackageManager pm = AppGlobals.getPackageManager();
3578        try {
3579            pm.notifyPackageUse(packageName, reason);
3580        } catch (RemoteException e) {
3581        }
3582    }
3583
3584    boolean isNextTransitionForward() {
3585        int transit = mWindowManager.getPendingAppTransition();
3586        return transit == TRANSIT_ACTIVITY_OPEN
3587                || transit == TRANSIT_TASK_OPEN
3588                || transit == TRANSIT_TASK_TO_FRONT;
3589    }
3590
3591    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3592            String processName, String abiOverride, int uid, Runnable crashHandler) {
3593        synchronized(this) {
3594            ApplicationInfo info = new ApplicationInfo();
3595            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3596            // For isolated processes, the former contains the parent's uid and the latter the
3597            // actual uid of the isolated process.
3598            // In the special case introduced by this method (which is, starting an isolated
3599            // process directly from the SystemServer without an actual parent app process) the
3600            // closest thing to a parent's uid is SYSTEM_UID.
3601            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3602            // the |isolated| logic in the ProcessRecord constructor.
3603            info.uid = SYSTEM_UID;
3604            info.processName = processName;
3605            info.className = entryPoint;
3606            info.packageName = "android";
3607            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3608            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3609                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3610                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3611                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3612                    crashHandler);
3613            return proc != null ? proc.pid : 0;
3614        }
3615    }
3616
3617    final ProcessRecord startProcessLocked(String processName,
3618            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3619            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3620            boolean isolated, boolean keepIfLarge) {
3621        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3622                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3623                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3624                null /* crashHandler */);
3625    }
3626
3627    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3628            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3629            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3630            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3631        long startTime = SystemClock.elapsedRealtime();
3632        ProcessRecord app;
3633        if (!isolated) {
3634            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3635            checkTime(startTime, "startProcess: after getProcessRecord");
3636
3637            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3638                // If we are in the background, then check to see if this process
3639                // is bad.  If so, we will just silently fail.
3640                if (mAppErrors.isBadProcessLocked(info)) {
3641                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3642                            + "/" + info.processName);
3643                    return null;
3644                }
3645            } else {
3646                // When the user is explicitly starting a process, then clear its
3647                // crash count so that we won't make it bad until they see at
3648                // least one crash dialog again, and make the process good again
3649                // if it had been bad.
3650                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3651                        + "/" + info.processName);
3652                mAppErrors.resetProcessCrashTimeLocked(info);
3653                if (mAppErrors.isBadProcessLocked(info)) {
3654                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3655                            UserHandle.getUserId(info.uid), info.uid,
3656                            info.processName);
3657                    mAppErrors.clearBadProcessLocked(info);
3658                    if (app != null) {
3659                        app.bad = false;
3660                    }
3661                }
3662            }
3663        } else {
3664            // If this is an isolated process, it can't re-use an existing process.
3665            app = null;
3666        }
3667
3668        // We don't have to do anything more if:
3669        // (1) There is an existing application record; and
3670        // (2) The caller doesn't think it is dead, OR there is no thread
3671        //     object attached to it so we know it couldn't have crashed; and
3672        // (3) There is a pid assigned to it, so it is either starting or
3673        //     already running.
3674        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3675                + " app=" + app + " knownToBeDead=" + knownToBeDead
3676                + " thread=" + (app != null ? app.thread : null)
3677                + " pid=" + (app != null ? app.pid : -1));
3678        if (app != null && app.pid > 0) {
3679            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3680                // We already have the app running, or are waiting for it to
3681                // come up (we have a pid but not yet its thread), so keep it.
3682                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3683                // If this is a new package in the process, add the package to the list
3684                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3685                checkTime(startTime, "startProcess: done, added package to proc");
3686                return app;
3687            }
3688
3689            // An application record is attached to a previous process,
3690            // clean it up now.
3691            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3692            checkTime(startTime, "startProcess: bad proc running, killing");
3693            killProcessGroup(app.uid, app.pid);
3694            handleAppDiedLocked(app, true, true);
3695            checkTime(startTime, "startProcess: done killing old proc");
3696        }
3697
3698        String hostingNameStr = hostingName != null
3699                ? hostingName.flattenToShortString() : null;
3700
3701        if (app == null) {
3702            checkTime(startTime, "startProcess: creating new process record");
3703            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3704            if (app == null) {
3705                Slog.w(TAG, "Failed making new process record for "
3706                        + processName + "/" + info.uid + " isolated=" + isolated);
3707                return null;
3708            }
3709            app.crashHandler = crashHandler;
3710            checkTime(startTime, "startProcess: done creating new process record");
3711        } else {
3712            // If this is a new package in the process, add the package to the list
3713            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3714            checkTime(startTime, "startProcess: added package to existing proc");
3715        }
3716
3717        // If the system is not ready yet, then hold off on starting this
3718        // process until it is.
3719        if (!mProcessesReady
3720                && !isAllowedWhileBooting(info)
3721                && !allowWhileBooting) {
3722            if (!mProcessesOnHold.contains(app)) {
3723                mProcessesOnHold.add(app);
3724            }
3725            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3726                    "System not ready, putting on hold: " + app);
3727            checkTime(startTime, "startProcess: returning with proc on hold");
3728            return app;
3729        }
3730
3731        checkTime(startTime, "startProcess: stepping in to startProcess");
3732        startProcessLocked(
3733                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3734        checkTime(startTime, "startProcess: done starting proc!");
3735        return (app.pid != 0) ? app : null;
3736    }
3737
3738    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3739        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3740    }
3741
3742    private final void startProcessLocked(ProcessRecord app,
3743            String hostingType, String hostingNameStr) {
3744        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3745                null /* entryPoint */, null /* entryPointArgs */);
3746    }
3747
3748    private final void startProcessLocked(ProcessRecord app, String hostingType,
3749            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3750        long startTime = SystemClock.elapsedRealtime();
3751        if (app.pid > 0 && app.pid != MY_PID) {
3752            checkTime(startTime, "startProcess: removing from pids map");
3753            synchronized (mPidsSelfLocked) {
3754                mPidsSelfLocked.remove(app.pid);
3755                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3756            }
3757            checkTime(startTime, "startProcess: done removing from pids map");
3758            app.setPid(0);
3759        }
3760
3761        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3762                "startProcessLocked removing on hold: " + app);
3763        mProcessesOnHold.remove(app);
3764
3765        checkTime(startTime, "startProcess: starting to update cpu stats");
3766        updateCpuStats();
3767        checkTime(startTime, "startProcess: done updating cpu stats");
3768
3769        try {
3770            try {
3771                final int userId = UserHandle.getUserId(app.uid);
3772                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3773            } catch (RemoteException e) {
3774                throw e.rethrowAsRuntimeException();
3775            }
3776
3777            int uid = app.uid;
3778            int[] gids = null;
3779            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3780            if (!app.isolated) {
3781                int[] permGids = null;
3782                try {
3783                    checkTime(startTime, "startProcess: getting gids from package manager");
3784                    final IPackageManager pm = AppGlobals.getPackageManager();
3785                    permGids = pm.getPackageGids(app.info.packageName,
3786                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3787                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3788                            StorageManagerInternal.class);
3789                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3790                            app.info.packageName);
3791                } catch (RemoteException e) {
3792                    throw e.rethrowAsRuntimeException();
3793                }
3794
3795                /*
3796                 * Add shared application and profile GIDs so applications can share some
3797                 * resources like shared libraries and access user-wide resources
3798                 */
3799                if (ArrayUtils.isEmpty(permGids)) {
3800                    gids = new int[3];
3801                } else {
3802                    gids = new int[permGids.length + 3];
3803                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3804                }
3805                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3806                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3807                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3808            }
3809            checkTime(startTime, "startProcess: building args");
3810            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3811                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3812                        && mTopComponent != null
3813                        && app.processName.equals(mTopComponent.getPackageName())) {
3814                    uid = 0;
3815                }
3816                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3817                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3818                    uid = 0;
3819                }
3820            }
3821            int debugFlags = 0;
3822            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3823                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3824                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3825                // Also turn on CheckJNI for debuggable apps. It's quite
3826                // awkward to turn on otherwise.
3827                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3828            }
3829            // Run the app in safe mode if its manifest requests so or the
3830            // system is booted in safe mode.
3831            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3832                mSafeMode == true) {
3833                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3834            }
3835            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3836                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3837            }
3838            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3839            if ("true".equals(genDebugInfoProperty)) {
3840                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3841            }
3842            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3843                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3844            }
3845            if ("1".equals(SystemProperties.get("debug.assert"))) {
3846                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3847            }
3848            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3849                // Enable all debug flags required by the native debugger.
3850                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3851                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3852                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3853                mNativeDebuggingApp = null;
3854            }
3855
3856            String invokeWith = null;
3857            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3858                // Debuggable apps may include a wrapper script with their library directory.
3859                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3860                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3861                try {
3862                    if (new File(wrapperFileName).exists()) {
3863                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3864                    }
3865                } finally {
3866                    StrictMode.setThreadPolicy(oldPolicy);
3867                }
3868            }
3869
3870            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3871            if (requiredAbi == null) {
3872                requiredAbi = Build.SUPPORTED_ABIS[0];
3873            }
3874
3875            String instructionSet = null;
3876            if (app.info.primaryCpuAbi != null) {
3877                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3878            }
3879
3880            app.gids = gids;
3881            app.requiredAbi = requiredAbi;
3882            app.instructionSet = instructionSet;
3883
3884            // the per-user SELinux context must be set
3885            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3886                Slog.wtf(TAG, "SELinux tag not defined",
3887                        new IllegalStateException("SELinux tag not defined for "
3888                        + app.info.packageName + " (uid " + app.uid + ")"));
3889            }
3890            final String seInfo = app.info.seInfo
3891                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3892            // Start the process.  It will either succeed and return a result containing
3893            // the PID of the new process, or else throw a RuntimeException.
3894            boolean isActivityProcess = (entryPoint == null);
3895            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3896            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3897                    app.processName);
3898            checkTime(startTime, "startProcess: asking zygote to start proc");
3899            ProcessStartResult startResult;
3900            if (hostingType.equals("webview_service")) {
3901                startResult = startWebView(entryPoint,
3902                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3903                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3904                        app.info.dataDir, null, entryPointArgs);
3905            } else {
3906                startResult = Process.start(entryPoint,
3907                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3908                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3909                        app.info.dataDir, invokeWith, entryPointArgs);
3910            }
3911            checkTime(startTime, "startProcess: returned from zygote!");
3912            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3913
3914            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3915            checkTime(startTime, "startProcess: done updating battery stats");
3916
3917            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3918                    UserHandle.getUserId(uid), startResult.pid, uid,
3919                    app.processName, hostingType,
3920                    hostingNameStr != null ? hostingNameStr : "");
3921
3922            try {
3923                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3924                        seInfo, app.info.sourceDir, startResult.pid);
3925            } catch (RemoteException ex) {
3926                // Ignore
3927            }
3928
3929            if (app.persistent) {
3930                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3931            }
3932
3933            checkTime(startTime, "startProcess: building log message");
3934            StringBuilder buf = mStringBuilder;
3935            buf.setLength(0);
3936            buf.append("Start proc ");
3937            buf.append(startResult.pid);
3938            buf.append(':');
3939            buf.append(app.processName);
3940            buf.append('/');
3941            UserHandle.formatUid(buf, uid);
3942            if (!isActivityProcess) {
3943                buf.append(" [");
3944                buf.append(entryPoint);
3945                buf.append("]");
3946            }
3947            buf.append(" for ");
3948            buf.append(hostingType);
3949            if (hostingNameStr != null) {
3950                buf.append(" ");
3951                buf.append(hostingNameStr);
3952            }
3953            Slog.i(TAG, buf.toString());
3954            app.setPid(startResult.pid);
3955            app.usingWrapper = startResult.usingWrapper;
3956            app.removed = false;
3957            app.killed = false;
3958            app.killedByAm = false;
3959            checkTime(startTime, "startProcess: starting to update pids map");
3960            ProcessRecord oldApp;
3961            synchronized (mPidsSelfLocked) {
3962                oldApp = mPidsSelfLocked.get(startResult.pid);
3963            }
3964            // If there is already an app occupying that pid that hasn't been cleaned up
3965            if (oldApp != null && !app.isolated) {
3966                // Clean up anything relating to this pid first
3967                Slog.w(TAG, "Reusing pid " + startResult.pid
3968                        + " while app is still mapped to it");
3969                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3970                        true /*replacingPid*/);
3971            }
3972            synchronized (mPidsSelfLocked) {
3973                this.mPidsSelfLocked.put(startResult.pid, app);
3974                if (isActivityProcess) {
3975                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3976                    msg.obj = app;
3977                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3978                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3979                }
3980            }
3981            checkTime(startTime, "startProcess: done updating pids map");
3982        } catch (RuntimeException e) {
3983            Slog.e(TAG, "Failure starting process " + app.processName, e);
3984
3985            // Something went very wrong while trying to start this process; one
3986            // common case is when the package is frozen due to an active
3987            // upgrade. To recover, clean up any active bookkeeping related to
3988            // starting this process. (We already invoked this method once when
3989            // the package was initially frozen through KILL_APPLICATION_MSG, so
3990            // it doesn't hurt to use it again.)
3991            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3992                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3993        }
3994    }
3995
3996    void updateUsageStats(ActivityRecord component, boolean resumed) {
3997        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3998                "updateUsageStats: comp=" + component + "res=" + resumed);
3999        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4000        if (resumed) {
4001            if (mUsageStatsService != null) {
4002                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4003                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4004            }
4005            synchronized (stats) {
4006                stats.noteActivityResumedLocked(component.app.uid);
4007            }
4008        } else {
4009            if (mUsageStatsService != null) {
4010                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4011                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4012            }
4013            synchronized (stats) {
4014                stats.noteActivityPausedLocked(component.app.uid);
4015            }
4016        }
4017    }
4018
4019    Intent getHomeIntent() {
4020        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4021        intent.setComponent(mTopComponent);
4022        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4023        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4024            intent.addCategory(Intent.CATEGORY_HOME);
4025        }
4026        return intent;
4027    }
4028
4029    boolean startHomeActivityLocked(int userId, String reason) {
4030        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4031                && mTopAction == null) {
4032            // We are running in factory test mode, but unable to find
4033            // the factory test app, so just sit around displaying the
4034            // error message and don't try to start anything.
4035            return false;
4036        }
4037        Intent intent = getHomeIntent();
4038        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4039        if (aInfo != null) {
4040            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4041            // Don't do this if the home app is currently being
4042            // instrumented.
4043            aInfo = new ActivityInfo(aInfo);
4044            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4045            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4046                    aInfo.applicationInfo.uid, true);
4047            if (app == null || app.instr == null) {
4048                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4049                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4050                // For ANR debugging to verify if the user activity is the one that actually
4051                // launched.
4052                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4053                mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4054            }
4055        } else {
4056            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4057        }
4058
4059        return true;
4060    }
4061
4062    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4063        ActivityInfo ai = null;
4064        ComponentName comp = intent.getComponent();
4065        try {
4066            if (comp != null) {
4067                // Factory test.
4068                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4069            } else {
4070                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4071                        intent,
4072                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4073                        flags, userId);
4074
4075                if (info != null) {
4076                    ai = info.activityInfo;
4077                }
4078            }
4079        } catch (RemoteException e) {
4080            // ignore
4081        }
4082
4083        return ai;
4084    }
4085
4086    /**
4087     * Starts the "new version setup screen" if appropriate.
4088     */
4089    void startSetupActivityLocked() {
4090        // Only do this once per boot.
4091        if (mCheckedForSetup) {
4092            return;
4093        }
4094
4095        // We will show this screen if the current one is a different
4096        // version than the last one shown, and we are not running in
4097        // low-level factory test mode.
4098        final ContentResolver resolver = mContext.getContentResolver();
4099        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4100                Settings.Global.getInt(resolver,
4101                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4102            mCheckedForSetup = true;
4103
4104            // See if we should be showing the platform update setup UI.
4105            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4106            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4107                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4108            if (!ris.isEmpty()) {
4109                final ResolveInfo ri = ris.get(0);
4110                String vers = ri.activityInfo.metaData != null
4111                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4112                        : null;
4113                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4114                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4115                            Intent.METADATA_SETUP_VERSION);
4116                }
4117                String lastVers = Settings.Secure.getString(
4118                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4119                if (vers != null && !vers.equals(lastVers)) {
4120                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4121                    intent.setComponent(new ComponentName(
4122                            ri.activityInfo.packageName, ri.activityInfo.name));
4123                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4124                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4125                            null, 0, 0, 0, null, false, false, null, null, null,
4126                            "startSetupActivity");
4127                }
4128            }
4129        }
4130    }
4131
4132    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4133        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4134    }
4135
4136    void enforceNotIsolatedCaller(String caller) {
4137        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4138            throw new SecurityException("Isolated process not allowed to call " + caller);
4139        }
4140    }
4141
4142    void enforceShellRestriction(String restriction, int userHandle) {
4143        if (Binder.getCallingUid() == SHELL_UID) {
4144            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4145                throw new SecurityException("Shell does not have permission to access user "
4146                        + userHandle);
4147            }
4148        }
4149    }
4150
4151    @Override
4152    public int getFrontActivityScreenCompatMode() {
4153        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4154        synchronized (this) {
4155            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4156        }
4157    }
4158
4159    @Override
4160    public void setFrontActivityScreenCompatMode(int mode) {
4161        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4162                "setFrontActivityScreenCompatMode");
4163        synchronized (this) {
4164            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4165        }
4166    }
4167
4168    @Override
4169    public int getPackageScreenCompatMode(String packageName) {
4170        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4171        synchronized (this) {
4172            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4173        }
4174    }
4175
4176    @Override
4177    public void setPackageScreenCompatMode(String packageName, int mode) {
4178        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4179                "setPackageScreenCompatMode");
4180        synchronized (this) {
4181            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4182        }
4183    }
4184
4185    @Override
4186    public boolean getPackageAskScreenCompat(String packageName) {
4187        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4188        synchronized (this) {
4189            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4190        }
4191    }
4192
4193    @Override
4194    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4195        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4196                "setPackageAskScreenCompat");
4197        synchronized (this) {
4198            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4199        }
4200    }
4201
4202    private boolean hasUsageStatsPermission(String callingPackage) {
4203        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4204                Binder.getCallingUid(), callingPackage);
4205        if (mode == AppOpsManager.MODE_DEFAULT) {
4206            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4207                    == PackageManager.PERMISSION_GRANTED;
4208        }
4209        return mode == AppOpsManager.MODE_ALLOWED;
4210    }
4211
4212    @Override
4213    public int getPackageProcessState(String packageName, String callingPackage) {
4214        if (!hasUsageStatsPermission(callingPackage)) {
4215            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4216                    "getPackageProcessState");
4217        }
4218
4219        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4220        synchronized (this) {
4221            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4222                final ProcessRecord proc = mLruProcesses.get(i);
4223                if (procState > proc.setProcState) {
4224                    if (proc.pkgList.containsKey(packageName) ||
4225                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4226                        procState = proc.setProcState;
4227                    }
4228                }
4229            }
4230        }
4231        return procState;
4232    }
4233
4234    @Override
4235    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4236            throws RemoteException {
4237        synchronized (this) {
4238            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4239            if (app == null) {
4240                throw new IllegalArgumentException("Unknown process: " + process);
4241            }
4242            if (app.thread == null) {
4243                throw new IllegalArgumentException("Process has no app thread");
4244            }
4245            if (app.trimMemoryLevel >= level) {
4246                throw new IllegalArgumentException(
4247                        "Unable to set a higher trim level than current level");
4248            }
4249            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4250                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4251                throw new IllegalArgumentException("Unable to set a background trim level "
4252                    + "on a foreground process");
4253            }
4254            app.thread.scheduleTrimMemory(level);
4255            app.trimMemoryLevel = level;
4256            return true;
4257        }
4258    }
4259
4260    private void dispatchProcessesChanged() {
4261        int N;
4262        synchronized (this) {
4263            N = mPendingProcessChanges.size();
4264            if (mActiveProcessChanges.length < N) {
4265                mActiveProcessChanges = new ProcessChangeItem[N];
4266            }
4267            mPendingProcessChanges.toArray(mActiveProcessChanges);
4268            mPendingProcessChanges.clear();
4269            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4270                    "*** Delivering " + N + " process changes");
4271        }
4272
4273        int i = mProcessObservers.beginBroadcast();
4274        while (i > 0) {
4275            i--;
4276            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4277            if (observer != null) {
4278                try {
4279                    for (int j=0; j<N; j++) {
4280                        ProcessChangeItem item = mActiveProcessChanges[j];
4281                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4282                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4283                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4284                                    + item.uid + ": " + item.foregroundActivities);
4285                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4286                                    item.foregroundActivities);
4287                        }
4288                    }
4289                } catch (RemoteException e) {
4290                }
4291            }
4292        }
4293        mProcessObservers.finishBroadcast();
4294
4295        synchronized (this) {
4296            for (int j=0; j<N; j++) {
4297                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4298            }
4299        }
4300    }
4301
4302    private void dispatchProcessDied(int pid, int uid) {
4303        int i = mProcessObservers.beginBroadcast();
4304        while (i > 0) {
4305            i--;
4306            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4307            if (observer != null) {
4308                try {
4309                    observer.onProcessDied(pid, uid);
4310                } catch (RemoteException e) {
4311                }
4312            }
4313        }
4314        mProcessObservers.finishBroadcast();
4315    }
4316
4317    @VisibleForTesting
4318    void dispatchUidsChanged() {
4319        int N;
4320        synchronized (this) {
4321            N = mPendingUidChanges.size();
4322            if (mActiveUidChanges.length < N) {
4323                mActiveUidChanges = new UidRecord.ChangeItem[N];
4324            }
4325            for (int i=0; i<N; i++) {
4326                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4327                mActiveUidChanges[i] = change;
4328                if (change.uidRecord != null) {
4329                    change.uidRecord.pendingChange = null;
4330                    change.uidRecord = null;
4331                }
4332            }
4333            mPendingUidChanges.clear();
4334            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4335                    "*** Delivering " + N + " uid changes");
4336        }
4337
4338        int i = mUidObservers.beginBroadcast();
4339        while (i > 0) {
4340            i--;
4341            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4342                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4343        }
4344        mUidObservers.finishBroadcast();
4345
4346        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4347            for (int j = 0; j < N; ++j) {
4348                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4349                if (item.change == UidRecord.CHANGE_GONE
4350                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4351                    mValidateUids.remove(item.uid);
4352                } else {
4353                    UidRecord validateUid = mValidateUids.get(item.uid);
4354                    if (validateUid == null) {
4355                        validateUid = new UidRecord(item.uid);
4356                        mValidateUids.put(item.uid, validateUid);
4357                    }
4358                    if (item.change == UidRecord.CHANGE_IDLE) {
4359                        validateUid.idle = true;
4360                    } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4361                        validateUid.idle = false;
4362                    }
4363                    validateUid.curProcState = validateUid.setProcState = item.processState;
4364                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4365                }
4366            }
4367        }
4368
4369        synchronized (this) {
4370            for (int j = 0; j < N; j++) {
4371                mAvailUidChanges.add(mActiveUidChanges[j]);
4372            }
4373        }
4374    }
4375
4376    private void dispatchUidsChangedForObserver(IUidObserver observer,
4377            UidObserverRegistration reg, int changesSize) {
4378        if (observer == null) {
4379            return;
4380        }
4381        try {
4382            for (int j = 0; j < changesSize; j++) {
4383                UidRecord.ChangeItem item = mActiveUidChanges[j];
4384                final int change = item.change;
4385                if (change == UidRecord.CHANGE_IDLE
4386                        || change == UidRecord.CHANGE_GONE_IDLE) {
4387                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4388                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4389                                "UID idle uid=" + item.uid);
4390                        observer.onUidIdle(item.uid, item.ephemeral);
4391                    }
4392                } else if (change == UidRecord.CHANGE_ACTIVE) {
4393                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4394                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4395                                "UID active uid=" + item.uid);
4396                        observer.onUidActive(item.uid);
4397                    }
4398                }
4399                if (change == UidRecord.CHANGE_GONE
4400                        || change == UidRecord.CHANGE_GONE_IDLE) {
4401                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4402                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4403                                "UID gone uid=" + item.uid);
4404                        observer.onUidGone(item.uid, item.ephemeral);
4405                    }
4406                    if (reg.lastProcStates != null) {
4407                        reg.lastProcStates.delete(item.uid);
4408                    }
4409                } else {
4410                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4411                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4412                                "UID CHANGED uid=" + item.uid
4413                                        + ": " + item.processState);
4414                        boolean doReport = true;
4415                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4416                            final int lastState = reg.lastProcStates.get(item.uid,
4417                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4418                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4419                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4420                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4421                                doReport = lastAboveCut != newAboveCut;
4422                            } else {
4423                                doReport = item.processState
4424                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4425                            }
4426                        }
4427                        if (doReport) {
4428                            if (reg.lastProcStates != null) {
4429                                reg.lastProcStates.put(item.uid, item.processState);
4430                            }
4431                            observer.onUidStateChanged(item.uid, item.processState,
4432                                    item.procStateSeq);
4433                        }
4434                    }
4435                }
4436            }
4437        } catch (RemoteException e) {
4438        }
4439    }
4440
4441    @Override
4442    public final int startActivity(IApplicationThread caller, String callingPackage,
4443            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4444            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4445        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4446                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4447                UserHandle.getCallingUserId());
4448    }
4449
4450    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4451        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4452        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4453                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4454                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4455
4456        // TODO: Switch to user app stacks here.
4457        String mimeType = intent.getType();
4458        final Uri data = intent.getData();
4459        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4460            mimeType = getProviderMimeType(data, userId);
4461        }
4462        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4463
4464        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4465        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null,
4466                null, null, 0, 0, null, null, null, null, false, userId, container, null,
4467                "startActivity");
4468    }
4469
4470    @Override
4471    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4472            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4473            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4474        enforceNotIsolatedCaller("startActivity");
4475        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4476                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4477        // TODO: Switch to user app stacks here.
4478        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4479                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4480                profilerInfo, null, null, bOptions, false, userId, null, null,
4481                "startActivityAsUser");
4482    }
4483
4484    @Override
4485    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4486            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4487            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4488            int userId) {
4489
4490        // This is very dangerous -- it allows you to perform a start activity (including
4491        // permission grants) as any app that may launch one of your own activities.  So
4492        // we will only allow this to be done from activities that are part of the core framework,
4493        // and then only when they are running as the system.
4494        final ActivityRecord sourceRecord;
4495        final int targetUid;
4496        final String targetPackage;
4497        synchronized (this) {
4498            if (resultTo == null) {
4499                throw new SecurityException("Must be called from an activity");
4500            }
4501            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4502            if (sourceRecord == null) {
4503                throw new SecurityException("Called with bad activity token: " + resultTo);
4504            }
4505            if (!sourceRecord.info.packageName.equals("android")) {
4506                throw new SecurityException(
4507                        "Must be called from an activity that is declared in the android package");
4508            }
4509            if (sourceRecord.app == null) {
4510                throw new SecurityException("Called without a process attached to activity");
4511            }
4512            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4513                // This is still okay, as long as this activity is running under the
4514                // uid of the original calling activity.
4515                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4516                    throw new SecurityException(
4517                            "Calling activity in uid " + sourceRecord.app.uid
4518                                    + " must be system uid or original calling uid "
4519                                    + sourceRecord.launchedFromUid);
4520                }
4521            }
4522            if (ignoreTargetSecurity) {
4523                if (intent.getComponent() == null) {
4524                    throw new SecurityException(
4525                            "Component must be specified with ignoreTargetSecurity");
4526                }
4527                if (intent.getSelector() != null) {
4528                    throw new SecurityException(
4529                            "Selector not allowed with ignoreTargetSecurity");
4530                }
4531            }
4532            targetUid = sourceRecord.launchedFromUid;
4533            targetPackage = sourceRecord.launchedFromPackage;
4534        }
4535
4536        if (userId == UserHandle.USER_NULL) {
4537            userId = UserHandle.getUserId(sourceRecord.app.uid);
4538        }
4539
4540        // TODO: Switch to user app stacks here.
4541        try {
4542            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4543                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4544                    null, null, bOptions, ignoreTargetSecurity, userId, null, null,
4545                    "startActivityAsCaller");
4546            return ret;
4547        } catch (SecurityException e) {
4548            // XXX need to figure out how to propagate to original app.
4549            // A SecurityException here is generally actually a fault of the original
4550            // calling activity (such as a fairly granting permissions), so propagate it
4551            // back to them.
4552            /*
4553            StringBuilder msg = new StringBuilder();
4554            msg.append("While launching");
4555            msg.append(intent.toString());
4556            msg.append(": ");
4557            msg.append(e.getMessage());
4558            */
4559            throw e;
4560        }
4561    }
4562
4563    @Override
4564    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4565            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4566            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4567        enforceNotIsolatedCaller("startActivityAndWait");
4568        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4569                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4570        WaitResult res = new WaitResult();
4571        // TODO: Switch to user app stacks here.
4572        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4573                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4574                bOptions, false, userId, null, null, "startActivityAndWait");
4575        return res;
4576    }
4577
4578    @Override
4579    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4580            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4581            int startFlags, Configuration config, Bundle bOptions, int userId) {
4582        enforceNotIsolatedCaller("startActivityWithConfig");
4583        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4584                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4585        // TODO: Switch to user app stacks here.
4586        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4587                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4588                null, null, config, bOptions, false, userId, null, null, "startActivityWithConfig");
4589        return ret;
4590    }
4591
4592    @Override
4593    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4594            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4595            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4596            throws TransactionTooLargeException {
4597        enforceNotIsolatedCaller("startActivityIntentSender");
4598        // Refuse possible leaked file descriptors
4599        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4600            throw new IllegalArgumentException("File descriptors passed in Intent");
4601        }
4602
4603        if (!(target instanceof PendingIntentRecord)) {
4604            throw new IllegalArgumentException("Bad PendingIntent object");
4605        }
4606
4607        PendingIntentRecord pir = (PendingIntentRecord)target;
4608
4609        synchronized (this) {
4610            // If this is coming from the currently resumed activity, it is
4611            // effectively saying that app switches are allowed at this point.
4612            final ActivityStack stack = getFocusedStack();
4613            if (stack.mResumedActivity != null &&
4614                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4615                mAppSwitchesAllowedTime = 0;
4616            }
4617        }
4618        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4619                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4620        return ret;
4621    }
4622
4623    @Override
4624    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4625            Intent intent, String resolvedType, IVoiceInteractionSession session,
4626            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4627            Bundle bOptions, int userId) {
4628        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4629                != PackageManager.PERMISSION_GRANTED) {
4630            String msg = "Permission Denial: startVoiceActivity() from pid="
4631                    + Binder.getCallingPid()
4632                    + ", uid=" + Binder.getCallingUid()
4633                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4634            Slog.w(TAG, msg);
4635            throw new SecurityException(msg);
4636        }
4637        if (session == null || interactor == null) {
4638            throw new NullPointerException("null session or interactor");
4639        }
4640        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4641                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4642        // TODO: Switch to user app stacks here.
4643        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4644                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4645                null, bOptions, false, userId, null, null, "startVoiceActivity");
4646    }
4647
4648    @Override
4649    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4650            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4651        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4652                != PackageManager.PERMISSION_GRANTED) {
4653            final String msg = "Permission Denial: startAssistantActivity() from pid="
4654                    + Binder.getCallingPid()
4655                    + ", uid=" + Binder.getCallingUid()
4656                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4657            Slog.w(TAG, msg);
4658            throw new SecurityException(msg);
4659        }
4660        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4661                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4662        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4663                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4664                userId, null, null, "startAssistantActivity");
4665    }
4666
4667    @Override
4668    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4669            throws RemoteException {
4670        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4671        synchronized (this) {
4672            ActivityRecord activity = getFocusedStack().topActivity();
4673            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4674                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4675            }
4676            if (mRunningVoice != null || activity.getTask().voiceSession != null
4677                    || activity.voiceSession != null) {
4678                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4679                return;
4680            }
4681            if (activity.pendingVoiceInteractionStart) {
4682                Slog.w(TAG, "Pending start of voice interaction already.");
4683                return;
4684            }
4685            activity.pendingVoiceInteractionStart = true;
4686        }
4687        LocalServices.getService(VoiceInteractionManagerInternal.class)
4688                .startLocalVoiceInteraction(callingActivity, options);
4689    }
4690
4691    @Override
4692    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4693        LocalServices.getService(VoiceInteractionManagerInternal.class)
4694                .stopLocalVoiceInteraction(callingActivity);
4695    }
4696
4697    @Override
4698    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4699        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4700                .supportsLocalVoiceInteraction();
4701    }
4702
4703    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4704            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4705        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4706        if (activityToCallback == null) return;
4707        activityToCallback.setVoiceSessionLocked(voiceSession);
4708
4709        // Inform the activity
4710        try {
4711            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4712                    voiceInteractor);
4713            long token = Binder.clearCallingIdentity();
4714            try {
4715                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4716            } finally {
4717                Binder.restoreCallingIdentity(token);
4718            }
4719            // TODO: VI Should we cache the activity so that it's easier to find later
4720            // rather than scan through all the stacks and activities?
4721        } catch (RemoteException re) {
4722            activityToCallback.clearVoiceSessionLocked();
4723            // TODO: VI Should this terminate the voice session?
4724        }
4725    }
4726
4727    @Override
4728    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4729        synchronized (this) {
4730            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4731                if (keepAwake) {
4732                    mVoiceWakeLock.acquire();
4733                } else {
4734                    mVoiceWakeLock.release();
4735                }
4736            }
4737        }
4738    }
4739
4740    @Override
4741    public boolean startNextMatchingActivity(IBinder callingActivity,
4742            Intent intent, Bundle bOptions) {
4743        // Refuse possible leaked file descriptors
4744        if (intent != null && intent.hasFileDescriptors() == true) {
4745            throw new IllegalArgumentException("File descriptors passed in Intent");
4746        }
4747        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4748
4749        synchronized (this) {
4750            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4751            if (r == null) {
4752                ActivityOptions.abort(options);
4753                return false;
4754            }
4755            if (r.app == null || r.app.thread == null) {
4756                // The caller is not running...  d'oh!
4757                ActivityOptions.abort(options);
4758                return false;
4759            }
4760            intent = new Intent(intent);
4761            // The caller is not allowed to change the data.
4762            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4763            // And we are resetting to find the next component...
4764            intent.setComponent(null);
4765
4766            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4767
4768            ActivityInfo aInfo = null;
4769            try {
4770                List<ResolveInfo> resolves =
4771                    AppGlobals.getPackageManager().queryIntentActivities(
4772                            intent, r.resolvedType,
4773                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4774                            UserHandle.getCallingUserId()).getList();
4775
4776                // Look for the original activity in the list...
4777                final int N = resolves != null ? resolves.size() : 0;
4778                for (int i=0; i<N; i++) {
4779                    ResolveInfo rInfo = resolves.get(i);
4780                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4781                            && rInfo.activityInfo.name.equals(r.info.name)) {
4782                        // We found the current one...  the next matching is
4783                        // after it.
4784                        i++;
4785                        if (i<N) {
4786                            aInfo = resolves.get(i).activityInfo;
4787                        }
4788                        if (debug) {
4789                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4790                                    + "/" + r.info.name);
4791                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4792                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4793                        }
4794                        break;
4795                    }
4796                }
4797            } catch (RemoteException e) {
4798            }
4799
4800            if (aInfo == null) {
4801                // Nobody who is next!
4802                ActivityOptions.abort(options);
4803                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4804                return false;
4805            }
4806
4807            intent.setComponent(new ComponentName(
4808                    aInfo.applicationInfo.packageName, aInfo.name));
4809            intent.setFlags(intent.getFlags()&~(
4810                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4811                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4812                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4813                    Intent.FLAG_ACTIVITY_NEW_TASK));
4814
4815            // Okay now we need to start the new activity, replacing the
4816            // currently running activity.  This is a little tricky because
4817            // we want to start the new one as if the current one is finished,
4818            // but not finish the current one first so that there is no flicker.
4819            // And thus...
4820            final boolean wasFinishing = r.finishing;
4821            r.finishing = true;
4822
4823            // Propagate reply information over to the new activity.
4824            final ActivityRecord resultTo = r.resultTo;
4825            final String resultWho = r.resultWho;
4826            final int requestCode = r.requestCode;
4827            r.resultTo = null;
4828            if (resultTo != null) {
4829                resultTo.removeResultsLocked(r, resultWho, requestCode);
4830            }
4831
4832            final long origId = Binder.clearCallingIdentity();
4833            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4834                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4835                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4836                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4837                    false, false, null, null, null, "startNextMatchingActivity");
4838            Binder.restoreCallingIdentity(origId);
4839
4840            r.finishing = wasFinishing;
4841            if (res != ActivityManager.START_SUCCESS) {
4842                return false;
4843            }
4844            return true;
4845        }
4846    }
4847
4848    @Override
4849    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4850        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4851            String msg = "Permission Denial: startActivityFromRecents called without " +
4852                    START_TASKS_FROM_RECENTS;
4853            Slog.w(TAG, msg);
4854            throw new SecurityException(msg);
4855        }
4856        final long origId = Binder.clearCallingIdentity();
4857        try {
4858            synchronized (this) {
4859                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4860            }
4861        } finally {
4862            Binder.restoreCallingIdentity(origId);
4863        }
4864    }
4865
4866    final int startActivityInPackage(int uid, String callingPackage,
4867            Intent intent, String resolvedType, IBinder resultTo,
4868            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4869            IActivityContainer container, TaskRecord inTask, String reason) {
4870
4871        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4872                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4873
4874        // TODO: Switch to user app stacks here.
4875        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4876                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4877                null, null, null, bOptions, false, userId, container, inTask, reason);
4878        return ret;
4879    }
4880
4881    @Override
4882    public final int startActivities(IApplicationThread caller, String callingPackage,
4883            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4884            int userId) {
4885        final String reason = "startActivities";
4886        enforceNotIsolatedCaller(reason);
4887        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4888                userId, false, ALLOW_FULL_ONLY, reason, null);
4889        // TODO: Switch to user app stacks here.
4890        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4891                resolvedTypes, resultTo, bOptions, userId, reason);
4892        return ret;
4893    }
4894
4895    final int startActivitiesInPackage(int uid, String callingPackage,
4896            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4897            Bundle bOptions, int userId) {
4898
4899        final String reason = "startActivityInPackage";
4900        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4901                userId, false, ALLOW_FULL_ONLY, reason, null);
4902        // TODO: Switch to user app stacks here.
4903        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4904                resultTo, bOptions, userId, reason);
4905        return ret;
4906    }
4907
4908    @Override
4909    public void reportActivityFullyDrawn(IBinder token) {
4910        synchronized (this) {
4911            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4912            if (r == null) {
4913                return;
4914            }
4915            r.reportFullyDrawnLocked();
4916        }
4917    }
4918
4919    @Override
4920    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4921        synchronized (this) {
4922            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4923            if (r == null) {
4924                return;
4925            }
4926            final long origId = Binder.clearCallingIdentity();
4927            try {
4928                r.setRequestedOrientation(requestedOrientation);
4929            } finally {
4930                Binder.restoreCallingIdentity(origId);
4931            }
4932        }
4933    }
4934
4935    @Override
4936    public int getRequestedOrientation(IBinder token) {
4937        synchronized (this) {
4938            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4939            if (r == null) {
4940                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4941            }
4942            return r.getRequestedOrientation();
4943        }
4944    }
4945
4946    @Override
4947    public final void requestActivityRelaunch(IBinder token) {
4948        synchronized(this) {
4949            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4950            if (r == null) {
4951                return;
4952            }
4953            final long origId = Binder.clearCallingIdentity();
4954            try {
4955                r.forceNewConfig = true;
4956                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4957                        true /* preserveWindow */);
4958            } finally {
4959                Binder.restoreCallingIdentity(origId);
4960            }
4961        }
4962    }
4963
4964    /**
4965     * This is the internal entry point for handling Activity.finish().
4966     *
4967     * @param token The Binder token referencing the Activity we want to finish.
4968     * @param resultCode Result code, if any, from this Activity.
4969     * @param resultData Result data (Intent), if any, from this Activity.
4970     * @param finishTask Whether to finish the task associated with this Activity.
4971     *
4972     * @return Returns true if the activity successfully finished, or false if it is still running.
4973     */
4974    @Override
4975    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4976            int finishTask) {
4977        // Refuse possible leaked file descriptors
4978        if (resultData != null && resultData.hasFileDescriptors() == true) {
4979            throw new IllegalArgumentException("File descriptors passed in Intent");
4980        }
4981
4982        synchronized(this) {
4983            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4984            if (r == null) {
4985                return true;
4986            }
4987            // Keep track of the root activity of the task before we finish it
4988            TaskRecord tr = r.getTask();
4989            ActivityRecord rootR = tr.getRootActivity();
4990            if (rootR == null) {
4991                Slog.w(TAG, "Finishing task with all activities already finished");
4992            }
4993            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4994            // finish.
4995            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4996                    mStackSupervisor.isLastLockedTask(tr)) {
4997                Slog.i(TAG, "Not finishing task in lock task mode");
4998                mStackSupervisor.showLockTaskToast();
4999                return false;
5000            }
5001            if (mController != null) {
5002                // Find the first activity that is not finishing.
5003                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5004                if (next != null) {
5005                    // ask watcher if this is allowed
5006                    boolean resumeOK = true;
5007                    try {
5008                        resumeOK = mController.activityResuming(next.packageName);
5009                    } catch (RemoteException e) {
5010                        mController = null;
5011                        Watchdog.getInstance().setActivityController(null);
5012                    }
5013
5014                    if (!resumeOK) {
5015                        Slog.i(TAG, "Not finishing activity because controller resumed");
5016                        return false;
5017                    }
5018                }
5019            }
5020            final long origId = Binder.clearCallingIdentity();
5021            try {
5022                boolean res;
5023                final boolean finishWithRootActivity =
5024                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5025                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5026                        || (finishWithRootActivity && r == rootR)) {
5027                    // If requested, remove the task that is associated to this activity only if it
5028                    // was the root activity in the task. The result code and data is ignored
5029                    // because we don't support returning them across task boundaries. Also, to
5030                    // keep backwards compatibility we remove the task from recents when finishing
5031                    // task with root activity.
5032                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5033                    if (!res) {
5034                        Slog.i(TAG, "Removing task failed to finish activity");
5035                    }
5036                } else {
5037                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5038                            resultData, "app-request", true);
5039                    if (!res) {
5040                        Slog.i(TAG, "Failed to finish by app-request");
5041                    }
5042                }
5043                return res;
5044            } finally {
5045                Binder.restoreCallingIdentity(origId);
5046            }
5047        }
5048    }
5049
5050    @Override
5051    public final void finishHeavyWeightApp() {
5052        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5053                != PackageManager.PERMISSION_GRANTED) {
5054            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5055                    + Binder.getCallingPid()
5056                    + ", uid=" + Binder.getCallingUid()
5057                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5058            Slog.w(TAG, msg);
5059            throw new SecurityException(msg);
5060        }
5061
5062        synchronized(this) {
5063            if (mHeavyWeightProcess == null) {
5064                return;
5065            }
5066
5067            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5068            for (int i = 0; i < activities.size(); i++) {
5069                ActivityRecord r = activities.get(i);
5070                if (!r.finishing && r.isInStackLocked()) {
5071                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5072                            null, "finish-heavy", true);
5073                }
5074            }
5075
5076            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5077                    mHeavyWeightProcess.userId, 0));
5078            mHeavyWeightProcess = null;
5079        }
5080    }
5081
5082    @Override
5083    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5084            String message) {
5085        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5086                != PackageManager.PERMISSION_GRANTED) {
5087            String msg = "Permission Denial: crashApplication() from pid="
5088                    + Binder.getCallingPid()
5089                    + ", uid=" + Binder.getCallingUid()
5090                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5091            Slog.w(TAG, msg);
5092            throw new SecurityException(msg);
5093        }
5094
5095        synchronized(this) {
5096            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5097        }
5098    }
5099
5100    @Override
5101    public final void finishSubActivity(IBinder token, String resultWho,
5102            int requestCode) {
5103        synchronized(this) {
5104            final long origId = Binder.clearCallingIdentity();
5105            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5106            if (r != null) {
5107                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5108            }
5109            Binder.restoreCallingIdentity(origId);
5110        }
5111    }
5112
5113    @Override
5114    public boolean finishActivityAffinity(IBinder token) {
5115        synchronized(this) {
5116            final long origId = Binder.clearCallingIdentity();
5117            try {
5118                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5119                if (r == null) {
5120                    return false;
5121                }
5122
5123                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5124                // can finish.
5125                final TaskRecord task = r.getTask();
5126                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5127                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5128                    mStackSupervisor.showLockTaskToast();
5129                    return false;
5130                }
5131                return task.getStack().finishActivityAffinityLocked(r);
5132            } finally {
5133                Binder.restoreCallingIdentity(origId);
5134            }
5135        }
5136    }
5137
5138    @Override
5139    public void finishVoiceTask(IVoiceInteractionSession session) {
5140        synchronized (this) {
5141            final long origId = Binder.clearCallingIdentity();
5142            try {
5143                // TODO: VI Consider treating local voice interactions and voice tasks
5144                // differently here
5145                mStackSupervisor.finishVoiceTask(session);
5146            } finally {
5147                Binder.restoreCallingIdentity(origId);
5148            }
5149        }
5150
5151    }
5152
5153    @Override
5154    public boolean releaseActivityInstance(IBinder token) {
5155        synchronized(this) {
5156            final long origId = Binder.clearCallingIdentity();
5157            try {
5158                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5159                if (r == null) {
5160                    return false;
5161                }
5162                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5163            } finally {
5164                Binder.restoreCallingIdentity(origId);
5165            }
5166        }
5167    }
5168
5169    @Override
5170    public void releaseSomeActivities(IApplicationThread appInt) {
5171        synchronized(this) {
5172            final long origId = Binder.clearCallingIdentity();
5173            try {
5174                ProcessRecord app = getRecordForAppLocked(appInt);
5175                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5176            } finally {
5177                Binder.restoreCallingIdentity(origId);
5178            }
5179        }
5180    }
5181
5182    @Override
5183    public boolean willActivityBeVisible(IBinder token) {
5184        synchronized(this) {
5185            ActivityStack stack = ActivityRecord.getStackLocked(token);
5186            if (stack != null) {
5187                return stack.willActivityBeVisibleLocked(token);
5188            }
5189            return false;
5190        }
5191    }
5192
5193    @Override
5194    public void overridePendingTransition(IBinder token, String packageName,
5195            int enterAnim, int exitAnim) {
5196        synchronized(this) {
5197            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5198            if (self == null) {
5199                return;
5200            }
5201
5202            final long origId = Binder.clearCallingIdentity();
5203
5204            if (self.state == ActivityState.RESUMED
5205                    || self.state == ActivityState.PAUSING) {
5206                mWindowManager.overridePendingAppTransition(packageName,
5207                        enterAnim, exitAnim, null);
5208            }
5209
5210            Binder.restoreCallingIdentity(origId);
5211        }
5212    }
5213
5214    /**
5215     * Main function for removing an existing process from the activity manager
5216     * as a result of that process going away.  Clears out all connections
5217     * to the process.
5218     */
5219    private final void handleAppDiedLocked(ProcessRecord app,
5220            boolean restarting, boolean allowRestart) {
5221        int pid = app.pid;
5222        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5223                false /*replacingPid*/);
5224        if (!kept && !restarting) {
5225            removeLruProcessLocked(app);
5226            if (pid > 0) {
5227                ProcessList.remove(pid);
5228            }
5229        }
5230
5231        if (mProfileProc == app) {
5232            clearProfilerLocked();
5233        }
5234
5235        // Remove this application's activities from active lists.
5236        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5237
5238        app.activities.clear();
5239
5240        if (app.instr != null) {
5241            Slog.w(TAG, "Crash of app " + app.processName
5242                  + " running instrumentation " + app.instr.mClass);
5243            Bundle info = new Bundle();
5244            info.putString("shortMsg", "Process crashed.");
5245            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5246        }
5247
5248        mWindowManager.deferSurfaceLayout();
5249        try {
5250            if (!restarting && hasVisibleActivities
5251                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5252                // If there was nothing to resume, and we are not already restarting this process, but
5253                // there is a visible activity that is hosted by the process...  then make sure all
5254                // visible activities are running, taking care of restarting this process.
5255                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5256            }
5257        } finally {
5258            mWindowManager.continueSurfaceLayout();
5259        }
5260    }
5261
5262    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5263        final IBinder threadBinder = thread.asBinder();
5264        // Find the application record.
5265        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5266            final ProcessRecord rec = mLruProcesses.get(i);
5267            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5268                return i;
5269            }
5270        }
5271        return -1;
5272    }
5273
5274    final ProcessRecord getRecordForAppLocked(
5275            IApplicationThread thread) {
5276        if (thread == null) {
5277            return null;
5278        }
5279
5280        int appIndex = getLRURecordIndexForAppLocked(thread);
5281        if (appIndex >= 0) {
5282            return mLruProcesses.get(appIndex);
5283        }
5284
5285        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5286        // double-check that.
5287        final IBinder threadBinder = thread.asBinder();
5288        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5289        for (int i = pmap.size()-1; i >= 0; i--) {
5290            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5291            for (int j = procs.size()-1; j >= 0; j--) {
5292                final ProcessRecord proc = procs.valueAt(j);
5293                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5294                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5295                            + proc);
5296                    return proc;
5297                }
5298            }
5299        }
5300
5301        return null;
5302    }
5303
5304    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5305        // If there are no longer any background processes running,
5306        // and the app that died was not running instrumentation,
5307        // then tell everyone we are now low on memory.
5308        boolean haveBg = false;
5309        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5310            ProcessRecord rec = mLruProcesses.get(i);
5311            if (rec.thread != null
5312                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5313                haveBg = true;
5314                break;
5315            }
5316        }
5317
5318        if (!haveBg) {
5319            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5320            if (doReport) {
5321                long now = SystemClock.uptimeMillis();
5322                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5323                    doReport = false;
5324                } else {
5325                    mLastMemUsageReportTime = now;
5326                }
5327            }
5328            final ArrayList<ProcessMemInfo> memInfos
5329                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5330            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5331            long now = SystemClock.uptimeMillis();
5332            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5333                ProcessRecord rec = mLruProcesses.get(i);
5334                if (rec == dyingProc || rec.thread == null) {
5335                    continue;
5336                }
5337                if (doReport) {
5338                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5339                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5340                }
5341                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5342                    // The low memory report is overriding any current
5343                    // state for a GC request.  Make sure to do
5344                    // heavy/important/visible/foreground processes first.
5345                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5346                        rec.lastRequestedGc = 0;
5347                    } else {
5348                        rec.lastRequestedGc = rec.lastLowMemory;
5349                    }
5350                    rec.reportLowMemory = true;
5351                    rec.lastLowMemory = now;
5352                    mProcessesToGc.remove(rec);
5353                    addProcessToGcListLocked(rec);
5354                }
5355            }
5356            if (doReport) {
5357                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5358                mHandler.sendMessage(msg);
5359            }
5360            scheduleAppGcsLocked();
5361        }
5362    }
5363
5364    final void appDiedLocked(ProcessRecord app) {
5365       appDiedLocked(app, app.pid, app.thread, false);
5366    }
5367
5368    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5369            boolean fromBinderDied) {
5370        // First check if this ProcessRecord is actually active for the pid.
5371        synchronized (mPidsSelfLocked) {
5372            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5373            if (curProc != app) {
5374                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5375                return;
5376            }
5377        }
5378
5379        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5380        synchronized (stats) {
5381            stats.noteProcessDiedLocked(app.info.uid, pid);
5382        }
5383
5384        if (!app.killed) {
5385            if (!fromBinderDied) {
5386                killProcessQuiet(pid);
5387            }
5388            killProcessGroup(app.uid, pid);
5389            app.killed = true;
5390        }
5391
5392        // Clean up already done if the process has been re-started.
5393        if (app.pid == pid && app.thread != null &&
5394                app.thread.asBinder() == thread.asBinder()) {
5395            boolean doLowMem = app.instr == null;
5396            boolean doOomAdj = doLowMem;
5397            if (!app.killedByAm) {
5398                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5399                        + ProcessList.makeOomAdjString(app.setAdj)
5400                        + ProcessList.makeProcStateString(app.setProcState));
5401                mAllowLowerMemLevel = true;
5402            } else {
5403                // Note that we always want to do oom adj to update our state with the
5404                // new number of procs.
5405                mAllowLowerMemLevel = false;
5406                doLowMem = false;
5407            }
5408            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5409                    app.setAdj, app.setProcState);
5410            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5411                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5412            handleAppDiedLocked(app, false, true);
5413
5414            if (doOomAdj) {
5415                updateOomAdjLocked();
5416            }
5417            if (doLowMem) {
5418                doLowMemReportIfNeededLocked(app);
5419            }
5420        } else if (app.pid != pid) {
5421            // A new process has already been started.
5422            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5423                    + ") has died and restarted (pid " + app.pid + ").");
5424            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5425        } else if (DEBUG_PROCESSES) {
5426            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5427                    + thread.asBinder());
5428        }
5429    }
5430
5431    /**
5432     * If a stack trace dump file is configured, dump process stack traces.
5433     * @param clearTraces causes the dump file to be erased prior to the new
5434     *    traces being written, if true; when false, the new traces will be
5435     *    appended to any existing file content.
5436     * @param firstPids of dalvik VM processes to dump stack traces for first
5437     * @param lastPids of dalvik VM processes to dump stack traces for last
5438     * @param nativePids optional list of native pids to dump stack crawls
5439     */
5440    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5441            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5442            ArrayList<Integer> nativePids) {
5443        ArrayList<Integer> extraPids = null;
5444
5445        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5446        // of the top users at the time of the request.
5447        if (processCpuTracker != null) {
5448            processCpuTracker.init();
5449            try {
5450                Thread.sleep(200);
5451            } catch (InterruptedException ignored) {
5452            }
5453
5454            processCpuTracker.update();
5455
5456            // We'll take the stack crawls of just the top apps using CPU.
5457            final int N = processCpuTracker.countWorkingStats();
5458            extraPids = new ArrayList<>();
5459            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5460                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5461                if (lastPids.indexOfKey(stats.pid) >= 0) {
5462                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5463
5464                    extraPids.add(stats.pid);
5465                } else if (DEBUG_ANR) {
5466                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5467                            + stats.pid);
5468                }
5469            }
5470        }
5471
5472        boolean useTombstonedForJavaTraces = false;
5473        File tracesFile;
5474
5475        final String tracesDir = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5476        if (tracesDir.isEmpty()) {
5477            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5478            // dumping scheme. All traces are written to a global trace file (usually
5479            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5480            // the file if requested.
5481            //
5482            // This mode of operation will be removed in the near future.
5483
5484
5485            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5486            if (globalTracesPath.isEmpty()) {
5487                Slog.w(TAG, "dumpStackTraces: no trace path configured");
5488                return null;
5489            }
5490
5491            tracesFile = new File(globalTracesPath);
5492            try {
5493                if (clearTraces && tracesFile.exists()) {
5494                    tracesFile.delete();
5495                }
5496
5497                tracesFile.createNewFile();
5498                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5499            } catch (IOException e) {
5500                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5501                return null;
5502            }
5503        } else {
5504            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5505            // Each set of ANR traces is written to a separate file and dumpstate will process
5506            // all such files and add them to a captured bug report if they're recent enough.
5507            //
5508            // NOTE: We should consider creating the file in native code atomically once we've
5509            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5510            // can be removed.
5511            try {
5512                tracesFile = File.createTempFile("anr_", "", new File(tracesDir));
5513                FileUtils.setPermissions(tracesFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5514            } catch (IOException ioe) {
5515                Slog.w(TAG, "Unable to create ANR traces file: ", ioe);
5516                return null;
5517            }
5518
5519            useTombstonedForJavaTraces = true;
5520        }
5521
5522        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5523                useTombstonedForJavaTraces);
5524        return tracesFile;
5525    }
5526
5527    /**
5528     * Legacy code, do not use. Existing users will be deleted.
5529     *
5530     * @deprecated
5531     */
5532    @Deprecated
5533    public static class DumpStackFileObserver extends FileObserver {
5534        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5535        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5536
5537        private final String mTracesPath;
5538        private boolean mClosed;
5539
5540        public DumpStackFileObserver(String tracesPath) {
5541            super(tracesPath, FileObserver.CLOSE_WRITE);
5542            mTracesPath = tracesPath;
5543        }
5544
5545        @Override
5546        public synchronized void onEvent(int event, String path) {
5547            mClosed = true;
5548            notify();
5549        }
5550
5551        public long dumpWithTimeout(int pid, long timeout) {
5552            sendSignal(pid, SIGNAL_QUIT);
5553            final long start = SystemClock.elapsedRealtime();
5554
5555            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5556            synchronized (this) {
5557                try {
5558                    wait(waitTime); // Wait for traces file to be closed.
5559                } catch (InterruptedException e) {
5560                    Slog.wtf(TAG, e);
5561                }
5562            }
5563
5564            // This avoids a corner case of passing a negative time to the native
5565            // trace in case we've already hit the overall timeout.
5566            final long timeWaited = SystemClock.elapsedRealtime() - start;
5567            if (timeWaited >= timeout) {
5568                return timeWaited;
5569            }
5570
5571            if (!mClosed) {
5572                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5573                       ". Attempting native stack collection.");
5574
5575                final long nativeDumpTimeoutMs = Math.min(
5576                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5577
5578                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5579                        (int) (nativeDumpTimeoutMs / 1000));
5580            }
5581
5582            final long end = SystemClock.elapsedRealtime();
5583            mClosed = false;
5584
5585            return (end - start);
5586        }
5587    }
5588
5589    /**
5590     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5591     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5592     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5593     * attempting to obtain native traces in the case of a failure. Returns the total time spent
5594     * capturing traces.
5595     */
5596    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5597        final long timeStart = SystemClock.elapsedRealtime();
5598        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5599            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5600                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
5601        }
5602
5603        return SystemClock.elapsedRealtime() - timeStart;
5604    }
5605
5606    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5607            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5608            boolean useTombstonedForJavaTraces) {
5609
5610        // We don't need any sort of inotify based monitoring when we're dumping traces via
5611        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5612        // control of all writes to the file in question.
5613        final DumpStackFileObserver observer;
5614        if (useTombstonedForJavaTraces) {
5615            observer = null;
5616        } else {
5617            // Use a FileObserver to detect when traces finish writing.
5618            // The order of traces is considered important to maintain for legibility.
5619            observer = new DumpStackFileObserver(tracesFile);
5620        }
5621
5622        // We must complete all stack dumps within 20 seconds.
5623        long remainingTime = 20 * 1000;
5624        try {
5625            if (observer != null) {
5626                observer.startWatching();
5627            }
5628
5629            // First collect all of the stacks of the most important pids.
5630            if (firstPids != null) {
5631                int num = firstPids.size();
5632                for (int i = 0; i < num; i++) {
5633                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5634                            + firstPids.get(i));
5635                    final long timeTaken;
5636                    if (useTombstonedForJavaTraces) {
5637                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5638                    } else {
5639                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5640                    }
5641
5642                    remainingTime -= timeTaken;
5643                    if (remainingTime <= 0) {
5644                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5645                            "); deadline exceeded.");
5646                        return;
5647                    }
5648
5649                    if (DEBUG_ANR) {
5650                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5651                    }
5652                }
5653            }
5654
5655            // Next collect the stacks of the native pids
5656            if (nativePids != null) {
5657                for (int pid : nativePids) {
5658                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5659                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5660
5661                    final long start = SystemClock.elapsedRealtime();
5662                    Debug.dumpNativeBacktraceToFileTimeout(
5663                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5664                    final long timeTaken = SystemClock.elapsedRealtime() - start;
5665
5666                    remainingTime -= timeTaken;
5667                    if (remainingTime <= 0) {
5668                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5669                            "); deadline exceeded.");
5670                        return;
5671                    }
5672
5673                    if (DEBUG_ANR) {
5674                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5675                    }
5676                }
5677            }
5678
5679            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5680            if (extraPids != null) {
5681                for (int pid : extraPids) {
5682                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5683
5684                    final long timeTaken;
5685                    if (useTombstonedForJavaTraces) {
5686                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5687                    } else {
5688                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5689                    }
5690
5691                    remainingTime -= timeTaken;
5692                    if (remainingTime <= 0) {
5693                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5694                                "); deadline exceeded.");
5695                        return;
5696                    }
5697
5698                    if (DEBUG_ANR) {
5699                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5700                    }
5701                }
5702            }
5703        } finally {
5704            if (observer != null) {
5705                observer.stopWatching();
5706            }
5707        }
5708    }
5709
5710    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5711        if (true || IS_USER_BUILD) {
5712            return;
5713        }
5714        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5715        if (tracesPath == null || tracesPath.length() == 0) {
5716            return;
5717        }
5718
5719        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5720        StrictMode.allowThreadDiskWrites();
5721        try {
5722            final File tracesFile = new File(tracesPath);
5723            final File tracesDir = tracesFile.getParentFile();
5724            final File tracesTmp = new File(tracesDir, "__tmp__");
5725            try {
5726                if (tracesFile.exists()) {
5727                    tracesTmp.delete();
5728                    tracesFile.renameTo(tracesTmp);
5729                }
5730                StringBuilder sb = new StringBuilder();
5731                Time tobj = new Time();
5732                tobj.set(System.currentTimeMillis());
5733                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5734                sb.append(": ");
5735                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5736                sb.append(" since ");
5737                sb.append(msg);
5738                FileOutputStream fos = new FileOutputStream(tracesFile);
5739                fos.write(sb.toString().getBytes());
5740                if (app == null) {
5741                    fos.write("\n*** No application process!".getBytes());
5742                }
5743                fos.close();
5744                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5745            } catch (IOException e) {
5746                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5747                return;
5748            }
5749
5750            if (app != null) {
5751                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5752                firstPids.add(app.pid);
5753                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5754            }
5755
5756            File lastTracesFile = null;
5757            File curTracesFile = null;
5758            for (int i=9; i>=0; i--) {
5759                String name = String.format(Locale.US, "slow%02d.txt", i);
5760                curTracesFile = new File(tracesDir, name);
5761                if (curTracesFile.exists()) {
5762                    if (lastTracesFile != null) {
5763                        curTracesFile.renameTo(lastTracesFile);
5764                    } else {
5765                        curTracesFile.delete();
5766                    }
5767                }
5768                lastTracesFile = curTracesFile;
5769            }
5770            tracesFile.renameTo(curTracesFile);
5771            if (tracesTmp.exists()) {
5772                tracesTmp.renameTo(tracesFile);
5773            }
5774        } finally {
5775            StrictMode.setThreadPolicy(oldPolicy);
5776        }
5777    }
5778
5779    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5780        if (!mLaunchWarningShown) {
5781            mLaunchWarningShown = true;
5782            mUiHandler.post(new Runnable() {
5783                @Override
5784                public void run() {
5785                    synchronized (ActivityManagerService.this) {
5786                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5787                        d.show();
5788                        mUiHandler.postDelayed(new Runnable() {
5789                            @Override
5790                            public void run() {
5791                                synchronized (ActivityManagerService.this) {
5792                                    d.dismiss();
5793                                    mLaunchWarningShown = false;
5794                                }
5795                            }
5796                        }, 4000);
5797                    }
5798                }
5799            });
5800        }
5801    }
5802
5803    @Override
5804    public boolean clearApplicationUserData(final String packageName,
5805            final IPackageDataObserver observer, int userId) {
5806        enforceNotIsolatedCaller("clearApplicationUserData");
5807        int uid = Binder.getCallingUid();
5808        int pid = Binder.getCallingPid();
5809        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5810                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5811
5812
5813        long callingId = Binder.clearCallingIdentity();
5814        try {
5815            IPackageManager pm = AppGlobals.getPackageManager();
5816            int pkgUid = -1;
5817            synchronized(this) {
5818                if (getPackageManagerInternalLocked().isPackageDataProtected(
5819                        userId, packageName)) {
5820                    throw new SecurityException(
5821                            "Cannot clear data for a protected package: " + packageName);
5822                }
5823
5824                try {
5825                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5826                } catch (RemoteException e) {
5827                }
5828                if (pkgUid == -1) {
5829                    Slog.w(TAG, "Invalid packageName: " + packageName);
5830                    if (observer != null) {
5831                        try {
5832                            observer.onRemoveCompleted(packageName, false);
5833                        } catch (RemoteException e) {
5834                            Slog.i(TAG, "Observer no longer exists.");
5835                        }
5836                    }
5837                    return false;
5838                }
5839                if (uid == pkgUid || checkComponentPermission(
5840                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5841                        pid, uid, -1, true)
5842                        == PackageManager.PERMISSION_GRANTED) {
5843                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5844                } else {
5845                    throw new SecurityException("PID " + pid + " does not have permission "
5846                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5847                                    + " of package " + packageName);
5848                }
5849
5850                // Remove all tasks match the cleared application package and user
5851                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5852                    final TaskRecord tr = mRecentTasks.get(i);
5853                    final String taskPackageName =
5854                            tr.getBaseIntent().getComponent().getPackageName();
5855                    if (tr.userId != userId) continue;
5856                    if (!taskPackageName.equals(packageName)) continue;
5857                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5858                }
5859            }
5860
5861            final int pkgUidF = pkgUid;
5862            final int userIdF = userId;
5863            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5864                @Override
5865                public void onRemoveCompleted(String packageName, boolean succeeded)
5866                        throws RemoteException {
5867                    synchronized (ActivityManagerService.this) {
5868                        finishForceStopPackageLocked(packageName, pkgUidF);
5869                    }
5870
5871                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5872                            Uri.fromParts("package", packageName, null));
5873                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5874                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5875                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5876                    broadcastIntentInPackage("android", SYSTEM_UID, intent,
5877                            null, null, 0, null, null, null, null, false, false, userIdF);
5878
5879                    if (observer != null) {
5880                        observer.onRemoveCompleted(packageName, succeeded);
5881                    }
5882                }
5883            };
5884
5885            try {
5886                // Clear application user data
5887                pm.clearApplicationUserData(packageName, localObserver, userId);
5888
5889                synchronized(this) {
5890                    // Remove all permissions granted from/to this package
5891                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5892                }
5893
5894                // Reset notification settings.
5895                INotificationManager inm = NotificationManager.getService();
5896                inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5897            } catch (RemoteException e) {
5898            }
5899        } finally {
5900            Binder.restoreCallingIdentity(callingId);
5901        }
5902        return true;
5903    }
5904
5905    @Override
5906    public void killBackgroundProcesses(final String packageName, int userId) {
5907        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5908                != PackageManager.PERMISSION_GRANTED &&
5909                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5910                        != PackageManager.PERMISSION_GRANTED) {
5911            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5912                    + Binder.getCallingPid()
5913                    + ", uid=" + Binder.getCallingUid()
5914                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5915            Slog.w(TAG, msg);
5916            throw new SecurityException(msg);
5917        }
5918
5919        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5920                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5921        long callingId = Binder.clearCallingIdentity();
5922        try {
5923            IPackageManager pm = AppGlobals.getPackageManager();
5924            synchronized(this) {
5925                int appId = -1;
5926                try {
5927                    appId = UserHandle.getAppId(
5928                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5929                } catch (RemoteException e) {
5930                }
5931                if (appId == -1) {
5932                    Slog.w(TAG, "Invalid packageName: " + packageName);
5933                    return;
5934                }
5935                killPackageProcessesLocked(packageName, appId, userId,
5936                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5937            }
5938        } finally {
5939            Binder.restoreCallingIdentity(callingId);
5940        }
5941    }
5942
5943    @Override
5944    public void killAllBackgroundProcesses() {
5945        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5946                != PackageManager.PERMISSION_GRANTED) {
5947            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5948                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5949                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5950            Slog.w(TAG, msg);
5951            throw new SecurityException(msg);
5952        }
5953
5954        final long callingId = Binder.clearCallingIdentity();
5955        try {
5956            synchronized (this) {
5957                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5958                final int NP = mProcessNames.getMap().size();
5959                for (int ip = 0; ip < NP; ip++) {
5960                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5961                    final int NA = apps.size();
5962                    for (int ia = 0; ia < NA; ia++) {
5963                        final ProcessRecord app = apps.valueAt(ia);
5964                        if (app.persistent) {
5965                            // We don't kill persistent processes.
5966                            continue;
5967                        }
5968                        if (app.removed) {
5969                            procs.add(app);
5970                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5971                            app.removed = true;
5972                            procs.add(app);
5973                        }
5974                    }
5975                }
5976
5977                final int N = procs.size();
5978                for (int i = 0; i < N; i++) {
5979                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5980                }
5981
5982                mAllowLowerMemLevel = true;
5983
5984                updateOomAdjLocked();
5985                doLowMemReportIfNeededLocked(null);
5986            }
5987        } finally {
5988            Binder.restoreCallingIdentity(callingId);
5989        }
5990    }
5991
5992    /**
5993     * Kills all background processes, except those matching any of the
5994     * specified properties.
5995     *
5996     * @param minTargetSdk the target SDK version at or above which to preserve
5997     *                     processes, or {@code -1} to ignore the target SDK
5998     * @param maxProcState the process state at or below which to preserve
5999     *                     processes, or {@code -1} to ignore the process state
6000     */
6001    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6002        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6003                != PackageManager.PERMISSION_GRANTED) {
6004            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6005                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6006                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6007            Slog.w(TAG, msg);
6008            throw new SecurityException(msg);
6009        }
6010
6011        final long callingId = Binder.clearCallingIdentity();
6012        try {
6013            synchronized (this) {
6014                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6015                final int NP = mProcessNames.getMap().size();
6016                for (int ip = 0; ip < NP; ip++) {
6017                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6018                    final int NA = apps.size();
6019                    for (int ia = 0; ia < NA; ia++) {
6020                        final ProcessRecord app = apps.valueAt(ia);
6021                        if (app.removed) {
6022                            procs.add(app);
6023                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6024                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6025                            app.removed = true;
6026                            procs.add(app);
6027                        }
6028                    }
6029                }
6030
6031                final int N = procs.size();
6032                for (int i = 0; i < N; i++) {
6033                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6034                }
6035            }
6036        } finally {
6037            Binder.restoreCallingIdentity(callingId);
6038        }
6039    }
6040
6041    @Override
6042    public void forceStopPackage(final String packageName, int userId) {
6043        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6044                != PackageManager.PERMISSION_GRANTED) {
6045            String msg = "Permission Denial: forceStopPackage() from pid="
6046                    + Binder.getCallingPid()
6047                    + ", uid=" + Binder.getCallingUid()
6048                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6049            Slog.w(TAG, msg);
6050            throw new SecurityException(msg);
6051        }
6052        final int callingPid = Binder.getCallingPid();
6053        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6054                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6055        long callingId = Binder.clearCallingIdentity();
6056        try {
6057            IPackageManager pm = AppGlobals.getPackageManager();
6058            synchronized(this) {
6059                int[] users = userId == UserHandle.USER_ALL
6060                        ? mUserController.getUsers() : new int[] { userId };
6061                for (int user : users) {
6062                    int pkgUid = -1;
6063                    try {
6064                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6065                                user);
6066                    } catch (RemoteException e) {
6067                    }
6068                    if (pkgUid == -1) {
6069                        Slog.w(TAG, "Invalid packageName: " + packageName);
6070                        continue;
6071                    }
6072                    try {
6073                        pm.setPackageStoppedState(packageName, true, user);
6074                    } catch (RemoteException e) {
6075                    } catch (IllegalArgumentException e) {
6076                        Slog.w(TAG, "Failed trying to unstop package "
6077                                + packageName + ": " + e);
6078                    }
6079                    if (mUserController.isUserRunningLocked(user, 0)) {
6080                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6081                        finishForceStopPackageLocked(packageName, pkgUid);
6082                    }
6083                }
6084            }
6085        } finally {
6086            Binder.restoreCallingIdentity(callingId);
6087        }
6088    }
6089
6090    @Override
6091    public void addPackageDependency(String packageName) {
6092        synchronized (this) {
6093            int callingPid = Binder.getCallingPid();
6094            if (callingPid == myPid()) {
6095                //  Yeah, um, no.
6096                return;
6097            }
6098            ProcessRecord proc;
6099            synchronized (mPidsSelfLocked) {
6100                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6101            }
6102            if (proc != null) {
6103                if (proc.pkgDeps == null) {
6104                    proc.pkgDeps = new ArraySet<String>(1);
6105                }
6106                proc.pkgDeps.add(packageName);
6107            }
6108        }
6109    }
6110
6111    /*
6112     * The pkg name and app id have to be specified.
6113     */
6114    @Override
6115    public void killApplication(String pkg, int appId, int userId, String reason) {
6116        if (pkg == null) {
6117            return;
6118        }
6119        // Make sure the uid is valid.
6120        if (appId < 0) {
6121            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6122            return;
6123        }
6124        int callerUid = Binder.getCallingUid();
6125        // Only the system server can kill an application
6126        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6127            // Post an aysnc message to kill the application
6128            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6129            msg.arg1 = appId;
6130            msg.arg2 = userId;
6131            Bundle bundle = new Bundle();
6132            bundle.putString("pkg", pkg);
6133            bundle.putString("reason", reason);
6134            msg.obj = bundle;
6135            mHandler.sendMessage(msg);
6136        } else {
6137            throw new SecurityException(callerUid + " cannot kill pkg: " +
6138                    pkg);
6139        }
6140    }
6141
6142    @Override
6143    public void closeSystemDialogs(String reason) {
6144        enforceNotIsolatedCaller("closeSystemDialogs");
6145
6146        final int pid = Binder.getCallingPid();
6147        final int uid = Binder.getCallingUid();
6148        final long origId = Binder.clearCallingIdentity();
6149        try {
6150            synchronized (this) {
6151                // Only allow this from foreground processes, so that background
6152                // applications can't abuse it to prevent system UI from being shown.
6153                if (uid >= FIRST_APPLICATION_UID) {
6154                    ProcessRecord proc;
6155                    synchronized (mPidsSelfLocked) {
6156                        proc = mPidsSelfLocked.get(pid);
6157                    }
6158                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6159                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6160                                + " from background process " + proc);
6161                        return;
6162                    }
6163                }
6164                closeSystemDialogsLocked(reason);
6165            }
6166        } finally {
6167            Binder.restoreCallingIdentity(origId);
6168        }
6169    }
6170
6171    void closeSystemDialogsLocked(String reason) {
6172        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6173        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6174                | Intent.FLAG_RECEIVER_FOREGROUND);
6175        if (reason != null) {
6176            intent.putExtra("reason", reason);
6177        }
6178        mWindowManager.closeSystemDialogs(reason);
6179
6180        mStackSupervisor.closeSystemDialogsLocked();
6181
6182        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6183                AppOpsManager.OP_NONE, null, false, false,
6184                -1, SYSTEM_UID, UserHandle.USER_ALL);
6185    }
6186
6187    @Override
6188    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6189        enforceNotIsolatedCaller("getProcessMemoryInfo");
6190        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6191        for (int i=pids.length-1; i>=0; i--) {
6192            ProcessRecord proc;
6193            int oomAdj;
6194            synchronized (this) {
6195                synchronized (mPidsSelfLocked) {
6196                    proc = mPidsSelfLocked.get(pids[i]);
6197                    oomAdj = proc != null ? proc.setAdj : 0;
6198                }
6199            }
6200            infos[i] = new Debug.MemoryInfo();
6201            Debug.getMemoryInfo(pids[i], infos[i]);
6202            if (proc != null) {
6203                synchronized (this) {
6204                    if (proc.thread != null && proc.setAdj == oomAdj) {
6205                        // Record this for posterity if the process has been stable.
6206                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6207                                infos[i].getTotalUss(), false, proc.pkgList);
6208                    }
6209                }
6210            }
6211        }
6212        return infos;
6213    }
6214
6215    @Override
6216    public long[] getProcessPss(int[] pids) {
6217        enforceNotIsolatedCaller("getProcessPss");
6218        long[] pss = new long[pids.length];
6219        for (int i=pids.length-1; i>=0; i--) {
6220            ProcessRecord proc;
6221            int oomAdj;
6222            synchronized (this) {
6223                synchronized (mPidsSelfLocked) {
6224                    proc = mPidsSelfLocked.get(pids[i]);
6225                    oomAdj = proc != null ? proc.setAdj : 0;
6226                }
6227            }
6228            long[] tmpUss = new long[1];
6229            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6230            if (proc != null) {
6231                synchronized (this) {
6232                    if (proc.thread != null && proc.setAdj == oomAdj) {
6233                        // Record this for posterity if the process has been stable.
6234                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6235                    }
6236                }
6237            }
6238        }
6239        return pss;
6240    }
6241
6242    @Override
6243    public void killApplicationProcess(String processName, int uid) {
6244        if (processName == null) {
6245            return;
6246        }
6247
6248        int callerUid = Binder.getCallingUid();
6249        // Only the system server can kill an application
6250        if (callerUid == SYSTEM_UID) {
6251            synchronized (this) {
6252                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6253                if (app != null && app.thread != null) {
6254                    try {
6255                        app.thread.scheduleSuicide();
6256                    } catch (RemoteException e) {
6257                        // If the other end already died, then our work here is done.
6258                    }
6259                } else {
6260                    Slog.w(TAG, "Process/uid not found attempting kill of "
6261                            + processName + " / " + uid);
6262                }
6263            }
6264        } else {
6265            throw new SecurityException(callerUid + " cannot kill app process: " +
6266                    processName);
6267        }
6268    }
6269
6270    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6271        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6272                false, true, false, false, UserHandle.getUserId(uid), reason);
6273    }
6274
6275    private void finishForceStopPackageLocked(final String packageName, int uid) {
6276        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6277                Uri.fromParts("package", packageName, null));
6278        if (!mProcessesReady) {
6279            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6280                    | Intent.FLAG_RECEIVER_FOREGROUND);
6281        }
6282        intent.putExtra(Intent.EXTRA_UID, uid);
6283        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6284        broadcastIntentLocked(null, null, intent,
6285                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6286                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6287    }
6288
6289
6290    private final boolean killPackageProcessesLocked(String packageName, int appId,
6291            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6292            boolean doit, boolean evenPersistent, String reason) {
6293        ArrayList<ProcessRecord> procs = new ArrayList<>();
6294
6295        // Remove all processes this package may have touched: all with the
6296        // same UID (except for the system or root user), and all whose name
6297        // matches the package name.
6298        final int NP = mProcessNames.getMap().size();
6299        for (int ip=0; ip<NP; ip++) {
6300            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6301            final int NA = apps.size();
6302            for (int ia=0; ia<NA; ia++) {
6303                ProcessRecord app = apps.valueAt(ia);
6304                if (app.persistent && !evenPersistent) {
6305                    // we don't kill persistent processes
6306                    continue;
6307                }
6308                if (app.removed) {
6309                    if (doit) {
6310                        procs.add(app);
6311                    }
6312                    continue;
6313                }
6314
6315                // Skip process if it doesn't meet our oom adj requirement.
6316                if (app.setAdj < minOomAdj) {
6317                    continue;
6318                }
6319
6320                // If no package is specified, we call all processes under the
6321                // give user id.
6322                if (packageName == null) {
6323                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6324                        continue;
6325                    }
6326                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6327                        continue;
6328                    }
6329                // Package has been specified, we want to hit all processes
6330                // that match it.  We need to qualify this by the processes
6331                // that are running under the specified app and user ID.
6332                } else {
6333                    final boolean isDep = app.pkgDeps != null
6334                            && app.pkgDeps.contains(packageName);
6335                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6336                        continue;
6337                    }
6338                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6339                        continue;
6340                    }
6341                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6342                        continue;
6343                    }
6344                }
6345
6346                // Process has passed all conditions, kill it!
6347                if (!doit) {
6348                    return true;
6349                }
6350                app.removed = true;
6351                procs.add(app);
6352            }
6353        }
6354
6355        int N = procs.size();
6356        for (int i=0; i<N; i++) {
6357            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6358        }
6359        updateOomAdjLocked();
6360        return N > 0;
6361    }
6362
6363    private void cleanupDisabledPackageComponentsLocked(
6364            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6365
6366        Set<String> disabledClasses = null;
6367        boolean packageDisabled = false;
6368        IPackageManager pm = AppGlobals.getPackageManager();
6369
6370        if (changedClasses == null) {
6371            // Nothing changed...
6372            return;
6373        }
6374
6375        // Determine enable/disable state of the package and its components.
6376        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6377        for (int i = changedClasses.length - 1; i >= 0; i--) {
6378            final String changedClass = changedClasses[i];
6379
6380            if (changedClass.equals(packageName)) {
6381                try {
6382                    // Entire package setting changed
6383                    enabled = pm.getApplicationEnabledSetting(packageName,
6384                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6385                } catch (Exception e) {
6386                    // No such package/component; probably racing with uninstall.  In any
6387                    // event it means we have nothing further to do here.
6388                    return;
6389                }
6390                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6391                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6392                if (packageDisabled) {
6393                    // Entire package is disabled.
6394                    // No need to continue to check component states.
6395                    disabledClasses = null;
6396                    break;
6397                }
6398            } else {
6399                try {
6400                    enabled = pm.getComponentEnabledSetting(
6401                            new ComponentName(packageName, changedClass),
6402                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6403                } catch (Exception e) {
6404                    // As above, probably racing with uninstall.
6405                    return;
6406                }
6407                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6408                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6409                    if (disabledClasses == null) {
6410                        disabledClasses = new ArraySet<>(changedClasses.length);
6411                    }
6412                    disabledClasses.add(changedClass);
6413                }
6414            }
6415        }
6416
6417        if (!packageDisabled && disabledClasses == null) {
6418            // Nothing to do here...
6419            return;
6420        }
6421
6422        // Clean-up disabled activities.
6423        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6424                packageName, disabledClasses, true, false, userId) && mBooted) {
6425            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6426            mStackSupervisor.scheduleIdleLocked();
6427        }
6428
6429        // Clean-up disabled tasks
6430        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6431
6432        // Clean-up disabled services.
6433        mServices.bringDownDisabledPackageServicesLocked(
6434                packageName, disabledClasses, userId, false, killProcess, true);
6435
6436        // Clean-up disabled providers.
6437        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6438        mProviderMap.collectPackageProvidersLocked(
6439                packageName, disabledClasses, true, false, userId, providers);
6440        for (int i = providers.size() - 1; i >= 0; i--) {
6441            removeDyingProviderLocked(null, providers.get(i), true);
6442        }
6443
6444        // Clean-up disabled broadcast receivers.
6445        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6446            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6447                    packageName, disabledClasses, userId, true);
6448        }
6449
6450    }
6451
6452    final boolean clearBroadcastQueueForUserLocked(int userId) {
6453        boolean didSomething = false;
6454        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6455            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6456                    null, null, userId, true);
6457        }
6458        return didSomething;
6459    }
6460
6461    final boolean forceStopPackageLocked(String packageName, int appId,
6462            boolean callerWillRestart, boolean purgeCache, boolean doit,
6463            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6464        int i;
6465
6466        if (userId == UserHandle.USER_ALL && packageName == null) {
6467            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6468        }
6469
6470        if (appId < 0 && packageName != null) {
6471            try {
6472                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6473                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6474            } catch (RemoteException e) {
6475            }
6476        }
6477
6478        if (doit) {
6479            if (packageName != null) {
6480                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6481                        + " user=" + userId + ": " + reason);
6482            } else {
6483                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6484            }
6485
6486            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6487        }
6488
6489        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6490                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6491                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6492
6493        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6494
6495        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6496                packageName, null, doit, evenPersistent, userId)) {
6497            if (!doit) {
6498                return true;
6499            }
6500            didSomething = true;
6501        }
6502
6503        if (mServices.bringDownDisabledPackageServicesLocked(
6504                packageName, null, userId, evenPersistent, true, doit)) {
6505            if (!doit) {
6506                return true;
6507            }
6508            didSomething = true;
6509        }
6510
6511        if (packageName == null) {
6512            // Remove all sticky broadcasts from this user.
6513            mStickyBroadcasts.remove(userId);
6514        }
6515
6516        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6517        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6518                userId, providers)) {
6519            if (!doit) {
6520                return true;
6521            }
6522            didSomething = true;
6523        }
6524        for (i = providers.size() - 1; i >= 0; i--) {
6525            removeDyingProviderLocked(null, providers.get(i), true);
6526        }
6527
6528        // Remove transient permissions granted from/to this package/user
6529        removeUriPermissionsForPackageLocked(packageName, userId, false);
6530
6531        if (doit) {
6532            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6533                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6534                        packageName, null, userId, doit);
6535            }
6536        }
6537
6538        if (packageName == null || uninstalling) {
6539            // Remove pending intents.  For now we only do this when force
6540            // stopping users, because we have some problems when doing this
6541            // for packages -- app widgets are not currently cleaned up for
6542            // such packages, so they can be left with bad pending intents.
6543            if (mIntentSenderRecords.size() > 0) {
6544                Iterator<WeakReference<PendingIntentRecord>> it
6545                        = mIntentSenderRecords.values().iterator();
6546                while (it.hasNext()) {
6547                    WeakReference<PendingIntentRecord> wpir = it.next();
6548                    if (wpir == null) {
6549                        it.remove();
6550                        continue;
6551                    }
6552                    PendingIntentRecord pir = wpir.get();
6553                    if (pir == null) {
6554                        it.remove();
6555                        continue;
6556                    }
6557                    if (packageName == null) {
6558                        // Stopping user, remove all objects for the user.
6559                        if (pir.key.userId != userId) {
6560                            // Not the same user, skip it.
6561                            continue;
6562                        }
6563                    } else {
6564                        if (UserHandle.getAppId(pir.uid) != appId) {
6565                            // Different app id, skip it.
6566                            continue;
6567                        }
6568                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6569                            // Different user, skip it.
6570                            continue;
6571                        }
6572                        if (!pir.key.packageName.equals(packageName)) {
6573                            // Different package, skip it.
6574                            continue;
6575                        }
6576                    }
6577                    if (!doit) {
6578                        return true;
6579                    }
6580                    didSomething = true;
6581                    it.remove();
6582                    makeIntentSenderCanceledLocked(pir);
6583                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6584                        pir.key.activity.pendingResults.remove(pir.ref);
6585                    }
6586                }
6587            }
6588        }
6589
6590        if (doit) {
6591            if (purgeCache && packageName != null) {
6592                AttributeCache ac = AttributeCache.instance();
6593                if (ac != null) {
6594                    ac.removePackage(packageName);
6595                }
6596            }
6597            if (mBooted) {
6598                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6599                mStackSupervisor.scheduleIdleLocked();
6600            }
6601        }
6602
6603        return didSomething;
6604    }
6605
6606    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6607        return removeProcessNameLocked(name, uid, null);
6608    }
6609
6610    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6611            final ProcessRecord expecting) {
6612        ProcessRecord old = mProcessNames.get(name, uid);
6613        // Only actually remove when the currently recorded value matches the
6614        // record that we expected; if it doesn't match then we raced with a
6615        // newly created process and we don't want to destroy the new one.
6616        if ((expecting == null) || (old == expecting)) {
6617            mProcessNames.remove(name, uid);
6618        }
6619        if (old != null && old.uidRecord != null) {
6620            old.uidRecord.numProcs--;
6621            if (old.uidRecord.numProcs == 0) {
6622                // No more processes using this uid, tell clients it is gone.
6623                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6624                        "No more processes in " + old.uidRecord);
6625                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6626                EventLogTags.writeAmUidStopped(uid);
6627                mActiveUids.remove(uid);
6628                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6629            }
6630            old.uidRecord = null;
6631        }
6632        mIsolatedProcesses.remove(uid);
6633        return old;
6634    }
6635
6636    private final void addProcessNameLocked(ProcessRecord proc) {
6637        // We shouldn't already have a process under this name, but just in case we
6638        // need to clean up whatever may be there now.
6639        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6640        if (old == proc && proc.persistent) {
6641            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6642            Slog.w(TAG, "Re-adding persistent process " + proc);
6643        } else if (old != null) {
6644            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6645        }
6646        UidRecord uidRec = mActiveUids.get(proc.uid);
6647        if (uidRec == null) {
6648            uidRec = new UidRecord(proc.uid);
6649            // This is the first appearance of the uid, report it now!
6650            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6651                    "Creating new process uid: " + uidRec);
6652            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6653                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6654                uidRec.setWhitelist = uidRec.curWhitelist = true;
6655            }
6656            uidRec.updateHasInternetPermission();
6657            mActiveUids.put(proc.uid, uidRec);
6658            EventLogTags.writeAmUidRunning(uidRec.uid);
6659            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6660            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6661        }
6662        proc.uidRecord = uidRec;
6663
6664        // Reset render thread tid if it was already set, so new process can set it again.
6665        proc.renderThreadTid = 0;
6666        uidRec.numProcs++;
6667        mProcessNames.put(proc.processName, proc.uid, proc);
6668        if (proc.isolated) {
6669            mIsolatedProcesses.put(proc.uid, proc);
6670        }
6671    }
6672
6673    boolean removeProcessLocked(ProcessRecord app,
6674            boolean callerWillRestart, boolean allowRestart, String reason) {
6675        final String name = app.processName;
6676        final int uid = app.uid;
6677        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6678            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6679
6680        ProcessRecord old = mProcessNames.get(name, uid);
6681        if (old != app) {
6682            // This process is no longer active, so nothing to do.
6683            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6684            return false;
6685        }
6686        removeProcessNameLocked(name, uid);
6687        if (mHeavyWeightProcess == app) {
6688            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6689                    mHeavyWeightProcess.userId, 0));
6690            mHeavyWeightProcess = null;
6691        }
6692        boolean needRestart = false;
6693        if (app.pid > 0 && app.pid != MY_PID) {
6694            int pid = app.pid;
6695            synchronized (mPidsSelfLocked) {
6696                mPidsSelfLocked.remove(pid);
6697                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6698            }
6699            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6700            if (app.isolated) {
6701                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6702                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6703            }
6704            boolean willRestart = false;
6705            if (app.persistent && !app.isolated) {
6706                if (!callerWillRestart) {
6707                    willRestart = true;
6708                } else {
6709                    needRestart = true;
6710                }
6711            }
6712            app.kill(reason, true);
6713            handleAppDiedLocked(app, willRestart, allowRestart);
6714            if (willRestart) {
6715                removeLruProcessLocked(app);
6716                addAppLocked(app.info, null, false, null /* ABI override */);
6717            }
6718        } else {
6719            mRemovedProcesses.add(app);
6720        }
6721
6722        return needRestart;
6723    }
6724
6725    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6726        cleanupAppInLaunchingProvidersLocked(app, true);
6727        removeProcessLocked(app, false, true, "timeout publishing content providers");
6728    }
6729
6730    private final void processStartTimedOutLocked(ProcessRecord app) {
6731        final int pid = app.pid;
6732        boolean gone = false;
6733        synchronized (mPidsSelfLocked) {
6734            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6735            if (knownApp != null && knownApp.thread == null) {
6736                mPidsSelfLocked.remove(pid);
6737                gone = true;
6738            }
6739        }
6740
6741        if (gone) {
6742            Slog.w(TAG, "Process " + app + " failed to attach");
6743            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6744                    pid, app.uid, app.processName);
6745            removeProcessNameLocked(app.processName, app.uid);
6746            if (mHeavyWeightProcess == app) {
6747                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6748                        mHeavyWeightProcess.userId, 0));
6749                mHeavyWeightProcess = null;
6750            }
6751            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6752            if (app.isolated) {
6753                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6754            }
6755            // Take care of any launching providers waiting for this process.
6756            cleanupAppInLaunchingProvidersLocked(app, true);
6757            // Take care of any services that are waiting for the process.
6758            mServices.processStartTimedOutLocked(app);
6759            app.kill("start timeout", true);
6760            removeLruProcessLocked(app);
6761            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6762                Slog.w(TAG, "Unattached app died before backup, skipping");
6763                mHandler.post(new Runnable() {
6764                @Override
6765                    public void run(){
6766                        try {
6767                            IBackupManager bm = IBackupManager.Stub.asInterface(
6768                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6769                            bm.agentDisconnected(app.info.packageName);
6770                        } catch (RemoteException e) {
6771                            // Can't happen; the backup manager is local
6772                        }
6773                    }
6774                });
6775            }
6776            if (isPendingBroadcastProcessLocked(pid)) {
6777                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6778                skipPendingBroadcastLocked(pid);
6779            }
6780        } else {
6781            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6782        }
6783    }
6784
6785    private final boolean attachApplicationLocked(IApplicationThread thread,
6786            int pid) {
6787
6788        // Find the application record that is being attached...  either via
6789        // the pid if we are running in multiple processes, or just pull the
6790        // next app record if we are emulating process with anonymous threads.
6791        ProcessRecord app;
6792        long startTime = SystemClock.uptimeMillis();
6793        if (pid != MY_PID && pid >= 0) {
6794            synchronized (mPidsSelfLocked) {
6795                app = mPidsSelfLocked.get(pid);
6796            }
6797        } else {
6798            app = null;
6799        }
6800
6801        if (app == null) {
6802            Slog.w(TAG, "No pending application record for pid " + pid
6803                    + " (IApplicationThread " + thread + "); dropping process");
6804            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6805            if (pid > 0 && pid != MY_PID) {
6806                killProcessQuiet(pid);
6807                //TODO: killProcessGroup(app.info.uid, pid);
6808            } else {
6809                try {
6810                    thread.scheduleExit();
6811                } catch (Exception e) {
6812                    // Ignore exceptions.
6813                }
6814            }
6815            return false;
6816        }
6817
6818        // If this application record is still attached to a previous
6819        // process, clean it up now.
6820        if (app.thread != null) {
6821            handleAppDiedLocked(app, true, true);
6822        }
6823
6824        // Tell the process all about itself.
6825
6826        if (DEBUG_ALL) Slog.v(
6827                TAG, "Binding process pid " + pid + " to record " + app);
6828
6829        final String processName = app.processName;
6830        try {
6831            AppDeathRecipient adr = new AppDeathRecipient(
6832                    app, pid, thread);
6833            thread.asBinder().linkToDeath(adr, 0);
6834            app.deathRecipient = adr;
6835        } catch (RemoteException e) {
6836            app.resetPackageList(mProcessStats);
6837            startProcessLocked(app, "link fail", processName);
6838            return false;
6839        }
6840
6841        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6842
6843        app.makeActive(thread, mProcessStats);
6844        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6845        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6846        app.forcingToImportant = null;
6847        updateProcessForegroundLocked(app, false, false);
6848        app.hasShownUi = false;
6849        app.debugging = false;
6850        app.cached = false;
6851        app.killedByAm = false;
6852        app.killed = false;
6853
6854
6855        // We carefully use the same state that PackageManager uses for
6856        // filtering, since we use this flag to decide if we need to install
6857        // providers when user is unlocked later
6858        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6859
6860        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6861
6862        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6863        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6864
6865        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6866            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6867            msg.obj = app;
6868            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6869        }
6870
6871        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6872
6873        if (!normalMode) {
6874            Slog.i(TAG, "Launching preboot mode app: " + app);
6875        }
6876
6877        if (DEBUG_ALL) Slog.v(
6878            TAG, "New app record " + app
6879            + " thread=" + thread.asBinder() + " pid=" + pid);
6880        try {
6881            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6882            if (mDebugApp != null && mDebugApp.equals(processName)) {
6883                testMode = mWaitForDebugger
6884                    ? ApplicationThreadConstants.DEBUG_WAIT
6885                    : ApplicationThreadConstants.DEBUG_ON;
6886                app.debugging = true;
6887                if (mDebugTransient) {
6888                    mDebugApp = mOrigDebugApp;
6889                    mWaitForDebugger = mOrigWaitForDebugger;
6890                }
6891            }
6892            String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6893            ParcelFileDescriptor profileFd = null;
6894            int samplingInterval = 0;
6895            boolean profileAutoStop = false;
6896            boolean profileStreamingOutput = false;
6897            if (mProfileApp != null && mProfileApp.equals(processName)) {
6898                mProfileProc = app;
6899                profileFile = mProfileFile;
6900                profileFd = mProfileFd;
6901                samplingInterval = mSamplingInterval;
6902                profileAutoStop = mAutoStopProfiler;
6903                profileStreamingOutput = mStreamingOutput;
6904            }
6905            boolean enableTrackAllocation = false;
6906            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6907                enableTrackAllocation = true;
6908                mTrackAllocationApp = null;
6909            }
6910
6911            // If the app is being launched for restore or full backup, set it up specially
6912            boolean isRestrictedBackupMode = false;
6913            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6914                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6915                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6916                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6917                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6918            }
6919
6920            if (app.instr != null) {
6921                notifyPackageUse(app.instr.mClass.getPackageName(),
6922                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6923            }
6924            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6925                    + processName + " with config " + getGlobalConfiguration());
6926            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6927            app.compat = compatibilityInfoForPackageLocked(appInfo);
6928            if (profileFd != null) {
6929                profileFd = profileFd.dup();
6930            }
6931            ProfilerInfo profilerInfo = profileFile == null ? null
6932                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6933                                       profileStreamingOutput);
6934
6935            // We deprecated Build.SERIAL and it is not accessible to
6936            // apps that target the v2 security sandbox. Since access to
6937            // the serial is now behind a permission we push down the value.
6938            String buildSerial = Build.UNKNOWN;
6939            if (appInfo.targetSandboxVersion != 2) {
6940                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6941                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6942                        .getSerial();
6943            }
6944
6945            // Check if this is a secondary process that should be incorporated into some
6946            // currently active instrumentation.  (Note we do this AFTER all of the profiling
6947            // stuff above because profiling can currently happen only in the primary
6948            // instrumentation process.)
6949            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6950                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6951                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6952                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6953                        if (aInstr.mTargetProcesses.length == 0) {
6954                            // This is the wildcard mode, where every process brought up for
6955                            // the target instrumentation should be included.
6956                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6957                                app.instr = aInstr;
6958                                aInstr.mRunningProcesses.add(app);
6959                            }
6960                        } else {
6961                            for (String proc : aInstr.mTargetProcesses) {
6962                                if (proc.equals(app.processName)) {
6963                                    app.instr = aInstr;
6964                                    aInstr.mRunningProcesses.add(app);
6965                                    break;
6966                                }
6967                            }
6968                        }
6969                    }
6970                }
6971            }
6972
6973            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6974            mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
6975            if (app.instr != null) {
6976                thread.bindApplication(processName, appInfo, providers,
6977                        app.instr.mClass,
6978                        profilerInfo, app.instr.mArguments,
6979                        app.instr.mWatcher,
6980                        app.instr.mUiAutomationConnection, testMode,
6981                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6982                        isRestrictedBackupMode || !normalMode, app.persistent,
6983                        new Configuration(getGlobalConfiguration()), app.compat,
6984                        getCommonServicesLocked(app.isolated),
6985                        mCoreSettingsObserver.getCoreSettingsLocked(),
6986                        buildSerial);
6987            } else {
6988                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6989                        null, null, null, testMode,
6990                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6991                        isRestrictedBackupMode || !normalMode, app.persistent,
6992                        new Configuration(getGlobalConfiguration()), app.compat,
6993                        getCommonServicesLocked(app.isolated),
6994                        mCoreSettingsObserver.getCoreSettingsLocked(),
6995                        buildSerial);
6996            }
6997
6998            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6999            updateLruProcessLocked(app, false, null);
7000            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7001            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7002        } catch (Exception e) {
7003            // todo: Yikes!  What should we do?  For now we will try to
7004            // start another process, but that could easily get us in
7005            // an infinite loop of restarting processes...
7006            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7007
7008            app.resetPackageList(mProcessStats);
7009            app.unlinkDeathRecipient();
7010            startProcessLocked(app, "bind fail", processName);
7011            return false;
7012        }
7013
7014        // Remove this record from the list of starting applications.
7015        mPersistentStartingProcesses.remove(app);
7016        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7017                "Attach application locked removing on hold: " + app);
7018        mProcessesOnHold.remove(app);
7019
7020        boolean badApp = false;
7021        boolean didSomething = false;
7022
7023        // See if the top visible activity is waiting to run in this process...
7024        if (normalMode) {
7025            try {
7026                if (mStackSupervisor.attachApplicationLocked(app)) {
7027                    didSomething = true;
7028                }
7029            } catch (Exception e) {
7030                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7031                badApp = true;
7032            }
7033        }
7034
7035        // Find any services that should be running in this process...
7036        if (!badApp) {
7037            try {
7038                didSomething |= mServices.attachApplicationLocked(app, processName);
7039                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7040            } catch (Exception e) {
7041                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7042                badApp = true;
7043            }
7044        }
7045
7046        // Check if a next-broadcast receiver is in this process...
7047        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7048            try {
7049                didSomething |= sendPendingBroadcastsLocked(app);
7050                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7051            } catch (Exception e) {
7052                // If the app died trying to launch the receiver we declare it 'bad'
7053                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7054                badApp = true;
7055            }
7056        }
7057
7058        // Check whether the next backup agent is in this process...
7059        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7060            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7061                    "New app is backup target, launching agent for " + app);
7062            notifyPackageUse(mBackupTarget.appInfo.packageName,
7063                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7064            try {
7065                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7066                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7067                        mBackupTarget.backupMode);
7068            } catch (Exception e) {
7069                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7070                badApp = true;
7071            }
7072        }
7073
7074        if (badApp) {
7075            app.kill("error during init", true);
7076            handleAppDiedLocked(app, false, true);
7077            return false;
7078        }
7079
7080        if (!didSomething) {
7081            updateOomAdjLocked();
7082            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7083        }
7084
7085        return true;
7086    }
7087
7088    @Override
7089    public final void attachApplication(IApplicationThread thread) {
7090        synchronized (this) {
7091            int callingPid = Binder.getCallingPid();
7092            final long origId = Binder.clearCallingIdentity();
7093            attachApplicationLocked(thread, callingPid);
7094            Binder.restoreCallingIdentity(origId);
7095        }
7096    }
7097
7098    @Override
7099    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7100        final long origId = Binder.clearCallingIdentity();
7101        synchronized (this) {
7102            ActivityStack stack = ActivityRecord.getStackLocked(token);
7103            if (stack != null) {
7104                ActivityRecord r =
7105                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7106                                false /* processPausingActivities */, config);
7107                if (stopProfiling) {
7108                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
7109                        try {
7110                            mProfileFd.close();
7111                        } catch (IOException e) {
7112                        }
7113                        clearProfilerLocked();
7114                    }
7115                }
7116            }
7117        }
7118        Binder.restoreCallingIdentity(origId);
7119    }
7120
7121    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7122        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7123                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7124    }
7125
7126    void enableScreenAfterBoot() {
7127        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7128                SystemClock.uptimeMillis());
7129        mWindowManager.enableScreenAfterBoot();
7130
7131        synchronized (this) {
7132            updateEventDispatchingLocked();
7133        }
7134    }
7135
7136    @Override
7137    public void showBootMessage(final CharSequence msg, final boolean always) {
7138        if (Binder.getCallingUid() != myUid()) {
7139            throw new SecurityException();
7140        }
7141        mWindowManager.showBootMessage(msg, always);
7142    }
7143
7144    @Override
7145    public void keyguardGoingAway(int flags) {
7146        enforceNotIsolatedCaller("keyguardGoingAway");
7147        final long token = Binder.clearCallingIdentity();
7148        try {
7149            synchronized (this) {
7150                mKeyguardController.keyguardGoingAway(flags);
7151            }
7152        } finally {
7153            Binder.restoreCallingIdentity(token);
7154        }
7155    }
7156
7157    /**
7158     * @return whther the keyguard is currently locked.
7159     */
7160    boolean isKeyguardLocked() {
7161        return mKeyguardController.isKeyguardLocked();
7162    }
7163
7164    final void finishBooting() {
7165        synchronized (this) {
7166            if (!mBootAnimationComplete) {
7167                mCallFinishBooting = true;
7168                return;
7169            }
7170            mCallFinishBooting = false;
7171        }
7172
7173        ArraySet<String> completedIsas = new ArraySet<String>();
7174        for (String abi : Build.SUPPORTED_ABIS) {
7175            zygoteProcess.establishZygoteConnectionForAbi(abi);
7176            final String instructionSet = VMRuntime.getInstructionSet(abi);
7177            if (!completedIsas.contains(instructionSet)) {
7178                try {
7179                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7180                } catch (InstallerException e) {
7181                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7182                            e.getMessage() +")");
7183                }
7184                completedIsas.add(instructionSet);
7185            }
7186        }
7187
7188        IntentFilter pkgFilter = new IntentFilter();
7189        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7190        pkgFilter.addDataScheme("package");
7191        mContext.registerReceiver(new BroadcastReceiver() {
7192            @Override
7193            public void onReceive(Context context, Intent intent) {
7194                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7195                if (pkgs != null) {
7196                    for (String pkg : pkgs) {
7197                        synchronized (ActivityManagerService.this) {
7198                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7199                                    0, "query restart")) {
7200                                setResultCode(Activity.RESULT_OK);
7201                                return;
7202                            }
7203                        }
7204                    }
7205                }
7206            }
7207        }, pkgFilter);
7208
7209        IntentFilter dumpheapFilter = new IntentFilter();
7210        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7211        mContext.registerReceiver(new BroadcastReceiver() {
7212            @Override
7213            public void onReceive(Context context, Intent intent) {
7214                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7215                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7216                } else {
7217                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7218                }
7219            }
7220        }, dumpheapFilter);
7221
7222        // Let system services know.
7223        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7224
7225        synchronized (this) {
7226            // Ensure that any processes we had put on hold are now started
7227            // up.
7228            final int NP = mProcessesOnHold.size();
7229            if (NP > 0) {
7230                ArrayList<ProcessRecord> procs =
7231                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7232                for (int ip=0; ip<NP; ip++) {
7233                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7234                            + procs.get(ip));
7235                    startProcessLocked(procs.get(ip), "on-hold", null);
7236                }
7237            }
7238
7239            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7240                // Start looking for apps that are abusing wake locks.
7241                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7242                mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
7243                // Tell anyone interested that we are done booting!
7244                SystemProperties.set("sys.boot_completed", "1");
7245
7246                // And trigger dev.bootcomplete if we are not showing encryption progress
7247                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7248                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7249                    SystemProperties.set("dev.bootcomplete", "1");
7250                }
7251                mUserController.sendBootCompletedLocked(
7252                        new IIntentReceiver.Stub() {
7253                            @Override
7254                            public void performReceive(Intent intent, int resultCode,
7255                                    String data, Bundle extras, boolean ordered,
7256                                    boolean sticky, int sendingUser) {
7257                                synchronized (ActivityManagerService.this) {
7258                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7259                                            true, false);
7260                                }
7261                            }
7262                        });
7263                scheduleStartProfilesLocked();
7264            }
7265        }
7266    }
7267
7268    @Override
7269    public void bootAnimationComplete() {
7270        final boolean callFinishBooting;
7271        synchronized (this) {
7272            callFinishBooting = mCallFinishBooting;
7273            mBootAnimationComplete = true;
7274        }
7275        if (callFinishBooting) {
7276            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7277            finishBooting();
7278            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7279        }
7280    }
7281
7282    final void ensureBootCompleted() {
7283        boolean booting;
7284        boolean enableScreen;
7285        synchronized (this) {
7286            booting = mBooting;
7287            mBooting = false;
7288            enableScreen = !mBooted;
7289            mBooted = true;
7290        }
7291
7292        if (booting) {
7293            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7294            finishBooting();
7295            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7296        }
7297
7298        if (enableScreen) {
7299            enableScreenAfterBoot();
7300        }
7301    }
7302
7303    @Override
7304    public final void activityResumed(IBinder token) {
7305        final long origId = Binder.clearCallingIdentity();
7306        synchronized(this) {
7307            ActivityRecord.activityResumedLocked(token);
7308            mWindowManager.notifyAppResumedFinished(token);
7309        }
7310        Binder.restoreCallingIdentity(origId);
7311    }
7312
7313    @Override
7314    public final void activityPaused(IBinder token) {
7315        final long origId = Binder.clearCallingIdentity();
7316        synchronized(this) {
7317            ActivityStack stack = ActivityRecord.getStackLocked(token);
7318            if (stack != null) {
7319                stack.activityPausedLocked(token, false);
7320            }
7321        }
7322        Binder.restoreCallingIdentity(origId);
7323    }
7324
7325    @Override
7326    public final void activityStopped(IBinder token, Bundle icicle,
7327            PersistableBundle persistentState, CharSequence description) {
7328        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7329
7330        // Refuse possible leaked file descriptors
7331        if (icicle != null && icicle.hasFileDescriptors()) {
7332            throw new IllegalArgumentException("File descriptors passed in Bundle");
7333        }
7334
7335        final long origId = Binder.clearCallingIdentity();
7336
7337        synchronized (this) {
7338            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7339            if (r != null) {
7340                r.activityStoppedLocked(icicle, persistentState, description);
7341            }
7342        }
7343
7344        trimApplications();
7345
7346        Binder.restoreCallingIdentity(origId);
7347    }
7348
7349    @Override
7350    public final void activityDestroyed(IBinder token) {
7351        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7352        synchronized (this) {
7353            ActivityStack stack = ActivityRecord.getStackLocked(token);
7354            if (stack != null) {
7355                stack.activityDestroyedLocked(token, "activityDestroyed");
7356            }
7357        }
7358    }
7359
7360    @Override
7361    public final void activityRelaunched(IBinder token) {
7362        final long origId = Binder.clearCallingIdentity();
7363        synchronized (this) {
7364            mStackSupervisor.activityRelaunchedLocked(token);
7365        }
7366        Binder.restoreCallingIdentity(origId);
7367    }
7368
7369    @Override
7370    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7371            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7372        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7373                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7374        synchronized (this) {
7375            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7376            if (record == null) {
7377                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7378                        + "found for: " + token);
7379            }
7380            record.setSizeConfigurations(horizontalSizeConfiguration,
7381                    verticalSizeConfigurations, smallestSizeConfigurations);
7382        }
7383    }
7384
7385    @Override
7386    public final void backgroundResourcesReleased(IBinder token) {
7387        final long origId = Binder.clearCallingIdentity();
7388        try {
7389            synchronized (this) {
7390                ActivityStack stack = ActivityRecord.getStackLocked(token);
7391                if (stack != null) {
7392                    stack.backgroundResourcesReleased();
7393                }
7394            }
7395        } finally {
7396            Binder.restoreCallingIdentity(origId);
7397        }
7398    }
7399
7400    @Override
7401    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7402        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7403    }
7404
7405    @Override
7406    public final void notifyEnterAnimationComplete(IBinder token) {
7407        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7408    }
7409
7410    @Override
7411    public String getCallingPackage(IBinder token) {
7412        synchronized (this) {
7413            ActivityRecord r = getCallingRecordLocked(token);
7414            return r != null ? r.info.packageName : null;
7415        }
7416    }
7417
7418    @Override
7419    public ComponentName getCallingActivity(IBinder token) {
7420        synchronized (this) {
7421            ActivityRecord r = getCallingRecordLocked(token);
7422            return r != null ? r.intent.getComponent() : null;
7423        }
7424    }
7425
7426    private ActivityRecord getCallingRecordLocked(IBinder token) {
7427        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7428        if (r == null) {
7429            return null;
7430        }
7431        return r.resultTo;
7432    }
7433
7434    @Override
7435    public ComponentName getActivityClassForToken(IBinder token) {
7436        synchronized(this) {
7437            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7438            if (r == null) {
7439                return null;
7440            }
7441            return r.intent.getComponent();
7442        }
7443    }
7444
7445    @Override
7446    public String getPackageForToken(IBinder token) {
7447        synchronized(this) {
7448            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7449            if (r == null) {
7450                return null;
7451            }
7452            return r.packageName;
7453        }
7454    }
7455
7456    @Override
7457    public boolean isRootVoiceInteraction(IBinder token) {
7458        synchronized(this) {
7459            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7460            if (r == null) {
7461                return false;
7462            }
7463            return r.rootVoiceInteraction;
7464        }
7465    }
7466
7467    @Override
7468    public IIntentSender getIntentSender(int type,
7469            String packageName, IBinder token, String resultWho,
7470            int requestCode, Intent[] intents, String[] resolvedTypes,
7471            int flags, Bundle bOptions, int userId) {
7472        enforceNotIsolatedCaller("getIntentSender");
7473        // Refuse possible leaked file descriptors
7474        if (intents != null) {
7475            if (intents.length < 1) {
7476                throw new IllegalArgumentException("Intents array length must be >= 1");
7477            }
7478            for (int i=0; i<intents.length; i++) {
7479                Intent intent = intents[i];
7480                if (intent != null) {
7481                    if (intent.hasFileDescriptors()) {
7482                        throw new IllegalArgumentException("File descriptors passed in Intent");
7483                    }
7484                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7485                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7486                        throw new IllegalArgumentException(
7487                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7488                    }
7489                    intents[i] = new Intent(intent);
7490                }
7491            }
7492            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7493                throw new IllegalArgumentException(
7494                        "Intent array length does not match resolvedTypes length");
7495            }
7496        }
7497        if (bOptions != null) {
7498            if (bOptions.hasFileDescriptors()) {
7499                throw new IllegalArgumentException("File descriptors passed in options");
7500            }
7501        }
7502
7503        synchronized(this) {
7504            int callingUid = Binder.getCallingUid();
7505            int origUserId = userId;
7506            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7507                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7508                    ALLOW_NON_FULL, "getIntentSender", null);
7509            if (origUserId == UserHandle.USER_CURRENT) {
7510                // We don't want to evaluate this until the pending intent is
7511                // actually executed.  However, we do want to always do the
7512                // security checking for it above.
7513                userId = UserHandle.USER_CURRENT;
7514            }
7515            try {
7516                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7517                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7518                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7519                    if (!UserHandle.isSameApp(callingUid, uid)) {
7520                        String msg = "Permission Denial: getIntentSender() from pid="
7521                            + Binder.getCallingPid()
7522                            + ", uid=" + Binder.getCallingUid()
7523                            + ", (need uid=" + uid + ")"
7524                            + " is not allowed to send as package " + packageName;
7525                        Slog.w(TAG, msg);
7526                        throw new SecurityException(msg);
7527                    }
7528                }
7529
7530                return getIntentSenderLocked(type, packageName, callingUid, userId,
7531                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7532
7533            } catch (RemoteException e) {
7534                throw new SecurityException(e);
7535            }
7536        }
7537    }
7538
7539    IIntentSender getIntentSenderLocked(int type, String packageName,
7540            int callingUid, int userId, IBinder token, String resultWho,
7541            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7542            Bundle bOptions) {
7543        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7544        ActivityRecord activity = null;
7545        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7546            activity = ActivityRecord.isInStackLocked(token);
7547            if (activity == null) {
7548                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7549                return null;
7550            }
7551            if (activity.finishing) {
7552                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7553                return null;
7554            }
7555        }
7556
7557        // We're going to be splicing together extras before sending, so we're
7558        // okay poking into any contained extras.
7559        if (intents != null) {
7560            for (int i = 0; i < intents.length; i++) {
7561                intents[i].setDefusable(true);
7562            }
7563        }
7564        Bundle.setDefusable(bOptions, true);
7565
7566        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7567        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7568        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7569        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7570                |PendingIntent.FLAG_UPDATE_CURRENT);
7571
7572        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7573                type, packageName, activity, resultWho,
7574                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7575        WeakReference<PendingIntentRecord> ref;
7576        ref = mIntentSenderRecords.get(key);
7577        PendingIntentRecord rec = ref != null ? ref.get() : null;
7578        if (rec != null) {
7579            if (!cancelCurrent) {
7580                if (updateCurrent) {
7581                    if (rec.key.requestIntent != null) {
7582                        rec.key.requestIntent.replaceExtras(intents != null ?
7583                                intents[intents.length - 1] : null);
7584                    }
7585                    if (intents != null) {
7586                        intents[intents.length-1] = rec.key.requestIntent;
7587                        rec.key.allIntents = intents;
7588                        rec.key.allResolvedTypes = resolvedTypes;
7589                    } else {
7590                        rec.key.allIntents = null;
7591                        rec.key.allResolvedTypes = null;
7592                    }
7593                }
7594                return rec;
7595            }
7596            makeIntentSenderCanceledLocked(rec);
7597            mIntentSenderRecords.remove(key);
7598        }
7599        if (noCreate) {
7600            return rec;
7601        }
7602        rec = new PendingIntentRecord(this, key, callingUid);
7603        mIntentSenderRecords.put(key, rec.ref);
7604        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7605            if (activity.pendingResults == null) {
7606                activity.pendingResults
7607                        = new HashSet<WeakReference<PendingIntentRecord>>();
7608            }
7609            activity.pendingResults.add(rec.ref);
7610        }
7611        return rec;
7612    }
7613
7614    @Override
7615    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7616            Intent intent, String resolvedType,
7617            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7618        if (target instanceof PendingIntentRecord) {
7619            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7620                    whitelistToken, finishedReceiver, requiredPermission, options);
7621        } else {
7622            if (intent == null) {
7623                // Weird case: someone has given us their own custom IIntentSender, and now
7624                // they have someone else trying to send to it but of course this isn't
7625                // really a PendingIntent, so there is no base Intent, and the caller isn't
7626                // supplying an Intent... but we never want to dispatch a null Intent to
7627                // a receiver, so um...  let's make something up.
7628                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7629                intent = new Intent(Intent.ACTION_MAIN);
7630            }
7631            try {
7632                target.send(code, intent, resolvedType, whitelistToken, null,
7633                        requiredPermission, options);
7634            } catch (RemoteException e) {
7635            }
7636            // Platform code can rely on getting a result back when the send is done, but if
7637            // this intent sender is from outside of the system we can't rely on it doing that.
7638            // So instead we don't give it the result receiver, and instead just directly
7639            // report the finish immediately.
7640            if (finishedReceiver != null) {
7641                try {
7642                    finishedReceiver.performReceive(intent, 0,
7643                            null, null, false, false, UserHandle.getCallingUserId());
7644                } catch (RemoteException e) {
7645                }
7646            }
7647            return 0;
7648        }
7649    }
7650
7651    @Override
7652    public void cancelIntentSender(IIntentSender sender) {
7653        if (!(sender instanceof PendingIntentRecord)) {
7654            return;
7655        }
7656        synchronized(this) {
7657            PendingIntentRecord rec = (PendingIntentRecord)sender;
7658            try {
7659                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7660                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7661                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7662                    String msg = "Permission Denial: cancelIntentSender() from pid="
7663                        + Binder.getCallingPid()
7664                        + ", uid=" + Binder.getCallingUid()
7665                        + " is not allowed to cancel package "
7666                        + rec.key.packageName;
7667                    Slog.w(TAG, msg);
7668                    throw new SecurityException(msg);
7669                }
7670            } catch (RemoteException e) {
7671                throw new SecurityException(e);
7672            }
7673            cancelIntentSenderLocked(rec, true);
7674        }
7675    }
7676
7677    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7678        makeIntentSenderCanceledLocked(rec);
7679        mIntentSenderRecords.remove(rec.key);
7680        if (cleanActivity && rec.key.activity != null) {
7681            rec.key.activity.pendingResults.remove(rec.ref);
7682        }
7683    }
7684
7685    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7686        rec.canceled = true;
7687        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7688        if (callbacks != null) {
7689            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7690        }
7691    }
7692
7693    @Override
7694    public String getPackageForIntentSender(IIntentSender pendingResult) {
7695        if (!(pendingResult instanceof PendingIntentRecord)) {
7696            return null;
7697        }
7698        try {
7699            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7700            return res.key.packageName;
7701        } catch (ClassCastException e) {
7702        }
7703        return null;
7704    }
7705
7706    @Override
7707    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7708        if (!(sender instanceof PendingIntentRecord)) {
7709            return;
7710        }
7711        synchronized(this) {
7712            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7713        }
7714    }
7715
7716    @Override
7717    public void unregisterIntentSenderCancelListener(IIntentSender sender,
7718            IResultReceiver receiver) {
7719        if (!(sender instanceof PendingIntentRecord)) {
7720            return;
7721        }
7722        synchronized(this) {
7723            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7724        }
7725    }
7726
7727    @Override
7728    public int getUidForIntentSender(IIntentSender sender) {
7729        if (sender instanceof PendingIntentRecord) {
7730            try {
7731                PendingIntentRecord res = (PendingIntentRecord)sender;
7732                return res.uid;
7733            } catch (ClassCastException e) {
7734            }
7735        }
7736        return -1;
7737    }
7738
7739    @Override
7740    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7741        if (!(pendingResult instanceof PendingIntentRecord)) {
7742            return false;
7743        }
7744        try {
7745            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7746            if (res.key.allIntents == null) {
7747                return false;
7748            }
7749            for (int i=0; i<res.key.allIntents.length; i++) {
7750                Intent intent = res.key.allIntents[i];
7751                if (intent.getPackage() != null && intent.getComponent() != null) {
7752                    return false;
7753                }
7754            }
7755            return true;
7756        } catch (ClassCastException e) {
7757        }
7758        return false;
7759    }
7760
7761    @Override
7762    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7763        if (!(pendingResult instanceof PendingIntentRecord)) {
7764            return false;
7765        }
7766        try {
7767            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7768            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7769                return true;
7770            }
7771            return false;
7772        } catch (ClassCastException e) {
7773        }
7774        return false;
7775    }
7776
7777    @Override
7778    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7779        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7780                "getIntentForIntentSender()");
7781        if (!(pendingResult instanceof PendingIntentRecord)) {
7782            return null;
7783        }
7784        try {
7785            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7786            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7787        } catch (ClassCastException e) {
7788        }
7789        return null;
7790    }
7791
7792    @Override
7793    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7794        if (!(pendingResult instanceof PendingIntentRecord)) {
7795            return null;
7796        }
7797        try {
7798            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7799            synchronized (this) {
7800                return getTagForIntentSenderLocked(res, prefix);
7801            }
7802        } catch (ClassCastException e) {
7803        }
7804        return null;
7805    }
7806
7807    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7808        final Intent intent = res.key.requestIntent;
7809        if (intent != null) {
7810            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7811                    || res.lastTagPrefix.equals(prefix))) {
7812                return res.lastTag;
7813            }
7814            res.lastTagPrefix = prefix;
7815            final StringBuilder sb = new StringBuilder(128);
7816            if (prefix != null) {
7817                sb.append(prefix);
7818            }
7819            if (intent.getAction() != null) {
7820                sb.append(intent.getAction());
7821            } else if (intent.getComponent() != null) {
7822                intent.getComponent().appendShortString(sb);
7823            } else {
7824                sb.append("?");
7825            }
7826            return res.lastTag = sb.toString();
7827        }
7828        return null;
7829    }
7830
7831    @Override
7832    public void setProcessLimit(int max) {
7833        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7834                "setProcessLimit()");
7835        synchronized (this) {
7836            mConstants.setOverrideMaxCachedProcesses(max);
7837        }
7838        trimApplications();
7839    }
7840
7841    @Override
7842    public int getProcessLimit() {
7843        synchronized (this) {
7844            return mConstants.getOverrideMaxCachedProcesses();
7845        }
7846    }
7847
7848    void importanceTokenDied(ImportanceToken token) {
7849        synchronized (ActivityManagerService.this) {
7850            synchronized (mPidsSelfLocked) {
7851                ImportanceToken cur
7852                    = mImportantProcesses.get(token.pid);
7853                if (cur != token) {
7854                    return;
7855                }
7856                mImportantProcesses.remove(token.pid);
7857                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7858                if (pr == null) {
7859                    return;
7860                }
7861                pr.forcingToImportant = null;
7862                updateProcessForegroundLocked(pr, false, false);
7863            }
7864            updateOomAdjLocked();
7865        }
7866    }
7867
7868    @Override
7869    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7870        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7871                "setProcessImportant()");
7872        synchronized(this) {
7873            boolean changed = false;
7874
7875            synchronized (mPidsSelfLocked) {
7876                ProcessRecord pr = mPidsSelfLocked.get(pid);
7877                if (pr == null && isForeground) {
7878                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7879                    return;
7880                }
7881                ImportanceToken oldToken = mImportantProcesses.get(pid);
7882                if (oldToken != null) {
7883                    oldToken.token.unlinkToDeath(oldToken, 0);
7884                    mImportantProcesses.remove(pid);
7885                    if (pr != null) {
7886                        pr.forcingToImportant = null;
7887                    }
7888                    changed = true;
7889                }
7890                if (isForeground && token != null) {
7891                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7892                        @Override
7893                        public void binderDied() {
7894                            importanceTokenDied(this);
7895                        }
7896                    };
7897                    try {
7898                        token.linkToDeath(newToken, 0);
7899                        mImportantProcesses.put(pid, newToken);
7900                        pr.forcingToImportant = newToken;
7901                        changed = true;
7902                    } catch (RemoteException e) {
7903                        // If the process died while doing this, we will later
7904                        // do the cleanup with the process death link.
7905                    }
7906                }
7907            }
7908
7909            if (changed) {
7910                updateOomAdjLocked();
7911            }
7912        }
7913    }
7914
7915    @Override
7916    public boolean isAppForeground(int uid) throws RemoteException {
7917        synchronized (this) {
7918            UidRecord uidRec = mActiveUids.get(uid);
7919            if (uidRec == null || uidRec.idle) {
7920                return false;
7921            }
7922            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7923        }
7924    }
7925
7926    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7927    // be guarded by permission checking.
7928    int getUidState(int uid) {
7929        synchronized (this) {
7930            return getUidStateLocked(uid);
7931        }
7932    }
7933
7934    int getUidStateLocked(int uid) {
7935        UidRecord uidRec = mActiveUids.get(uid);
7936        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7937    }
7938
7939    @Override
7940    public boolean isInMultiWindowMode(IBinder token) {
7941        final long origId = Binder.clearCallingIdentity();
7942        try {
7943            synchronized(this) {
7944                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7945                if (r == null) {
7946                    return false;
7947                }
7948                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7949                return !r.getTask().mFullscreen;
7950            }
7951        } finally {
7952            Binder.restoreCallingIdentity(origId);
7953        }
7954    }
7955
7956    @Override
7957    public boolean isInPictureInPictureMode(IBinder token) {
7958        final long origId = Binder.clearCallingIdentity();
7959        try {
7960            synchronized(this) {
7961                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
7962            }
7963        } finally {
7964            Binder.restoreCallingIdentity(origId);
7965        }
7966    }
7967
7968    private boolean isInPictureInPictureMode(ActivityRecord r) {
7969        if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
7970                r.getStack().isInStackLocked(r) == null) {
7971            return false;
7972        }
7973
7974        // If we are animating to fullscreen then we have already dispatched the PIP mode
7975        // changed, so we should reflect that check here as well.
7976        final PinnedActivityStack stack = r.getStack();
7977        final PinnedStackWindowController windowController = stack.getWindowContainerController();
7978        return !windowController.isAnimatingBoundsToFullscreen();
7979    }
7980
7981    @Override
7982    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
7983        final long origId = Binder.clearCallingIdentity();
7984        try {
7985            synchronized(this) {
7986                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7987                        "enterPictureInPictureMode", token, params);
7988
7989                // If the activity is already in picture in picture mode, then just return early
7990                if (isInPictureInPictureMode(r)) {
7991                    return true;
7992                }
7993
7994                // Activity supports picture-in-picture, now check that we can enter PiP at this
7995                // point, if it is
7996                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7997                        false /* noThrow */, false /* beforeStopping */)) {
7998                    return false;
7999                }
8000
8001                final Runnable enterPipRunnable = () -> {
8002                    // Only update the saved args from the args that are set
8003                    r.pictureInPictureArgs.copyOnlySet(params);
8004                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8005                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8006                    // Adjust the source bounds by the insets for the transition down
8007                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8008                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8009                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8010                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8011                    stack.setPictureInPictureAspectRatio(aspectRatio);
8012                    stack.setPictureInPictureActions(actions);
8013
8014                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8015                            r.supportsPictureInPictureWhilePausing);
8016                    logPictureInPictureArgs(params);
8017                };
8018
8019                if (isKeyguardLocked()) {
8020                    // If the keyguard is showing or occluded, then try and dismiss it before
8021                    // entering picture-in-picture (this will prompt the user to authenticate if the
8022                    // device is currently locked).
8023                    try {
8024                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8025                            @Override
8026                            public void onDismissError() throws RemoteException {
8027                                // Do nothing
8028                            }
8029
8030                            @Override
8031                            public void onDismissSucceeded() throws RemoteException {
8032                                mHandler.post(enterPipRunnable);
8033                            }
8034
8035                            @Override
8036                            public void onDismissCancelled() throws RemoteException {
8037                                // Do nothing
8038                            }
8039                        });
8040                    } catch (RemoteException e) {
8041                        // Local call
8042                    }
8043                } else {
8044                    // Enter picture in picture immediately otherwise
8045                    enterPipRunnable.run();
8046                }
8047                return true;
8048            }
8049        } finally {
8050            Binder.restoreCallingIdentity(origId);
8051        }
8052    }
8053
8054    @Override
8055    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8056        final long origId = Binder.clearCallingIdentity();
8057        try {
8058            synchronized(this) {
8059                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8060                        "setPictureInPictureParams", token, params);
8061
8062                // Only update the saved args from the args that are set
8063                r.pictureInPictureArgs.copyOnlySet(params);
8064                if (r.getStack().getStackId() == PINNED_STACK_ID) {
8065                    // If the activity is already in picture-in-picture, update the pinned stack now
8066                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8067                    // be used the next time the activity enters PiP
8068                    final PinnedActivityStack stack = r.getStack();
8069                    if (!stack.isAnimatingBoundsToFullscreen()) {
8070                        stack.setPictureInPictureAspectRatio(
8071                                r.pictureInPictureArgs.getAspectRatio());
8072                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8073                    }
8074                }
8075                logPictureInPictureArgs(params);
8076            }
8077        } finally {
8078            Binder.restoreCallingIdentity(origId);
8079        }
8080    }
8081
8082    @Override
8083    public int getMaxNumPictureInPictureActions(IBinder token) {
8084        // Currently, this is a static constant, but later, we may change this to be dependent on
8085        // the context of the activity
8086        return 3;
8087    }
8088
8089    private void logPictureInPictureArgs(PictureInPictureParams params) {
8090        if (params.hasSetActions()) {
8091            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8092                    params.getActions().size());
8093        }
8094        if (params.hasSetAspectRatio()) {
8095            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8096            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8097            MetricsLogger.action(lm);
8098        }
8099    }
8100
8101    /**
8102     * Checks the state of the system and the activity associated with the given {@param token} to
8103     * verify that picture-in-picture is supported for that activity.
8104     *
8105     * @return the activity record for the given {@param token} if all the checks pass.
8106     */
8107    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8108            IBinder token, PictureInPictureParams params) {
8109        if (!mSupportsPictureInPicture) {
8110            throw new IllegalStateException(caller
8111                    + ": Device doesn't support picture-in-picture mode.");
8112        }
8113
8114        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8115        if (r == null) {
8116            throw new IllegalStateException(caller
8117                    + ": Can't find activity for token=" + token);
8118        }
8119
8120        if (!r.supportsPictureInPicture()) {
8121            throw new IllegalStateException(caller
8122                    + ": Current activity does not support picture-in-picture.");
8123        }
8124
8125        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8126            throw new IllegalStateException(caller
8127                    + ": Activities on the home, assistant, or recents stack not supported");
8128        }
8129
8130        if (params.hasSetAspectRatio()
8131                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8132                        params.getAspectRatio())) {
8133            final float minAspectRatio = mContext.getResources().getFloat(
8134                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8135            final float maxAspectRatio = mContext.getResources().getFloat(
8136                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8137            throw new IllegalArgumentException(String.format(caller
8138                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8139                            minAspectRatio, maxAspectRatio));
8140        }
8141
8142        // Truncate the number of actions if necessary
8143        params.truncateActions(getMaxNumPictureInPictureActions(token));
8144
8145        return r;
8146    }
8147
8148    // =========================================================
8149    // PROCESS INFO
8150    // =========================================================
8151
8152    static class ProcessInfoService extends IProcessInfoService.Stub {
8153        final ActivityManagerService mActivityManagerService;
8154        ProcessInfoService(ActivityManagerService activityManagerService) {
8155            mActivityManagerService = activityManagerService;
8156        }
8157
8158        @Override
8159        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8160            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8161                    /*in*/ pids, /*out*/ states, null);
8162        }
8163
8164        @Override
8165        public void getProcessStatesAndOomScoresFromPids(
8166                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8167            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8168                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8169        }
8170    }
8171
8172    /**
8173     * For each PID in the given input array, write the current process state
8174     * for that process into the states array, or -1 to indicate that no
8175     * process with the given PID exists. If scores array is provided, write
8176     * the oom score for the process into the scores array, with INVALID_ADJ
8177     * indicating the PID doesn't exist.
8178     */
8179    public void getProcessStatesAndOomScoresForPIDs(
8180            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8181        if (scores != null) {
8182            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8183                    "getProcessStatesAndOomScoresForPIDs()");
8184        }
8185
8186        if (pids == null) {
8187            throw new NullPointerException("pids");
8188        } else if (states == null) {
8189            throw new NullPointerException("states");
8190        } else if (pids.length != states.length) {
8191            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8192        } else if (scores != null && pids.length != scores.length) {
8193            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8194        }
8195
8196        synchronized (mPidsSelfLocked) {
8197            for (int i = 0; i < pids.length; i++) {
8198                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8199                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8200                        pr.curProcState;
8201                if (scores != null) {
8202                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8203                }
8204            }
8205        }
8206    }
8207
8208    // =========================================================
8209    // PERMISSIONS
8210    // =========================================================
8211
8212    static class PermissionController extends IPermissionController.Stub {
8213        ActivityManagerService mActivityManagerService;
8214        PermissionController(ActivityManagerService activityManagerService) {
8215            mActivityManagerService = activityManagerService;
8216        }
8217
8218        @Override
8219        public boolean checkPermission(String permission, int pid, int uid) {
8220            return mActivityManagerService.checkPermission(permission, pid,
8221                    uid) == PackageManager.PERMISSION_GRANTED;
8222        }
8223
8224        @Override
8225        public String[] getPackagesForUid(int uid) {
8226            return mActivityManagerService.mContext.getPackageManager()
8227                    .getPackagesForUid(uid);
8228        }
8229
8230        @Override
8231        public boolean isRuntimePermission(String permission) {
8232            try {
8233                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8234                        .getPermissionInfo(permission, 0);
8235                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8236                        == PermissionInfo.PROTECTION_DANGEROUS;
8237            } catch (NameNotFoundException nnfe) {
8238                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8239            }
8240            return false;
8241        }
8242    }
8243
8244    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8245        @Override
8246        public int checkComponentPermission(String permission, int pid, int uid,
8247                int owningUid, boolean exported) {
8248            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8249                    owningUid, exported);
8250        }
8251
8252        @Override
8253        public Object getAMSLock() {
8254            return ActivityManagerService.this;
8255        }
8256    }
8257
8258    /**
8259     * This can be called with or without the global lock held.
8260     */
8261    int checkComponentPermission(String permission, int pid, int uid,
8262            int owningUid, boolean exported) {
8263        if (pid == MY_PID) {
8264            return PackageManager.PERMISSION_GRANTED;
8265        }
8266        return ActivityManager.checkComponentPermission(permission, uid,
8267                owningUid, exported);
8268    }
8269
8270    /**
8271     * As the only public entry point for permissions checking, this method
8272     * can enforce the semantic that requesting a check on a null global
8273     * permission is automatically denied.  (Internally a null permission
8274     * string is used when calling {@link #checkComponentPermission} in cases
8275     * when only uid-based security is needed.)
8276     *
8277     * This can be called with or without the global lock held.
8278     */
8279    @Override
8280    public int checkPermission(String permission, int pid, int uid) {
8281        if (permission == null) {
8282            return PackageManager.PERMISSION_DENIED;
8283        }
8284        return checkComponentPermission(permission, pid, uid, -1, true);
8285    }
8286
8287    @Override
8288    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8289        if (permission == null) {
8290            return PackageManager.PERMISSION_DENIED;
8291        }
8292
8293        // We might be performing an operation on behalf of an indirect binder
8294        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8295        // client identity accordingly before proceeding.
8296        Identity tlsIdentity = sCallerIdentity.get();
8297        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8298            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8299                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8300            uid = tlsIdentity.uid;
8301            pid = tlsIdentity.pid;
8302        }
8303
8304        return checkComponentPermission(permission, pid, uid, -1, true);
8305    }
8306
8307    /**
8308     * Binder IPC calls go through the public entry point.
8309     * This can be called with or without the global lock held.
8310     */
8311    int checkCallingPermission(String permission) {
8312        return checkPermission(permission,
8313                Binder.getCallingPid(),
8314                UserHandle.getAppId(Binder.getCallingUid()));
8315    }
8316
8317    /**
8318     * This can be called with or without the global lock held.
8319     */
8320    void enforceCallingPermission(String permission, String func) {
8321        if (checkCallingPermission(permission)
8322                == PackageManager.PERMISSION_GRANTED) {
8323            return;
8324        }
8325
8326        String msg = "Permission Denial: " + func + " from pid="
8327                + Binder.getCallingPid()
8328                + ", uid=" + Binder.getCallingUid()
8329                + " requires " + permission;
8330        Slog.w(TAG, msg);
8331        throw new SecurityException(msg);
8332    }
8333
8334    /**
8335     * Determine if UID is holding permissions required to access {@link Uri} in
8336     * the given {@link ProviderInfo}. Final permission checking is always done
8337     * in {@link ContentProvider}.
8338     */
8339    private final boolean checkHoldingPermissionsLocked(
8340            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8341        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8342                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8343        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8344            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8345                    != PERMISSION_GRANTED) {
8346                return false;
8347            }
8348        }
8349        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8350    }
8351
8352    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8353            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8354        if (pi.applicationInfo.uid == uid) {
8355            return true;
8356        } else if (!pi.exported) {
8357            return false;
8358        }
8359
8360        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8361        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8362        try {
8363            // check if target holds top-level <provider> permissions
8364            if (!readMet && pi.readPermission != null && considerUidPermissions
8365                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8366                readMet = true;
8367            }
8368            if (!writeMet && pi.writePermission != null && considerUidPermissions
8369                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8370                writeMet = true;
8371            }
8372
8373            // track if unprotected read/write is allowed; any denied
8374            // <path-permission> below removes this ability
8375            boolean allowDefaultRead = pi.readPermission == null;
8376            boolean allowDefaultWrite = pi.writePermission == null;
8377
8378            // check if target holds any <path-permission> that match uri
8379            final PathPermission[] pps = pi.pathPermissions;
8380            if (pps != null) {
8381                final String path = grantUri.uri.getPath();
8382                int i = pps.length;
8383                while (i > 0 && (!readMet || !writeMet)) {
8384                    i--;
8385                    PathPermission pp = pps[i];
8386                    if (pp.match(path)) {
8387                        if (!readMet) {
8388                            final String pprperm = pp.getReadPermission();
8389                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8390                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8391                                    + ": match=" + pp.match(path)
8392                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8393                            if (pprperm != null) {
8394                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8395                                        == PERMISSION_GRANTED) {
8396                                    readMet = true;
8397                                } else {
8398                                    allowDefaultRead = false;
8399                                }
8400                            }
8401                        }
8402                        if (!writeMet) {
8403                            final String ppwperm = pp.getWritePermission();
8404                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8405                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8406                                    + ": match=" + pp.match(path)
8407                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8408                            if (ppwperm != null) {
8409                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8410                                        == PERMISSION_GRANTED) {
8411                                    writeMet = true;
8412                                } else {
8413                                    allowDefaultWrite = false;
8414                                }
8415                            }
8416                        }
8417                    }
8418                }
8419            }
8420
8421            // grant unprotected <provider> read/write, if not blocked by
8422            // <path-permission> above
8423            if (allowDefaultRead) readMet = true;
8424            if (allowDefaultWrite) writeMet = true;
8425
8426        } catch (RemoteException e) {
8427            return false;
8428        }
8429
8430        return readMet && writeMet;
8431    }
8432
8433    public boolean isAppStartModeDisabled(int uid, String packageName) {
8434        synchronized (this) {
8435            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8436                    == ActivityManager.APP_START_MODE_DISABLED;
8437        }
8438    }
8439
8440    // Unified app-op and target sdk check
8441    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8442        // Apps that target O+ are always subject to background check
8443        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8444            if (DEBUG_BACKGROUND_CHECK) {
8445                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8446            }
8447            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8448        }
8449        // ...and legacy apps get an AppOp check
8450        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8451                uid, packageName);
8452        if (DEBUG_BACKGROUND_CHECK) {
8453            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8454        }
8455        switch (appop) {
8456            case AppOpsManager.MODE_ALLOWED:
8457                return ActivityManager.APP_START_MODE_NORMAL;
8458            case AppOpsManager.MODE_IGNORED:
8459                return ActivityManager.APP_START_MODE_DELAYED;
8460            default:
8461                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8462        }
8463    }
8464
8465    // Service launch is available to apps with run-in-background exemptions but
8466    // some other background operations are not.  If we're doing a check
8467    // of service-launch policy, allow those callers to proceed unrestricted.
8468    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8469        // Persistent app?
8470        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8471            if (DEBUG_BACKGROUND_CHECK) {
8472                Slog.i(TAG, "App " + uid + "/" + packageName
8473                        + " is persistent; not restricted in background");
8474            }
8475            return ActivityManager.APP_START_MODE_NORMAL;
8476        }
8477
8478        // Non-persistent but background whitelisted?
8479        if (uidOnBackgroundWhitelist(uid)) {
8480            if (DEBUG_BACKGROUND_CHECK) {
8481                Slog.i(TAG, "App " + uid + "/" + packageName
8482                        + " on background whitelist; not restricted in background");
8483            }
8484            return ActivityManager.APP_START_MODE_NORMAL;
8485        }
8486
8487        // Is this app on the battery whitelist?
8488        if (isOnDeviceIdleWhitelistLocked(uid)) {
8489            if (DEBUG_BACKGROUND_CHECK) {
8490                Slog.i(TAG, "App " + uid + "/" + packageName
8491                        + " on idle whitelist; not restricted in background");
8492            }
8493            return ActivityManager.APP_START_MODE_NORMAL;
8494        }
8495
8496        // None of the service-policy criteria apply, so we apply the common criteria
8497        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8498    }
8499
8500    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8501            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8502        UidRecord uidRec = mActiveUids.get(uid);
8503        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8504                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8505                + (uidRec != null ? uidRec.idle : false));
8506        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8507            boolean ephemeral;
8508            if (uidRec == null) {
8509                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8510                        UserHandle.getUserId(uid), packageName);
8511            } else {
8512                ephemeral = uidRec.ephemeral;
8513            }
8514
8515            if (ephemeral) {
8516                // We are hard-core about ephemeral apps not running in the background.
8517                return ActivityManager.APP_START_MODE_DISABLED;
8518            } else {
8519                if (disabledOnly) {
8520                    // The caller is only interested in whether app starts are completely
8521                    // disabled for the given package (that is, it is an instant app).  So
8522                    // we don't need to go further, which is all just seeing if we should
8523                    // apply a "delayed" mode for a regular app.
8524                    return ActivityManager.APP_START_MODE_NORMAL;
8525                }
8526                final int startMode = (alwaysRestrict)
8527                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8528                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8529                                packageTargetSdk);
8530                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8531                        + " pkg=" + packageName + " startMode=" + startMode
8532                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8533                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8534                    // This is an old app that has been forced into a "compatible as possible"
8535                    // mode of background check.  To increase compatibility, we will allow other
8536                    // foreground apps to cause its services to start.
8537                    if (callingPid >= 0) {
8538                        ProcessRecord proc;
8539                        synchronized (mPidsSelfLocked) {
8540                            proc = mPidsSelfLocked.get(callingPid);
8541                        }
8542                        if (proc != null &&
8543                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
8544                            // Whoever is instigating this is in the foreground, so we will allow it
8545                            // to go through.
8546                            return ActivityManager.APP_START_MODE_NORMAL;
8547                        }
8548                    }
8549                }
8550                return startMode;
8551            }
8552        }
8553        return ActivityManager.APP_START_MODE_NORMAL;
8554    }
8555
8556    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8557        final int appId = UserHandle.getAppId(uid);
8558        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8559                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8560                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8561    }
8562
8563    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8564        ProviderInfo pi = null;
8565        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8566        if (cpr != null) {
8567            pi = cpr.info;
8568        } else {
8569            try {
8570                pi = AppGlobals.getPackageManager().resolveContentProvider(
8571                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8572                        userHandle);
8573            } catch (RemoteException ex) {
8574            }
8575        }
8576        return pi;
8577    }
8578
8579    void grantEphemeralAccessLocked(int userId, Intent intent,
8580            int targetAppId, int ephemeralAppId) {
8581        getPackageManagerInternalLocked().
8582                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8583    }
8584
8585    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8586        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8587        if (targetUris != null) {
8588            return targetUris.get(grantUri);
8589        }
8590        return null;
8591    }
8592
8593    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8594            String targetPkg, int targetUid, GrantUri grantUri) {
8595        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8596        if (targetUris == null) {
8597            targetUris = Maps.newArrayMap();
8598            mGrantedUriPermissions.put(targetUid, targetUris);
8599        }
8600
8601        UriPermission perm = targetUris.get(grantUri);
8602        if (perm == null) {
8603            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8604            targetUris.put(grantUri, perm);
8605        }
8606
8607        return perm;
8608    }
8609
8610    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8611            final int modeFlags) {
8612        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8613        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8614                : UriPermission.STRENGTH_OWNED;
8615
8616        // Root gets to do everything.
8617        if (uid == 0) {
8618            return true;
8619        }
8620
8621        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8622        if (perms == null) return false;
8623
8624        // First look for exact match
8625        final UriPermission exactPerm = perms.get(grantUri);
8626        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8627            return true;
8628        }
8629
8630        // No exact match, look for prefixes
8631        final int N = perms.size();
8632        for (int i = 0; i < N; i++) {
8633            final UriPermission perm = perms.valueAt(i);
8634            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8635                    && perm.getStrength(modeFlags) >= minStrength) {
8636                return true;
8637            }
8638        }
8639
8640        return false;
8641    }
8642
8643    /**
8644     * @param uri This uri must NOT contain an embedded userId.
8645     * @param userId The userId in which the uri is to be resolved.
8646     */
8647    @Override
8648    public int checkUriPermission(Uri uri, int pid, int uid,
8649            final int modeFlags, int userId, IBinder callerToken) {
8650        enforceNotIsolatedCaller("checkUriPermission");
8651
8652        // Another redirected-binder-call permissions check as in
8653        // {@link checkPermissionWithToken}.
8654        Identity tlsIdentity = sCallerIdentity.get();
8655        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8656            uid = tlsIdentity.uid;
8657            pid = tlsIdentity.pid;
8658        }
8659
8660        // Our own process gets to do everything.
8661        if (pid == MY_PID) {
8662            return PackageManager.PERMISSION_GRANTED;
8663        }
8664        synchronized (this) {
8665            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8666                    ? PackageManager.PERMISSION_GRANTED
8667                    : PackageManager.PERMISSION_DENIED;
8668        }
8669    }
8670
8671    /**
8672     * Check if the targetPkg can be granted permission to access uri by
8673     * the callingUid using the given modeFlags.  Throws a security exception
8674     * if callingUid is not allowed to do this.  Returns the uid of the target
8675     * if the URI permission grant should be performed; returns -1 if it is not
8676     * needed (for example targetPkg already has permission to access the URI).
8677     * If you already know the uid of the target, you can supply it in
8678     * lastTargetUid else set that to -1.
8679     */
8680    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8681            final int modeFlags, int lastTargetUid) {
8682        if (!Intent.isAccessUriMode(modeFlags)) {
8683            return -1;
8684        }
8685
8686        if (targetPkg != null) {
8687            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8688                    "Checking grant " + targetPkg + " permission to " + grantUri);
8689        }
8690
8691        final IPackageManager pm = AppGlobals.getPackageManager();
8692
8693        // If this is not a content: uri, we can't do anything with it.
8694        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8695            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8696                    "Can't grant URI permission for non-content URI: " + grantUri);
8697            return -1;
8698        }
8699
8700        final String authority = grantUri.uri.getAuthority();
8701        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8702                MATCH_DEBUG_TRIAGED_MISSING);
8703        if (pi == null) {
8704            Slog.w(TAG, "No content provider found for permission check: " +
8705                    grantUri.uri.toSafeString());
8706            return -1;
8707        }
8708
8709        int targetUid = lastTargetUid;
8710        if (targetUid < 0 && targetPkg != null) {
8711            try {
8712                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8713                        UserHandle.getUserId(callingUid));
8714                if (targetUid < 0) {
8715                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8716                            "Can't grant URI permission no uid for: " + targetPkg);
8717                    return -1;
8718                }
8719            } catch (RemoteException ex) {
8720                return -1;
8721            }
8722        }
8723
8724        // If we're extending a persistable grant, then we always need to create
8725        // the grant data structure so that take/release APIs work
8726        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8727            return targetUid;
8728        }
8729
8730        if (targetUid >= 0) {
8731            // First...  does the target actually need this permission?
8732            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8733                // No need to grant the target this permission.
8734                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8735                        "Target " + targetPkg + " already has full permission to " + grantUri);
8736                return -1;
8737            }
8738        } else {
8739            // First...  there is no target package, so can anyone access it?
8740            boolean allowed = pi.exported;
8741            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8742                if (pi.readPermission != null) {
8743                    allowed = false;
8744                }
8745            }
8746            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8747                if (pi.writePermission != null) {
8748                    allowed = false;
8749                }
8750            }
8751            if (allowed) {
8752                return -1;
8753            }
8754        }
8755
8756        /* There is a special cross user grant if:
8757         * - The target is on another user.
8758         * - Apps on the current user can access the uri without any uid permissions.
8759         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8760         * grant uri permissions.
8761         */
8762        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8763                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8764                modeFlags, false /*without considering the uid permissions*/);
8765
8766        // Second...  is the provider allowing granting of URI permissions?
8767        if (!specialCrossUserGrant) {
8768            if (!pi.grantUriPermissions) {
8769                throw new SecurityException("Provider " + pi.packageName
8770                        + "/" + pi.name
8771                        + " does not allow granting of Uri permissions (uri "
8772                        + grantUri + ")");
8773            }
8774            if (pi.uriPermissionPatterns != null) {
8775                final int N = pi.uriPermissionPatterns.length;
8776                boolean allowed = false;
8777                for (int i=0; i<N; i++) {
8778                    if (pi.uriPermissionPatterns[i] != null
8779                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8780                        allowed = true;
8781                        break;
8782                    }
8783                }
8784                if (!allowed) {
8785                    throw new SecurityException("Provider " + pi.packageName
8786                            + "/" + pi.name
8787                            + " does not allow granting of permission to path of Uri "
8788                            + grantUri);
8789                }
8790            }
8791        }
8792
8793        // Third...  does the caller itself have permission to access
8794        // this uri?
8795        final int callingAppId = UserHandle.getAppId(callingUid);
8796        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8797            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8798                // Exempted authority for cropping user photos in Settings app
8799            } else {
8800                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8801                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8802                return -1;
8803            }
8804        }
8805        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8806            // Require they hold a strong enough Uri permission
8807            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8808                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8809                    throw new SecurityException(
8810                            "UID " + callingUid + " does not have permission to " + grantUri
8811                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8812                                    + "or related APIs");
8813                } else {
8814                    throw new SecurityException(
8815                            "UID " + callingUid + " does not have permission to " + grantUri);
8816                }
8817            }
8818        }
8819        return targetUid;
8820    }
8821
8822    /**
8823     * @param uri This uri must NOT contain an embedded userId.
8824     * @param userId The userId in which the uri is to be resolved.
8825     */
8826    @Override
8827    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8828            final int modeFlags, int userId) {
8829        enforceNotIsolatedCaller("checkGrantUriPermission");
8830        synchronized(this) {
8831            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8832                    new GrantUri(userId, uri, false), modeFlags, -1);
8833        }
8834    }
8835
8836    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8837            final int modeFlags, UriPermissionOwner owner) {
8838        if (!Intent.isAccessUriMode(modeFlags)) {
8839            return;
8840        }
8841
8842        // So here we are: the caller has the assumed permission
8843        // to the uri, and the target doesn't.  Let's now give this to
8844        // the target.
8845
8846        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8847                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8848
8849        final String authority = grantUri.uri.getAuthority();
8850        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8851                MATCH_DEBUG_TRIAGED_MISSING);
8852        if (pi == null) {
8853            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8854            return;
8855        }
8856
8857        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8858            grantUri.prefix = true;
8859        }
8860        final UriPermission perm = findOrCreateUriPermissionLocked(
8861                pi.packageName, targetPkg, targetUid, grantUri);
8862        perm.grantModes(modeFlags, owner);
8863    }
8864
8865    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8866            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8867        if (targetPkg == null) {
8868            throw new NullPointerException("targetPkg");
8869        }
8870        int targetUid;
8871        final IPackageManager pm = AppGlobals.getPackageManager();
8872        try {
8873            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8874        } catch (RemoteException ex) {
8875            return;
8876        }
8877
8878        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8879                targetUid);
8880        if (targetUid < 0) {
8881            return;
8882        }
8883
8884        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8885                owner);
8886    }
8887
8888    static class NeededUriGrants extends ArrayList<GrantUri> {
8889        final String targetPkg;
8890        final int targetUid;
8891        final int flags;
8892
8893        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8894            this.targetPkg = targetPkg;
8895            this.targetUid = targetUid;
8896            this.flags = flags;
8897        }
8898    }
8899
8900    /**
8901     * Like checkGrantUriPermissionLocked, but takes an Intent.
8902     */
8903    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8904            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8905        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8906                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8907                + " clip=" + (intent != null ? intent.getClipData() : null)
8908                + " from " + intent + "; flags=0x"
8909                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8910
8911        if (targetPkg == null) {
8912            throw new NullPointerException("targetPkg");
8913        }
8914
8915        if (intent == null) {
8916            return null;
8917        }
8918        Uri data = intent.getData();
8919        ClipData clip = intent.getClipData();
8920        if (data == null && clip == null) {
8921            return null;
8922        }
8923        // Default userId for uris in the intent (if they don't specify it themselves)
8924        int contentUserHint = intent.getContentUserHint();
8925        if (contentUserHint == UserHandle.USER_CURRENT) {
8926            contentUserHint = UserHandle.getUserId(callingUid);
8927        }
8928        final IPackageManager pm = AppGlobals.getPackageManager();
8929        int targetUid;
8930        if (needed != null) {
8931            targetUid = needed.targetUid;
8932        } else {
8933            try {
8934                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8935                        targetUserId);
8936            } catch (RemoteException ex) {
8937                return null;
8938            }
8939            if (targetUid < 0) {
8940                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8941                        "Can't grant URI permission no uid for: " + targetPkg
8942                        + " on user " + targetUserId);
8943                return null;
8944            }
8945        }
8946        if (data != null) {
8947            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8948            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8949                    targetUid);
8950            if (targetUid > 0) {
8951                if (needed == null) {
8952                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8953                }
8954                needed.add(grantUri);
8955            }
8956        }
8957        if (clip != null) {
8958            for (int i=0; i<clip.getItemCount(); i++) {
8959                Uri uri = clip.getItemAt(i).getUri();
8960                if (uri != null) {
8961                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8962                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8963                            targetUid);
8964                    if (targetUid > 0) {
8965                        if (needed == null) {
8966                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8967                        }
8968                        needed.add(grantUri);
8969                    }
8970                } else {
8971                    Intent clipIntent = clip.getItemAt(i).getIntent();
8972                    if (clipIntent != null) {
8973                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8974                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8975                        if (newNeeded != null) {
8976                            needed = newNeeded;
8977                        }
8978                    }
8979                }
8980            }
8981        }
8982
8983        return needed;
8984    }
8985
8986    /**
8987     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8988     */
8989    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8990            UriPermissionOwner owner) {
8991        if (needed != null) {
8992            for (int i=0; i<needed.size(); i++) {
8993                GrantUri grantUri = needed.get(i);
8994                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8995                        grantUri, needed.flags, owner);
8996            }
8997        }
8998    }
8999
9000    void grantUriPermissionFromIntentLocked(int callingUid,
9001            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9002        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9003                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9004        if (needed == null) {
9005            return;
9006        }
9007
9008        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9009    }
9010
9011    /**
9012     * @param uri This uri must NOT contain an embedded userId.
9013     * @param userId The userId in which the uri is to be resolved.
9014     */
9015    @Override
9016    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9017            final int modeFlags, int userId) {
9018        enforceNotIsolatedCaller("grantUriPermission");
9019        GrantUri grantUri = new GrantUri(userId, uri, false);
9020        synchronized(this) {
9021            final ProcessRecord r = getRecordForAppLocked(caller);
9022            if (r == null) {
9023                throw new SecurityException("Unable to find app for caller "
9024                        + caller
9025                        + " when granting permission to uri " + grantUri);
9026            }
9027            if (targetPkg == null) {
9028                throw new IllegalArgumentException("null target");
9029            }
9030            if (grantUri == null) {
9031                throw new IllegalArgumentException("null uri");
9032            }
9033
9034            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9035                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9036                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9037                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9038
9039            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9040                    UserHandle.getUserId(r.uid));
9041        }
9042    }
9043
9044    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9045        if (perm.modeFlags == 0) {
9046            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9047                    perm.targetUid);
9048            if (perms != null) {
9049                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9050                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9051
9052                perms.remove(perm.uri);
9053                if (perms.isEmpty()) {
9054                    mGrantedUriPermissions.remove(perm.targetUid);
9055                }
9056            }
9057        }
9058    }
9059
9060    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9061            final int modeFlags) {
9062        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9063                "Revoking all granted permissions to " + grantUri);
9064
9065        final IPackageManager pm = AppGlobals.getPackageManager();
9066        final String authority = grantUri.uri.getAuthority();
9067        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9068                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9069        if (pi == null) {
9070            Slog.w(TAG, "No content provider found for permission revoke: "
9071                    + grantUri.toSafeString());
9072            return;
9073        }
9074
9075        // Does the caller have this permission on the URI?
9076        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9077            // If they don't have direct access to the URI, then revoke any
9078            // ownerless URI permissions that have been granted to them.
9079            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9080            if (perms != null) {
9081                boolean persistChanged = false;
9082                for (int i = perms.size()-1; i >= 0; i--) {
9083                    final UriPermission perm = perms.valueAt(i);
9084                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9085                        continue;
9086                    }
9087                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9088                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9089                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9090                                "Revoking non-owned " + perm.targetUid
9091                                + " permission to " + perm.uri);
9092                        persistChanged |= perm.revokeModes(
9093                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9094                        if (perm.modeFlags == 0) {
9095                            perms.removeAt(i);
9096                        }
9097                    }
9098                }
9099                if (perms.isEmpty()) {
9100                    mGrantedUriPermissions.remove(callingUid);
9101                }
9102                if (persistChanged) {
9103                    schedulePersistUriGrants();
9104                }
9105            }
9106            return;
9107        }
9108
9109        boolean persistChanged = false;
9110
9111        // Go through all of the permissions and remove any that match.
9112        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9113            final int targetUid = mGrantedUriPermissions.keyAt(i);
9114            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9115
9116            for (int j = perms.size()-1; j >= 0; j--) {
9117                final UriPermission perm = perms.valueAt(j);
9118                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9119                    continue;
9120                }
9121                if (perm.uri.sourceUserId == grantUri.sourceUserId
9122                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9123                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9124                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9125                    persistChanged |= perm.revokeModes(
9126                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9127                            targetPackage == null);
9128                    if (perm.modeFlags == 0) {
9129                        perms.removeAt(j);
9130                    }
9131                }
9132            }
9133
9134            if (perms.isEmpty()) {
9135                mGrantedUriPermissions.removeAt(i);
9136            }
9137        }
9138
9139        if (persistChanged) {
9140            schedulePersistUriGrants();
9141        }
9142    }
9143
9144    /**
9145     * @param uri This uri must NOT contain an embedded userId.
9146     * @param userId The userId in which the uri is to be resolved.
9147     */
9148    @Override
9149    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9150            final int modeFlags, int userId) {
9151        enforceNotIsolatedCaller("revokeUriPermission");
9152        synchronized(this) {
9153            final ProcessRecord r = getRecordForAppLocked(caller);
9154            if (r == null) {
9155                throw new SecurityException("Unable to find app for caller "
9156                        + caller
9157                        + " when revoking permission to uri " + uri);
9158            }
9159            if (uri == null) {
9160                Slog.w(TAG, "revokeUriPermission: null uri");
9161                return;
9162            }
9163
9164            if (!Intent.isAccessUriMode(modeFlags)) {
9165                return;
9166            }
9167
9168            final String authority = uri.getAuthority();
9169            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9170                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9171            if (pi == null) {
9172                Slog.w(TAG, "No content provider found for permission revoke: "
9173                        + uri.toSafeString());
9174                return;
9175            }
9176
9177            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9178                    modeFlags);
9179        }
9180    }
9181
9182    /**
9183     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9184     * given package.
9185     *
9186     * @param packageName Package name to match, or {@code null} to apply to all
9187     *            packages.
9188     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9189     *            to all users.
9190     * @param persistable If persistable grants should be removed.
9191     */
9192    private void removeUriPermissionsForPackageLocked(
9193            String packageName, int userHandle, boolean persistable) {
9194        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9195            throw new IllegalArgumentException("Must narrow by either package or user");
9196        }
9197
9198        boolean persistChanged = false;
9199
9200        int N = mGrantedUriPermissions.size();
9201        for (int i = 0; i < N; i++) {
9202            final int targetUid = mGrantedUriPermissions.keyAt(i);
9203            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9204
9205            // Only inspect grants matching user
9206            if (userHandle == UserHandle.USER_ALL
9207                    || userHandle == UserHandle.getUserId(targetUid)) {
9208                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9209                    final UriPermission perm = it.next();
9210
9211                    // Only inspect grants matching package
9212                    if (packageName == null || perm.sourcePkg.equals(packageName)
9213                            || perm.targetPkg.equals(packageName)) {
9214                        // Hacky solution as part of fixing a security bug; ignore
9215                        // grants associated with DownloadManager so we don't have
9216                        // to immediately launch it to regrant the permissions
9217                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9218                                && !persistable) continue;
9219
9220                        persistChanged |= perm.revokeModes(persistable
9221                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9222
9223                        // Only remove when no modes remain; any persisted grants
9224                        // will keep this alive.
9225                        if (perm.modeFlags == 0) {
9226                            it.remove();
9227                        }
9228                    }
9229                }
9230
9231                if (perms.isEmpty()) {
9232                    mGrantedUriPermissions.remove(targetUid);
9233                    N--;
9234                    i--;
9235                }
9236            }
9237        }
9238
9239        if (persistChanged) {
9240            schedulePersistUriGrants();
9241        }
9242    }
9243
9244    @Override
9245    public IBinder newUriPermissionOwner(String name) {
9246        enforceNotIsolatedCaller("newUriPermissionOwner");
9247        synchronized(this) {
9248            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9249            return owner.getExternalTokenLocked();
9250        }
9251    }
9252
9253    @Override
9254    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9255        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9256        synchronized(this) {
9257            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9258            if (r == null) {
9259                throw new IllegalArgumentException("Activity does not exist; token="
9260                        + activityToken);
9261            }
9262            return r.getUriPermissionsLocked().getExternalTokenLocked();
9263        }
9264    }
9265    /**
9266     * @param uri This uri must NOT contain an embedded userId.
9267     * @param sourceUserId The userId in which the uri is to be resolved.
9268     * @param targetUserId The userId of the app that receives the grant.
9269     */
9270    @Override
9271    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9272            final int modeFlags, int sourceUserId, int targetUserId) {
9273        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9274                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9275                "grantUriPermissionFromOwner", null);
9276        synchronized(this) {
9277            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9278            if (owner == null) {
9279                throw new IllegalArgumentException("Unknown owner: " + token);
9280            }
9281            if (fromUid != Binder.getCallingUid()) {
9282                if (Binder.getCallingUid() != myUid()) {
9283                    // Only system code can grant URI permissions on behalf
9284                    // of other users.
9285                    throw new SecurityException("nice try");
9286                }
9287            }
9288            if (targetPkg == null) {
9289                throw new IllegalArgumentException("null target");
9290            }
9291            if (uri == null) {
9292                throw new IllegalArgumentException("null uri");
9293            }
9294
9295            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9296                    modeFlags, owner, targetUserId);
9297        }
9298    }
9299
9300    /**
9301     * @param uri This uri must NOT contain an embedded userId.
9302     * @param userId The userId in which the uri is to be resolved.
9303     */
9304    @Override
9305    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9306        synchronized(this) {
9307            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9308            if (owner == null) {
9309                throw new IllegalArgumentException("Unknown owner: " + token);
9310            }
9311
9312            if (uri == null) {
9313                owner.removeUriPermissionsLocked(mode);
9314            } else {
9315                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9316                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9317            }
9318        }
9319    }
9320
9321    private void schedulePersistUriGrants() {
9322        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9323            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9324                    10 * DateUtils.SECOND_IN_MILLIS);
9325        }
9326    }
9327
9328    private void writeGrantedUriPermissions() {
9329        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9330
9331        // Snapshot permissions so we can persist without lock
9332        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9333        synchronized (this) {
9334            final int size = mGrantedUriPermissions.size();
9335            for (int i = 0; i < size; i++) {
9336                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9337                for (UriPermission perm : perms.values()) {
9338                    if (perm.persistedModeFlags != 0) {
9339                        persist.add(perm.snapshot());
9340                    }
9341                }
9342            }
9343        }
9344
9345        FileOutputStream fos = null;
9346        try {
9347            fos = mGrantFile.startWrite();
9348
9349            XmlSerializer out = new FastXmlSerializer();
9350            out.setOutput(fos, StandardCharsets.UTF_8.name());
9351            out.startDocument(null, true);
9352            out.startTag(null, TAG_URI_GRANTS);
9353            for (UriPermission.Snapshot perm : persist) {
9354                out.startTag(null, TAG_URI_GRANT);
9355                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9356                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9357                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9358                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9359                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9360                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9361                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9362                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9363                out.endTag(null, TAG_URI_GRANT);
9364            }
9365            out.endTag(null, TAG_URI_GRANTS);
9366            out.endDocument();
9367
9368            mGrantFile.finishWrite(fos);
9369        } catch (IOException e) {
9370            if (fos != null) {
9371                mGrantFile.failWrite(fos);
9372            }
9373        }
9374    }
9375
9376    private void readGrantedUriPermissionsLocked() {
9377        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9378
9379        final long now = System.currentTimeMillis();
9380
9381        FileInputStream fis = null;
9382        try {
9383            fis = mGrantFile.openRead();
9384            final XmlPullParser in = Xml.newPullParser();
9385            in.setInput(fis, StandardCharsets.UTF_8.name());
9386
9387            int type;
9388            while ((type = in.next()) != END_DOCUMENT) {
9389                final String tag = in.getName();
9390                if (type == START_TAG) {
9391                    if (TAG_URI_GRANT.equals(tag)) {
9392                        final int sourceUserId;
9393                        final int targetUserId;
9394                        final int userHandle = readIntAttribute(in,
9395                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9396                        if (userHandle != UserHandle.USER_NULL) {
9397                            // For backwards compatibility.
9398                            sourceUserId = userHandle;
9399                            targetUserId = userHandle;
9400                        } else {
9401                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9402                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9403                        }
9404                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9405                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9406                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9407                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9408                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9409                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9410
9411                        // Sanity check that provider still belongs to source package
9412                        // Both direct boot aware and unaware packages are fine as we
9413                        // will do filtering at query time to avoid multiple parsing.
9414                        final ProviderInfo pi = getProviderInfoLocked(
9415                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9416                                        | MATCH_DIRECT_BOOT_UNAWARE);
9417                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9418                            int targetUid = -1;
9419                            try {
9420                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9421                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9422                            } catch (RemoteException e) {
9423                            }
9424                            if (targetUid != -1) {
9425                                final UriPermission perm = findOrCreateUriPermissionLocked(
9426                                        sourcePkg, targetPkg, targetUid,
9427                                        new GrantUri(sourceUserId, uri, prefix));
9428                                perm.initPersistedModes(modeFlags, createdTime);
9429                            }
9430                        } else {
9431                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9432                                    + " but instead found " + pi);
9433                        }
9434                    }
9435                }
9436            }
9437        } catch (FileNotFoundException e) {
9438            // Missing grants is okay
9439        } catch (IOException e) {
9440            Slog.wtf(TAG, "Failed reading Uri grants", e);
9441        } catch (XmlPullParserException e) {
9442            Slog.wtf(TAG, "Failed reading Uri grants", e);
9443        } finally {
9444            IoUtils.closeQuietly(fis);
9445        }
9446    }
9447
9448    /**
9449     * @param uri This uri must NOT contain an embedded userId.
9450     * @param userId The userId in which the uri is to be resolved.
9451     */
9452    @Override
9453    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9454        enforceNotIsolatedCaller("takePersistableUriPermission");
9455
9456        Preconditions.checkFlagsArgument(modeFlags,
9457                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9458
9459        synchronized (this) {
9460            final int callingUid = Binder.getCallingUid();
9461            boolean persistChanged = false;
9462            GrantUri grantUri = new GrantUri(userId, uri, false);
9463
9464            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9465                    new GrantUri(userId, uri, false));
9466            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9467                    new GrantUri(userId, uri, true));
9468
9469            final boolean exactValid = (exactPerm != null)
9470                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9471            final boolean prefixValid = (prefixPerm != null)
9472                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9473
9474            if (!(exactValid || prefixValid)) {
9475                throw new SecurityException("No persistable permission grants found for UID "
9476                        + callingUid + " and Uri " + grantUri.toSafeString());
9477            }
9478
9479            if (exactValid) {
9480                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9481            }
9482            if (prefixValid) {
9483                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9484            }
9485
9486            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9487
9488            if (persistChanged) {
9489                schedulePersistUriGrants();
9490            }
9491        }
9492    }
9493
9494    /**
9495     * @param uri This uri must NOT contain an embedded userId.
9496     * @param userId The userId in which the uri is to be resolved.
9497     */
9498    @Override
9499    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9500        enforceNotIsolatedCaller("releasePersistableUriPermission");
9501
9502        Preconditions.checkFlagsArgument(modeFlags,
9503                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9504
9505        synchronized (this) {
9506            final int callingUid = Binder.getCallingUid();
9507            boolean persistChanged = false;
9508
9509            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9510                    new GrantUri(userId, uri, false));
9511            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9512                    new GrantUri(userId, uri, true));
9513            if (exactPerm == null && prefixPerm == null) {
9514                throw new SecurityException("No permission grants found for UID " + callingUid
9515                        + " and Uri " + uri.toSafeString());
9516            }
9517
9518            if (exactPerm != null) {
9519                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9520                removeUriPermissionIfNeededLocked(exactPerm);
9521            }
9522            if (prefixPerm != null) {
9523                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9524                removeUriPermissionIfNeededLocked(prefixPerm);
9525            }
9526
9527            if (persistChanged) {
9528                schedulePersistUriGrants();
9529            }
9530        }
9531    }
9532
9533    /**
9534     * Prune any older {@link UriPermission} for the given UID until outstanding
9535     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9536     *
9537     * @return if any mutations occured that require persisting.
9538     */
9539    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9540        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9541        if (perms == null) return false;
9542        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9543
9544        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9545        for (UriPermission perm : perms.values()) {
9546            if (perm.persistedModeFlags != 0) {
9547                persisted.add(perm);
9548            }
9549        }
9550
9551        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9552        if (trimCount <= 0) return false;
9553
9554        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9555        for (int i = 0; i < trimCount; i++) {
9556            final UriPermission perm = persisted.get(i);
9557
9558            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9559                    "Trimming grant created at " + perm.persistedCreateTime);
9560
9561            perm.releasePersistableModes(~0);
9562            removeUriPermissionIfNeededLocked(perm);
9563        }
9564
9565        return true;
9566    }
9567
9568    @Override
9569    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9570            String packageName, boolean incoming) {
9571        enforceNotIsolatedCaller("getPersistedUriPermissions");
9572        Preconditions.checkNotNull(packageName, "packageName");
9573
9574        final int callingUid = Binder.getCallingUid();
9575        final int callingUserId = UserHandle.getUserId(callingUid);
9576        final IPackageManager pm = AppGlobals.getPackageManager();
9577        try {
9578            final int packageUid = pm.getPackageUid(packageName,
9579                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9580            if (packageUid != callingUid) {
9581                throw new SecurityException(
9582                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9583            }
9584        } catch (RemoteException e) {
9585            throw new SecurityException("Failed to verify package name ownership");
9586        }
9587
9588        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9589        synchronized (this) {
9590            if (incoming) {
9591                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9592                        callingUid);
9593                if (perms == null) {
9594                    Slog.w(TAG, "No permission grants found for " + packageName);
9595                } else {
9596                    for (UriPermission perm : perms.values()) {
9597                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9598                            result.add(perm.buildPersistedPublicApiObject());
9599                        }
9600                    }
9601                }
9602            } else {
9603                final int size = mGrantedUriPermissions.size();
9604                for (int i = 0; i < size; i++) {
9605                    final ArrayMap<GrantUri, UriPermission> perms =
9606                            mGrantedUriPermissions.valueAt(i);
9607                    for (UriPermission perm : perms.values()) {
9608                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9609                            result.add(perm.buildPersistedPublicApiObject());
9610                        }
9611                    }
9612                }
9613            }
9614        }
9615        return new ParceledListSlice<android.content.UriPermission>(result);
9616    }
9617
9618    @Override
9619    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9620            String packageName, int userId) {
9621        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9622                "getGrantedUriPermissions");
9623
9624        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9625        synchronized (this) {
9626            final int size = mGrantedUriPermissions.size();
9627            for (int i = 0; i < size; i++) {
9628                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9629                for (UriPermission perm : perms.values()) {
9630                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9631                            && perm.persistedModeFlags != 0) {
9632                        result.add(perm.buildPersistedPublicApiObject());
9633                    }
9634                }
9635            }
9636        }
9637        return new ParceledListSlice<android.content.UriPermission>(result);
9638    }
9639
9640    @Override
9641    public void clearGrantedUriPermissions(String packageName, int userId) {
9642        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9643                "clearGrantedUriPermissions");
9644        removeUriPermissionsForPackageLocked(packageName, userId, true);
9645    }
9646
9647    @Override
9648    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9649        synchronized (this) {
9650            ProcessRecord app =
9651                who != null ? getRecordForAppLocked(who) : null;
9652            if (app == null) return;
9653
9654            Message msg = Message.obtain();
9655            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9656            msg.obj = app;
9657            msg.arg1 = waiting ? 1 : 0;
9658            mUiHandler.sendMessage(msg);
9659        }
9660    }
9661
9662    @Override
9663    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9664        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9665        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9666        outInfo.availMem = getFreeMemory();
9667        outInfo.totalMem = getTotalMemory();
9668        outInfo.threshold = homeAppMem;
9669        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9670        outInfo.hiddenAppThreshold = cachedAppMem;
9671        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9672                ProcessList.SERVICE_ADJ);
9673        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9674                ProcessList.VISIBLE_APP_ADJ);
9675        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9676                ProcessList.FOREGROUND_APP_ADJ);
9677    }
9678
9679    // =========================================================
9680    // TASK MANAGEMENT
9681    // =========================================================
9682
9683    @Override
9684    public List<IBinder> getAppTasks(String callingPackage) {
9685        int callingUid = Binder.getCallingUid();
9686        long ident = Binder.clearCallingIdentity();
9687
9688        synchronized(this) {
9689            ArrayList<IBinder> list = new ArrayList<IBinder>();
9690            try {
9691                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9692
9693                final int N = mRecentTasks.size();
9694                for (int i = 0; i < N; i++) {
9695                    TaskRecord tr = mRecentTasks.get(i);
9696                    // Skip tasks that do not match the caller.  We don't need to verify
9697                    // callingPackage, because we are also limiting to callingUid and know
9698                    // that will limit to the correct security sandbox.
9699                    if (tr.effectiveUid != callingUid) {
9700                        continue;
9701                    }
9702                    Intent intent = tr.getBaseIntent();
9703                    if (intent == null ||
9704                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9705                        continue;
9706                    }
9707                    ActivityManager.RecentTaskInfo taskInfo =
9708                            createRecentTaskInfoFromTaskRecord(tr);
9709                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9710                    list.add(taskImpl.asBinder());
9711                }
9712            } finally {
9713                Binder.restoreCallingIdentity(ident);
9714            }
9715            return list;
9716        }
9717    }
9718
9719    @Override
9720    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9721        final int callingUid = Binder.getCallingUid();
9722        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9723
9724        synchronized(this) {
9725            if (DEBUG_ALL) Slog.v(
9726                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9727
9728            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9729                    callingUid);
9730
9731            // TODO: Improve with MRU list from all ActivityStacks.
9732            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9733        }
9734
9735        return list;
9736    }
9737
9738    /**
9739     * Creates a new RecentTaskInfo from a TaskRecord.
9740     */
9741    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9742        // Update the task description to reflect any changes in the task stack
9743        tr.updateTaskDescription();
9744
9745        // Compose the recent task info
9746        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9747        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9748        rti.persistentId = tr.taskId;
9749        rti.baseIntent = new Intent(tr.getBaseIntent());
9750        rti.origActivity = tr.origActivity;
9751        rti.realActivity = tr.realActivity;
9752        rti.description = tr.lastDescription;
9753        rti.stackId = tr.getStackId();
9754        rti.userId = tr.userId;
9755        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9756        rti.firstActiveTime = tr.firstActiveTime;
9757        rti.lastActiveTime = tr.lastActiveTime;
9758        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9759        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9760        rti.numActivities = 0;
9761        if (tr.mBounds != null) {
9762            rti.bounds = new Rect(tr.mBounds);
9763        }
9764        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9765        rti.resizeMode = tr.mResizeMode;
9766
9767        ActivityRecord base = null;
9768        ActivityRecord top = null;
9769        ActivityRecord tmp;
9770
9771        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9772            tmp = tr.mActivities.get(i);
9773            if (tmp.finishing) {
9774                continue;
9775            }
9776            base = tmp;
9777            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9778                top = base;
9779            }
9780            rti.numActivities++;
9781        }
9782
9783        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9784        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9785
9786        return rti;
9787    }
9788
9789    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9790        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9791                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9792        if (!allowed) {
9793            if (checkPermission(android.Manifest.permission.GET_TASKS,
9794                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9795                // Temporary compatibility: some existing apps on the system image may
9796                // still be requesting the old permission and not switched to the new
9797                // one; if so, we'll still allow them full access.  This means we need
9798                // to see if they are holding the old permission and are a system app.
9799                try {
9800                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9801                        allowed = true;
9802                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9803                                + " is using old GET_TASKS but privileged; allowing");
9804                    }
9805                } catch (RemoteException e) {
9806                }
9807            }
9808        }
9809        if (!allowed) {
9810            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9811                    + " does not hold REAL_GET_TASKS; limiting output");
9812        }
9813        return allowed;
9814    }
9815
9816    @Override
9817    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9818            int userId) {
9819        final int callingUid = Binder.getCallingUid();
9820        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9821                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9822
9823        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9824        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9825        synchronized (this) {
9826            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9827                    callingUid);
9828            final boolean detailed = checkCallingPermission(
9829                    android.Manifest.permission.GET_DETAILED_TASKS)
9830                    == PackageManager.PERMISSION_GRANTED;
9831
9832            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9833                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9834                return ParceledListSlice.emptyList();
9835            }
9836            mRecentTasks.loadUserRecentsLocked(userId);
9837
9838            final int recentsCount = mRecentTasks.size();
9839            ArrayList<ActivityManager.RecentTaskInfo> res =
9840                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9841
9842            final Set<Integer> includedUsers;
9843            if (includeProfiles) {
9844                includedUsers = mUserController.getProfileIds(userId);
9845            } else {
9846                includedUsers = new HashSet<>();
9847            }
9848            includedUsers.add(Integer.valueOf(userId));
9849
9850            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9851                TaskRecord tr = mRecentTasks.get(i);
9852                // Only add calling user or related users recent tasks
9853                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9854                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9855                    continue;
9856                }
9857
9858                if (tr.realActivitySuspended) {
9859                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9860                    continue;
9861                }
9862
9863                // Return the entry if desired by the caller.  We always return
9864                // the first entry, because callers always expect this to be the
9865                // foreground app.  We may filter others if the caller has
9866                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9867                // we should exclude the entry.
9868
9869                if (i == 0
9870                        || withExcluded
9871                        || (tr.intent == null)
9872                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9873                                == 0)) {
9874                    if (!allowed) {
9875                        // If the caller doesn't have the GET_TASKS permission, then only
9876                        // allow them to see a small subset of tasks -- their own and home.
9877                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9878                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9879                            continue;
9880                        }
9881                    }
9882                    final ActivityStack stack = tr.getStack();
9883                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9884                        if (stack != null && stack.isHomeOrRecentsStack()) {
9885                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9886                                    "Skipping, home or recents stack task: " + tr);
9887                            continue;
9888                        }
9889                    }
9890                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9891                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9892                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9893                                    "Skipping, top task in docked stack: " + tr);
9894                            continue;
9895                        }
9896                    }
9897                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9898                        if (stack != null && stack.isPinnedStack()) {
9899                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9900                                    "Skipping, pinned stack task: " + tr);
9901                            continue;
9902                        }
9903                    }
9904                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9905                        // Don't include auto remove tasks that are finished or finishing.
9906                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9907                                "Skipping, auto-remove without activity: " + tr);
9908                        continue;
9909                    }
9910                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9911                            && !tr.isAvailable) {
9912                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9913                                "Skipping, unavail real act: " + tr);
9914                        continue;
9915                    }
9916
9917                    if (!tr.mUserSetupComplete) {
9918                        // Don't include task launched while user is not done setting-up.
9919                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9920                                "Skipping, user setup not complete: " + tr);
9921                        continue;
9922                    }
9923
9924                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9925                    if (!detailed) {
9926                        rti.baseIntent.replaceExtras((Bundle)null);
9927                    }
9928
9929                    res.add(rti);
9930                    maxNum--;
9931                }
9932            }
9933            return new ParceledListSlice<>(res);
9934        }
9935    }
9936
9937    @Override
9938    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9939        synchronized (this) {
9940            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9941                    "getTaskThumbnail()");
9942            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9943                    id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9944            if (tr != null) {
9945                return tr.getTaskThumbnailLocked();
9946            }
9947        }
9948        return null;
9949    }
9950
9951    @Override
9952    public ActivityManager.TaskDescription getTaskDescription(int id) {
9953        synchronized (this) {
9954            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9955                    "getTaskDescription()");
9956            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9957                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9958            if (tr != null) {
9959                return tr.lastTaskDescription;
9960            }
9961        }
9962        return null;
9963    }
9964
9965    @Override
9966    public int addAppTask(IBinder activityToken, Intent intent,
9967            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9968        final int callingUid = Binder.getCallingUid();
9969        final long callingIdent = Binder.clearCallingIdentity();
9970
9971        try {
9972            synchronized (this) {
9973                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9974                if (r == null) {
9975                    throw new IllegalArgumentException("Activity does not exist; token="
9976                            + activityToken);
9977                }
9978                ComponentName comp = intent.getComponent();
9979                if (comp == null) {
9980                    throw new IllegalArgumentException("Intent " + intent
9981                            + " must specify explicit component");
9982                }
9983                if (thumbnail.getWidth() != mThumbnailWidth
9984                        || thumbnail.getHeight() != mThumbnailHeight) {
9985                    throw new IllegalArgumentException("Bad thumbnail size: got "
9986                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9987                            + mThumbnailWidth + "x" + mThumbnailHeight);
9988                }
9989                if (intent.getSelector() != null) {
9990                    intent.setSelector(null);
9991                }
9992                if (intent.getSourceBounds() != null) {
9993                    intent.setSourceBounds(null);
9994                }
9995                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9996                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9997                        // The caller has added this as an auto-remove task...  that makes no
9998                        // sense, so turn off auto-remove.
9999                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10000                    }
10001                }
10002                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10003                    mLastAddedTaskActivity = null;
10004                }
10005                ActivityInfo ainfo = mLastAddedTaskActivity;
10006                if (ainfo == null) {
10007                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10008                            comp, 0, UserHandle.getUserId(callingUid));
10009                    if (ainfo.applicationInfo.uid != callingUid) {
10010                        throw new SecurityException(
10011                                "Can't add task for another application: target uid="
10012                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10013                    }
10014                }
10015
10016                TaskRecord task = new TaskRecord(this,
10017                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10018                        ainfo, intent, description, new TaskThumbnailInfo());
10019
10020                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10021                if (trimIdx >= 0) {
10022                    // If this would have caused a trim, then we'll abort because that
10023                    // means it would be added at the end of the list but then just removed.
10024                    return INVALID_TASK_ID;
10025                }
10026
10027                final int N = mRecentTasks.size();
10028                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10029                    final TaskRecord tr = mRecentTasks.remove(N - 1);
10030                    tr.removedFromRecents();
10031                }
10032
10033                task.inRecents = true;
10034                mRecentTasks.add(task);
10035                r.getStack().addTask(task, false, "addAppTask");
10036
10037                task.setLastThumbnailLocked(thumbnail);
10038                task.freeLastThumbnail();
10039                return task.taskId;
10040            }
10041        } finally {
10042            Binder.restoreCallingIdentity(callingIdent);
10043        }
10044    }
10045
10046    @Override
10047    public Point getAppTaskThumbnailSize() {
10048        synchronized (this) {
10049            return new Point(mThumbnailWidth,  mThumbnailHeight);
10050        }
10051    }
10052
10053    @Override
10054    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10055        synchronized (this) {
10056            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10057            if (r != null) {
10058                r.setTaskDescription(td);
10059                final TaskRecord task = r.getTask();
10060                task.updateTaskDescription();
10061                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10062            }
10063        }
10064    }
10065
10066    @Override
10067    public void setTaskResizeable(int taskId, int resizeableMode) {
10068        synchronized (this) {
10069            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10070                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10071            if (task == null) {
10072                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10073                return;
10074            }
10075            task.setResizeMode(resizeableMode);
10076        }
10077    }
10078
10079    @Override
10080    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10081        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10082        long ident = Binder.clearCallingIdentity();
10083        try {
10084            synchronized (this) {
10085                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10086                if (task == null) {
10087                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10088                    return;
10089                }
10090                // Place the task in the right stack if it isn't there already based on
10091                // the requested bounds.
10092                // The stack transition logic is:
10093                // - a null bounds on a freeform task moves that task to fullscreen
10094                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10095                //   that task to freeform
10096                // - otherwise the task is not moved
10097                int stackId = task.getStackId();
10098                if (!StackId.isTaskResizeAllowed(stackId)) {
10099                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10100                }
10101                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10102                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10103                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10104                    stackId = FREEFORM_WORKSPACE_STACK_ID;
10105                }
10106
10107                // Reparent the task to the right stack if necessary
10108                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10109                if (stackId != task.getStackId()) {
10110                    // Defer resume until the task is resized below
10111                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10112                            DEFER_RESUME, "resizeTask");
10113                    preserveWindow = false;
10114                }
10115
10116                // After reparenting (which only resizes the task to the stack bounds), resize the
10117                // task to the actual bounds provided
10118                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10119            }
10120        } finally {
10121            Binder.restoreCallingIdentity(ident);
10122        }
10123    }
10124
10125    @Override
10126    public Rect getTaskBounds(int taskId) {
10127        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10128        long ident = Binder.clearCallingIdentity();
10129        Rect rect = new Rect();
10130        try {
10131            synchronized (this) {
10132                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10133                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10134                if (task == null) {
10135                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10136                    return rect;
10137                }
10138                if (task.getStack() != null) {
10139                    // Return the bounds from window manager since it will be adjusted for various
10140                    // things like the presense of a docked stack for tasks that aren't resizeable.
10141                    task.getWindowContainerBounds(rect);
10142                } else {
10143                    // Task isn't in window manager yet since it isn't associated with a stack.
10144                    // Return the persist value from activity manager
10145                    if (task.mBounds != null) {
10146                        rect.set(task.mBounds);
10147                    } else if (task.mLastNonFullscreenBounds != null) {
10148                        rect.set(task.mLastNonFullscreenBounds);
10149                    }
10150                }
10151            }
10152        } finally {
10153            Binder.restoreCallingIdentity(ident);
10154        }
10155        return rect;
10156    }
10157
10158    @Override
10159    public void cancelTaskWindowTransition(int taskId) {
10160        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10161        final long ident = Binder.clearCallingIdentity();
10162        try {
10163            synchronized (this) {
10164                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10165                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10166                if (task == null) {
10167                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10168                    return;
10169                }
10170                task.cancelWindowTransition();
10171            }
10172        } finally {
10173            Binder.restoreCallingIdentity(ident);
10174        }
10175    }
10176
10177    @Override
10178    public void cancelTaskThumbnailTransition(int taskId) {
10179        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10180        final long ident = Binder.clearCallingIdentity();
10181        try {
10182            synchronized (this) {
10183                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10184                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10185                if (task == null) {
10186                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10187                    return;
10188                }
10189                task.cancelThumbnailTransition();
10190            }
10191        } finally {
10192            Binder.restoreCallingIdentity(ident);
10193        }
10194    }
10195
10196    @Override
10197    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10198        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10199        final long ident = Binder.clearCallingIdentity();
10200        try {
10201            final TaskRecord task;
10202            synchronized (this) {
10203                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10204                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10205                if (task == null) {
10206                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10207                    return null;
10208                }
10209            }
10210            // Don't call this while holding the lock as this operation might hit the disk.
10211            return task.getSnapshot(reducedResolution);
10212        } finally {
10213            Binder.restoreCallingIdentity(ident);
10214        }
10215    }
10216
10217    @Override
10218    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10219        if (userId != UserHandle.getCallingUserId()) {
10220            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10221                    "getTaskDescriptionIcon");
10222        }
10223        final File passedIconFile = new File(filePath);
10224        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10225                passedIconFile.getName());
10226        if (!legitIconFile.getPath().equals(filePath)
10227                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10228            throw new IllegalArgumentException("Bad file path: " + filePath
10229                    + " passed for userId " + userId);
10230        }
10231        return mRecentTasks.getTaskDescriptionIcon(filePath);
10232    }
10233
10234    @Override
10235    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10236            throws RemoteException {
10237        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10238        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10239                activityOptions.getCustomInPlaceResId() == 0) {
10240            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10241                    "with valid animation");
10242        }
10243        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10244        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10245                activityOptions.getCustomInPlaceResId());
10246        mWindowManager.executeAppTransition();
10247    }
10248
10249    private void removeTasksByPackageNameLocked(String packageName, int userId) {
10250        // Remove all tasks with activities in the specified package from the list of recent tasks
10251        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10252            TaskRecord tr = mRecentTasks.get(i);
10253            if (tr.userId != userId) continue;
10254
10255            ComponentName cn = tr.intent.getComponent();
10256            if (cn != null && cn.getPackageName().equals(packageName)) {
10257                // If the package name matches, remove the task.
10258                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10259            }
10260        }
10261    }
10262
10263    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10264            int userId) {
10265
10266        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10267            TaskRecord tr = mRecentTasks.get(i);
10268            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10269                continue;
10270            }
10271
10272            ComponentName cn = tr.intent.getComponent();
10273            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10274                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10275            if (sameComponent) {
10276                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10277            }
10278        }
10279    }
10280
10281    @Override
10282    public void removeStack(int stackId) {
10283        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10284        if (StackId.isHomeOrRecentsStack(stackId)) {
10285            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10286        }
10287
10288        synchronized (this) {
10289            final long ident = Binder.clearCallingIdentity();
10290            try {
10291                mStackSupervisor.removeStackLocked(stackId);
10292            } finally {
10293                Binder.restoreCallingIdentity(ident);
10294            }
10295        }
10296    }
10297
10298    @Override
10299    public void moveStackToDisplay(int stackId, int displayId) {
10300        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
10301
10302        synchronized (this) {
10303            final long ident = Binder.clearCallingIdentity();
10304            try {
10305                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10306                        + " to displayId=" + displayId);
10307                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10308            } finally {
10309                Binder.restoreCallingIdentity(ident);
10310            }
10311        }
10312    }
10313
10314    @Override
10315    public boolean removeTask(int taskId) {
10316        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10317        synchronized (this) {
10318            final long ident = Binder.clearCallingIdentity();
10319            try {
10320                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10321            } finally {
10322                Binder.restoreCallingIdentity(ident);
10323            }
10324        }
10325    }
10326
10327    /**
10328     * TODO: Add mController hook
10329     */
10330    @Override
10331    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10332        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10333
10334        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10335        synchronized(this) {
10336            moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10337        }
10338    }
10339
10340    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10341        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10342
10343        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10344                Binder.getCallingUid(), -1, -1, "Task to front")) {
10345            ActivityOptions.abort(options);
10346            return;
10347        }
10348        final long origId = Binder.clearCallingIdentity();
10349        try {
10350            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10351            if (task == null) {
10352                Slog.d(TAG, "Could not find task for id: "+ taskId);
10353                return;
10354            }
10355            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10356                mStackSupervisor.showLockTaskToast();
10357                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10358                return;
10359            }
10360            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10361            if (prev != null) {
10362                task.setTaskToReturnTo(prev);
10363            }
10364            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10365                    false /* forceNonResizable */);
10366
10367            final ActivityRecord topActivity = task.getTopActivity();
10368            if (topActivity != null) {
10369
10370                // We are reshowing a task, use a starting window to hide the initial draw delay
10371                // so the transition can start earlier.
10372                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10373                        true /* taskSwitch */, fromRecents);
10374            }
10375        } finally {
10376            Binder.restoreCallingIdentity(origId);
10377        }
10378        ActivityOptions.abort(options);
10379    }
10380
10381    /**
10382     * Attempts to move a task backwards in z-order (the order of activities within the task is
10383     * unchanged).
10384     *
10385     * There are several possible results of this call:
10386     * - if the task is locked, then we will show the lock toast
10387     * - if there is a task behind the provided task, then that task is made visible and resumed as
10388     *   this task is moved to the back
10389     * - otherwise, if there are no other tasks in the stack:
10390     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10391     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10392     *       (depending on whether it is visible)
10393     *     - otherwise, we simply return home and hide this task
10394     *
10395     * @param token A reference to the activity we wish to move
10396     * @param nonRoot If false then this only works if the activity is the root
10397     *                of a task; if true it will work for any activity in a task.
10398     * @return Returns true if the move completed, false if not.
10399     */
10400    @Override
10401    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10402        enforceNotIsolatedCaller("moveActivityTaskToBack");
10403        synchronized(this) {
10404            final long origId = Binder.clearCallingIdentity();
10405            try {
10406                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10407                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10408                if (task != null) {
10409                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10410                }
10411            } finally {
10412                Binder.restoreCallingIdentity(origId);
10413            }
10414        }
10415        return false;
10416    }
10417
10418    @Override
10419    public void moveTaskBackwards(int task) {
10420        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10421                "moveTaskBackwards()");
10422
10423        synchronized(this) {
10424            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10425                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10426                return;
10427            }
10428            final long origId = Binder.clearCallingIdentity();
10429            moveTaskBackwardsLocked(task);
10430            Binder.restoreCallingIdentity(origId);
10431        }
10432    }
10433
10434    private final void moveTaskBackwardsLocked(int task) {
10435        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10436    }
10437
10438    @Override
10439    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10440            IActivityContainerCallback callback) throws RemoteException {
10441        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10442        synchronized (this) {
10443            if (parentActivityToken == null) {
10444                throw new IllegalArgumentException("parent token must not be null");
10445            }
10446            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10447            if (r == null) {
10448                return null;
10449            }
10450            if (callback == null) {
10451                throw new IllegalArgumentException("callback must not be null");
10452            }
10453            return mStackSupervisor.createVirtualActivityContainer(r, callback);
10454        }
10455    }
10456
10457    @Override
10458    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10459        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10460        synchronized (this) {
10461            final int stackId = mStackSupervisor.getNextStackId();
10462            final ActivityStack stack =
10463                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10464            if (stack == null) {
10465                return null;
10466            }
10467            return stack.mActivityContainer;
10468        }
10469    }
10470
10471    @Override
10472    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10473        synchronized (this) {
10474            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10475            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10476                return stack.mActivityContainer.getDisplayId();
10477            }
10478            return DEFAULT_DISPLAY;
10479        }
10480    }
10481
10482    @Override
10483    public int getActivityStackId(IBinder token) throws RemoteException {
10484        synchronized (this) {
10485            ActivityStack stack = ActivityRecord.getStackLocked(token);
10486            if (stack == null) {
10487                return INVALID_STACK_ID;
10488            }
10489            return stack.mStackId;
10490        }
10491    }
10492
10493    @Override
10494    public void exitFreeformMode(IBinder token) throws RemoteException {
10495        synchronized (this) {
10496            long ident = Binder.clearCallingIdentity();
10497            try {
10498                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10499                if (r == null) {
10500                    throw new IllegalArgumentException(
10501                            "exitFreeformMode: No activity record matching token=" + token);
10502                }
10503
10504                final ActivityStack stack = r.getStack();
10505                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10506                    throw new IllegalStateException(
10507                            "exitFreeformMode: You can only go fullscreen from freeform.");
10508                }
10509
10510                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10511                r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10512                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10513            } finally {
10514                Binder.restoreCallingIdentity(ident);
10515            }
10516        }
10517    }
10518
10519    @Override
10520    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10521        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10522        if (StackId.isHomeOrRecentsStack(stackId)) {
10523            throw new IllegalArgumentException(
10524                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10525        }
10526        synchronized (this) {
10527            long ident = Binder.clearCallingIdentity();
10528            try {
10529                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10530                if (task == null) {
10531                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10532                    return;
10533                }
10534
10535                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10536                        + " to stackId=" + stackId + " toTop=" + toTop);
10537                if (stackId == DOCKED_STACK_ID) {
10538                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10539                            null /* initialBounds */);
10540                }
10541                task.reparent(stackId, toTop,
10542                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10543            } finally {
10544                Binder.restoreCallingIdentity(ident);
10545            }
10546        }
10547    }
10548
10549    @Override
10550    public void swapDockedAndFullscreenStack() throws RemoteException {
10551        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10552        synchronized (this) {
10553            long ident = Binder.clearCallingIdentity();
10554            try {
10555                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10556                        FULLSCREEN_WORKSPACE_STACK_ID);
10557                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10558                        : null;
10559                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10560                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10561                        : null;
10562                if (topTask == null || tasks == null || tasks.size() == 0) {
10563                    Slog.w(TAG,
10564                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10565                    return;
10566                }
10567
10568                // TODO: App transition
10569                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10570
10571                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10572                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10573                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10574                final int size = tasks.size();
10575                for (int i = 0; i < size; i++) {
10576                    final int id = tasks.get(i).taskId;
10577                    if (id == topTask.taskId) {
10578                        continue;
10579                    }
10580
10581                    // Defer the resume until after all the tasks have been moved
10582                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10583                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10584                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10585                }
10586
10587                // Because we deferred the resume to avoid conflicts with stack switches while
10588                // resuming, we need to do it after all the tasks are moved.
10589                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10590                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10591
10592                mWindowManager.executeAppTransition();
10593            } finally {
10594                Binder.restoreCallingIdentity(ident);
10595            }
10596        }
10597    }
10598
10599    /**
10600     * Moves the input task to the docked stack.
10601     *
10602     * @param taskId Id of task to move.
10603     * @param createMode The mode the docked stack should be created in if it doesn't exist
10604     *                   already. See
10605     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10606     *                   and
10607     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10608     * @param toTop If the task and stack should be moved to the top.
10609     * @param animate Whether we should play an animation for the moving the task
10610     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10611     *                      docked stack. Pass {@code null} to use default bounds.
10612     */
10613    @Override
10614    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10615            Rect initialBounds) {
10616        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10617        synchronized (this) {
10618            long ident = Binder.clearCallingIdentity();
10619            try {
10620                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10621                if (task == null) {
10622                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10623                    return false;
10624                }
10625
10626                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10627                        + " to createMode=" + createMode + " toTop=" + toTop);
10628                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10629
10630                // Defer resuming until we move the home stack to the front below
10631                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10632                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10633                        "moveTaskToDockedStack");
10634                if (moved) {
10635                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10636                }
10637                return moved;
10638            } finally {
10639                Binder.restoreCallingIdentity(ident);
10640            }
10641        }
10642    }
10643
10644    /**
10645     * Moves the top activity in the input stackId to the pinned stack.
10646     *
10647     * @param stackId Id of stack to move the top activity to pinned stack.
10648     * @param bounds Bounds to use for pinned stack.
10649     *
10650     * @return True if the top activity of the input stack was successfully moved to the pinned
10651     *          stack.
10652     */
10653    @Override
10654    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10655        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10656        synchronized (this) {
10657            if (!mSupportsPictureInPicture) {
10658                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10659                        + "Device doesn't support picture-in-picture mode");
10660            }
10661
10662            long ident = Binder.clearCallingIdentity();
10663            try {
10664                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10665            } finally {
10666                Binder.restoreCallingIdentity(ident);
10667            }
10668        }
10669    }
10670
10671    @Override
10672    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10673            boolean preserveWindows, boolean animate, int animationDuration) {
10674        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10675        long ident = Binder.clearCallingIdentity();
10676        try {
10677            synchronized (this) {
10678                if (animate) {
10679                    if (stackId == PINNED_STACK_ID) {
10680                        final PinnedActivityStack pinnedStack =
10681                                mStackSupervisor.getStack(PINNED_STACK_ID);
10682                        if (pinnedStack != null) {
10683                            pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10684                                    destBounds, animationDuration, false /* fromFullscreen */);
10685                        }
10686                    } else {
10687                        throw new IllegalArgumentException("Stack: " + stackId
10688                                + " doesn't support animated resize.");
10689                    }
10690                } else {
10691                    mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10692                            null /* tempTaskInsetBounds */, preserveWindows,
10693                            allowResizeInDockedMode, !DEFER_RESUME);
10694                }
10695            }
10696        } finally {
10697            Binder.restoreCallingIdentity(ident);
10698        }
10699    }
10700
10701    @Override
10702    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10703            Rect tempDockedTaskInsetBounds,
10704            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10705        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10706                "resizeDockedStack()");
10707        long ident = Binder.clearCallingIdentity();
10708        try {
10709            synchronized (this) {
10710                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10711                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10712                        PRESERVE_WINDOWS);
10713            }
10714        } finally {
10715            Binder.restoreCallingIdentity(ident);
10716        }
10717    }
10718
10719    @Override
10720    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10721        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10722                "resizePinnedStack()");
10723        final long ident = Binder.clearCallingIdentity();
10724        try {
10725            synchronized (this) {
10726                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10727            }
10728        } finally {
10729            Binder.restoreCallingIdentity(ident);
10730        }
10731    }
10732
10733    /**
10734     * Try to place task to provided position. The final position might be different depending on
10735     * current user and stacks state. The task will be moved to target stack if it's currently in
10736     * different stack.
10737     */
10738    @Override
10739    public void positionTaskInStack(int taskId, int stackId, int position) {
10740        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10741        if (StackId.isHomeOrRecentsStack(stackId)) {
10742            throw new IllegalArgumentException(
10743                    "positionTaskInStack: Attempt to change the position of task "
10744                    + taskId + " in/to home/recents stack");
10745        }
10746        synchronized (this) {
10747            long ident = Binder.clearCallingIdentity();
10748            try {
10749                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10750                        + taskId + " in stackId=" + stackId + " at position=" + position);
10751                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10752                if (task == null) {
10753                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10754                            + taskId);
10755                }
10756
10757                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10758                        !ON_TOP);
10759
10760                // TODO: Have the callers of this API call a separate reparent method if that is
10761                // what they intended to do vs. having this method also do reparenting.
10762                if (task.getStack() == stack) {
10763                    // Change position in current stack.
10764                    stack.positionChildAt(task, position);
10765                } else {
10766                    // Reparent to new stack.
10767                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10768                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10769                }
10770            } finally {
10771                Binder.restoreCallingIdentity(ident);
10772            }
10773        }
10774    }
10775
10776    @Override
10777    public List<StackInfo> getAllStackInfos() {
10778        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10779        long ident = Binder.clearCallingIdentity();
10780        try {
10781            synchronized (this) {
10782                return mStackSupervisor.getAllStackInfosLocked();
10783            }
10784        } finally {
10785            Binder.restoreCallingIdentity(ident);
10786        }
10787    }
10788
10789    @Override
10790    public StackInfo getStackInfo(int stackId) {
10791        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10792        long ident = Binder.clearCallingIdentity();
10793        try {
10794            synchronized (this) {
10795                return mStackSupervisor.getStackInfoLocked(stackId);
10796            }
10797        } finally {
10798            Binder.restoreCallingIdentity(ident);
10799        }
10800    }
10801
10802    @Override
10803    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10804        synchronized(this) {
10805            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10806        }
10807    }
10808
10809    @Override
10810    public void updateDeviceOwner(String packageName) {
10811        final int callingUid = Binder.getCallingUid();
10812        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10813            throw new SecurityException("updateDeviceOwner called from non-system process");
10814        }
10815        synchronized (this) {
10816            mDeviceOwnerName = packageName;
10817        }
10818    }
10819
10820    @Override
10821    public void updateLockTaskPackages(int userId, String[] packages) {
10822        final int callingUid = Binder.getCallingUid();
10823        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10824            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10825                    "updateLockTaskPackages()");
10826        }
10827        synchronized (this) {
10828            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10829                    Arrays.toString(packages));
10830            mLockTaskPackages.put(userId, packages);
10831            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10832        }
10833    }
10834
10835
10836    void startLockTaskModeLocked(TaskRecord task) {
10837        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10838        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10839            return;
10840        }
10841
10842        // When a task is locked, dismiss the pinned stack if it exists
10843        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10844                PINNED_STACK_ID);
10845        if (pinnedStack != null) {
10846            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10847        }
10848
10849        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10850        // is initiated by system after the pinning request was shown and locked mode is initiated
10851        // by an authorized app directly
10852        final int callingUid = Binder.getCallingUid();
10853        boolean isSystemInitiated = callingUid == SYSTEM_UID;
10854        long ident = Binder.clearCallingIdentity();
10855        try {
10856            if (!isSystemInitiated) {
10857                task.mLockTaskUid = callingUid;
10858                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10859                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10860                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10861                    StatusBarManagerInternal statusBarManager =
10862                            LocalServices.getService(StatusBarManagerInternal.class);
10863                    if (statusBarManager != null) {
10864                        statusBarManager.showScreenPinningRequest(task.taskId);
10865                    }
10866                    return;
10867                }
10868
10869                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10870                if (stack == null || task != stack.topTask()) {
10871                    throw new IllegalArgumentException("Invalid task, not in foreground");
10872                }
10873            }
10874            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10875                    "Locking fully");
10876            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10877                    ActivityManager.LOCK_TASK_MODE_PINNED :
10878                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10879                    "startLockTask", true);
10880        } finally {
10881            Binder.restoreCallingIdentity(ident);
10882        }
10883    }
10884
10885    @Override
10886    public void startLockTaskModeById(int taskId) {
10887        synchronized (this) {
10888            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10889            if (task != null) {
10890                startLockTaskModeLocked(task);
10891            }
10892        }
10893    }
10894
10895    @Override
10896    public void startLockTaskModeByToken(IBinder token) {
10897        synchronized (this) {
10898            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10899            if (r == null) {
10900                return;
10901            }
10902            final TaskRecord task = r.getTask();
10903            if (task != null) {
10904                startLockTaskModeLocked(task);
10905            }
10906        }
10907    }
10908
10909    @Override
10910    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10911        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10912        // This makes inner call to look as if it was initiated by system.
10913        long ident = Binder.clearCallingIdentity();
10914        try {
10915            synchronized (this) {
10916                startLockTaskModeById(taskId);
10917            }
10918        } finally {
10919            Binder.restoreCallingIdentity(ident);
10920        }
10921    }
10922
10923    @Override
10924    public void stopLockTaskMode() {
10925        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10926        if (lockTask == null) {
10927            // Our work here is done.
10928            return;
10929        }
10930
10931        final int callingUid = Binder.getCallingUid();
10932        final int lockTaskUid = lockTask.mLockTaskUid;
10933        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10934        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10935            // Done.
10936            return;
10937        } else {
10938            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10939            // It is possible lockTaskMode was started by the system process because
10940            // android:lockTaskMode is set to a locking value in the application manifest
10941            // instead of the app calling startLockTaskMode. In this case
10942            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10943            // {@link TaskRecord.effectiveUid} instead. Also caller with
10944            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10945            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10946                    && callingUid != lockTaskUid
10947                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10948                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10949                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10950            }
10951        }
10952        long ident = Binder.clearCallingIdentity();
10953        try {
10954            Log.d(TAG, "stopLockTaskMode");
10955            // Stop lock task
10956            synchronized (this) {
10957                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10958                        "stopLockTask", true);
10959            }
10960            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10961            if (tm != null) {
10962                tm.showInCallScreen(false);
10963            }
10964        } finally {
10965            Binder.restoreCallingIdentity(ident);
10966        }
10967    }
10968
10969    /**
10970     * This API should be called by SystemUI only when user perform certain action to dismiss
10971     * lock task mode. We should only dismiss pinned lock task mode in this case.
10972     */
10973    @Override
10974    public void stopSystemLockTaskMode() throws RemoteException {
10975        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10976            stopLockTaskMode();
10977        } else {
10978            mStackSupervisor.showLockTaskToast();
10979        }
10980    }
10981
10982    @Override
10983    public boolean isInLockTaskMode() {
10984        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10985    }
10986
10987    @Override
10988    public int getLockTaskModeState() {
10989        synchronized (this) {
10990            return mStackSupervisor.getLockTaskModeState();
10991        }
10992    }
10993
10994    @Override
10995    public void showLockTaskEscapeMessage(IBinder token) {
10996        synchronized (this) {
10997            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10998            if (r == null) {
10999                return;
11000            }
11001            mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11002        }
11003    }
11004
11005    @Override
11006    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11007            throws RemoteException {
11008        synchronized (this) {
11009            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11010            if (r == null) {
11011                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11012                        + token);
11013                return;
11014            }
11015            final long origId = Binder.clearCallingIdentity();
11016            try {
11017                r.setDisablePreviewScreenshots(disable);
11018            } finally {
11019                Binder.restoreCallingIdentity(origId);
11020            }
11021        }
11022    }
11023
11024    // =========================================================
11025    // CONTENT PROVIDERS
11026    // =========================================================
11027
11028    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11029        List<ProviderInfo> providers = null;
11030        try {
11031            providers = AppGlobals.getPackageManager()
11032                    .queryContentProviders(app.processName, app.uid,
11033                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11034                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11035                    .getList();
11036        } catch (RemoteException ex) {
11037        }
11038        if (DEBUG_MU) Slog.v(TAG_MU,
11039                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11040        int userId = app.userId;
11041        if (providers != null) {
11042            int N = providers.size();
11043            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11044            for (int i=0; i<N; i++) {
11045                // TODO: keep logic in sync with installEncryptionUnawareProviders
11046                ProviderInfo cpi =
11047                    (ProviderInfo)providers.get(i);
11048                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11049                        cpi.name, cpi.flags);
11050                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11051                    // This is a singleton provider, but a user besides the
11052                    // default user is asking to initialize a process it runs
11053                    // in...  well, no, it doesn't actually run in this process,
11054                    // it runs in the process of the default user.  Get rid of it.
11055                    providers.remove(i);
11056                    N--;
11057                    i--;
11058                    continue;
11059                }
11060
11061                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11062                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11063                if (cpr == null) {
11064                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11065                    mProviderMap.putProviderByClass(comp, cpr);
11066                }
11067                if (DEBUG_MU) Slog.v(TAG_MU,
11068                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11069                app.pubProviders.put(cpi.name, cpr);
11070                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11071                    // Don't add this if it is a platform component that is marked
11072                    // to run in multiple processes, because this is actually
11073                    // part of the framework so doesn't make sense to track as a
11074                    // separate apk in the process.
11075                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11076                            mProcessStats);
11077                }
11078                notifyPackageUse(cpi.applicationInfo.packageName,
11079                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11080            }
11081        }
11082        return providers;
11083    }
11084
11085    /**
11086     * Check if the calling UID has a possible chance at accessing the provider
11087     * at the given authority and user.
11088     */
11089    public String checkContentProviderAccess(String authority, int userId) {
11090        if (userId == UserHandle.USER_ALL) {
11091            mContext.enforceCallingOrSelfPermission(
11092                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11093            userId = UserHandle.getCallingUserId();
11094        }
11095
11096        ProviderInfo cpi = null;
11097        try {
11098            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11099                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11100                            | PackageManager.MATCH_DISABLED_COMPONENTS
11101                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11102                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11103                    userId);
11104        } catch (RemoteException ignored) {
11105        }
11106        if (cpi == null) {
11107            return "Failed to find provider " + authority + " for user " + userId
11108                    + "; expected to find a valid ContentProvider for this authority";
11109        }
11110
11111        ProcessRecord r = null;
11112        synchronized (mPidsSelfLocked) {
11113            r = mPidsSelfLocked.get(Binder.getCallingPid());
11114        }
11115        if (r == null) {
11116            return "Failed to find PID " + Binder.getCallingPid();
11117        }
11118
11119        synchronized (this) {
11120            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11121        }
11122    }
11123
11124    /**
11125     * Check if {@link ProcessRecord} has a possible chance at accessing the
11126     * given {@link ProviderInfo}. Final permission checking is always done
11127     * in {@link ContentProvider}.
11128     */
11129    private final String checkContentProviderPermissionLocked(
11130            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11131        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11132        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11133        boolean checkedGrants = false;
11134        if (checkUser) {
11135            // Looking for cross-user grants before enforcing the typical cross-users permissions
11136            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11137            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11138                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11139                    return null;
11140                }
11141                checkedGrants = true;
11142            }
11143            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11144                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11145            if (userId != tmpTargetUserId) {
11146                // When we actually went to determine the final targer user ID, this ended
11147                // up different than our initial check for the authority.  This is because
11148                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11149                // SELF.  So we need to re-check the grants again.
11150                checkedGrants = false;
11151            }
11152        }
11153        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11154                cpi.applicationInfo.uid, cpi.exported)
11155                == PackageManager.PERMISSION_GRANTED) {
11156            return null;
11157        }
11158        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11159                cpi.applicationInfo.uid, cpi.exported)
11160                == PackageManager.PERMISSION_GRANTED) {
11161            return null;
11162        }
11163
11164        PathPermission[] pps = cpi.pathPermissions;
11165        if (pps != null) {
11166            int i = pps.length;
11167            while (i > 0) {
11168                i--;
11169                PathPermission pp = pps[i];
11170                String pprperm = pp.getReadPermission();
11171                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11172                        cpi.applicationInfo.uid, cpi.exported)
11173                        == PackageManager.PERMISSION_GRANTED) {
11174                    return null;
11175                }
11176                String ppwperm = pp.getWritePermission();
11177                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11178                        cpi.applicationInfo.uid, cpi.exported)
11179                        == PackageManager.PERMISSION_GRANTED) {
11180                    return null;
11181                }
11182            }
11183        }
11184        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11185            return null;
11186        }
11187
11188        final String suffix;
11189        if (!cpi.exported) {
11190            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11191        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11192            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11193        } else {
11194            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11195        }
11196        final String msg = "Permission Denial: opening provider " + cpi.name
11197                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11198                + ", uid=" + callingUid + ")" + suffix;
11199        Slog.w(TAG, msg);
11200        return msg;
11201    }
11202
11203    /**
11204     * Returns if the ContentProvider has granted a uri to callingUid
11205     */
11206    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11207        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11208        if (perms != null) {
11209            for (int i=perms.size()-1; i>=0; i--) {
11210                GrantUri grantUri = perms.keyAt(i);
11211                if (grantUri.sourceUserId == userId || !checkUser) {
11212                    if (matchesProvider(grantUri.uri, cpi)) {
11213                        return true;
11214                    }
11215                }
11216            }
11217        }
11218        return false;
11219    }
11220
11221    /**
11222     * Returns true if the uri authority is one of the authorities specified in the provider.
11223     */
11224    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11225        String uriAuth = uri.getAuthority();
11226        String cpiAuth = cpi.authority;
11227        if (cpiAuth.indexOf(';') == -1) {
11228            return cpiAuth.equals(uriAuth);
11229        }
11230        String[] cpiAuths = cpiAuth.split(";");
11231        int length = cpiAuths.length;
11232        for (int i = 0; i < length; i++) {
11233            if (cpiAuths[i].equals(uriAuth)) return true;
11234        }
11235        return false;
11236    }
11237
11238    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11239            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11240        if (r != null) {
11241            for (int i=0; i<r.conProviders.size(); i++) {
11242                ContentProviderConnection conn = r.conProviders.get(i);
11243                if (conn.provider == cpr) {
11244                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11245                            "Adding provider requested by "
11246                            + r.processName + " from process "
11247                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11248                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11249                    if (stable) {
11250                        conn.stableCount++;
11251                        conn.numStableIncs++;
11252                    } else {
11253                        conn.unstableCount++;
11254                        conn.numUnstableIncs++;
11255                    }
11256                    return conn;
11257                }
11258            }
11259            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11260            if (stable) {
11261                conn.stableCount = 1;
11262                conn.numStableIncs = 1;
11263            } else {
11264                conn.unstableCount = 1;
11265                conn.numUnstableIncs = 1;
11266            }
11267            cpr.connections.add(conn);
11268            r.conProviders.add(conn);
11269            startAssociationLocked(r.uid, r.processName, r.curProcState,
11270                    cpr.uid, cpr.name, cpr.info.processName);
11271            return conn;
11272        }
11273        cpr.addExternalProcessHandleLocked(externalProcessToken);
11274        return null;
11275    }
11276
11277    boolean decProviderCountLocked(ContentProviderConnection conn,
11278            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11279        if (conn != null) {
11280            cpr = conn.provider;
11281            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11282                    "Removing provider requested by "
11283                    + conn.client.processName + " from process "
11284                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11285                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11286            if (stable) {
11287                conn.stableCount--;
11288            } else {
11289                conn.unstableCount--;
11290            }
11291            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11292                cpr.connections.remove(conn);
11293                conn.client.conProviders.remove(conn);
11294                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11295                    // The client is more important than last activity -- note the time this
11296                    // is happening, so we keep the old provider process around a bit as last
11297                    // activity to avoid thrashing it.
11298                    if (cpr.proc != null) {
11299                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11300                    }
11301                }
11302                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11303                return true;
11304            }
11305            return false;
11306        }
11307        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11308        return false;
11309    }
11310
11311    private void checkTime(long startTime, String where) {
11312        long now = SystemClock.uptimeMillis();
11313        if ((now-startTime) > 50) {
11314            // If we are taking more than 50ms, log about it.
11315            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11316        }
11317    }
11318
11319    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11320            PROC_SPACE_TERM,
11321            PROC_SPACE_TERM|PROC_PARENS,
11322            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11323    };
11324
11325    private final long[] mProcessStateStatsLongs = new long[1];
11326
11327    boolean isProcessAliveLocked(ProcessRecord proc) {
11328        if (proc.procStatFile == null) {
11329            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11330        }
11331        mProcessStateStatsLongs[0] = 0;
11332        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11333                mProcessStateStatsLongs, null)) {
11334            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11335            return false;
11336        }
11337        final long state = mProcessStateStatsLongs[0];
11338        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11339                + (char)state);
11340        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11341    }
11342
11343    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11344            String name, IBinder token, boolean stable, int userId) {
11345        ContentProviderRecord cpr;
11346        ContentProviderConnection conn = null;
11347        ProviderInfo cpi = null;
11348
11349        synchronized(this) {
11350            long startTime = SystemClock.uptimeMillis();
11351
11352            ProcessRecord r = null;
11353            if (caller != null) {
11354                r = getRecordForAppLocked(caller);
11355                if (r == null) {
11356                    throw new SecurityException(
11357                            "Unable to find app for caller " + caller
11358                          + " (pid=" + Binder.getCallingPid()
11359                          + ") when getting content provider " + name);
11360                }
11361            }
11362
11363            boolean checkCrossUser = true;
11364
11365            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11366
11367            // First check if this content provider has been published...
11368            cpr = mProviderMap.getProviderByName(name, userId);
11369            // If that didn't work, check if it exists for user 0 and then
11370            // verify that it's a singleton provider before using it.
11371            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11372                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11373                if (cpr != null) {
11374                    cpi = cpr.info;
11375                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11376                            cpi.name, cpi.flags)
11377                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11378                        userId = UserHandle.USER_SYSTEM;
11379                        checkCrossUser = false;
11380                    } else {
11381                        cpr = null;
11382                        cpi = null;
11383                    }
11384                }
11385            }
11386
11387            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11388            if (providerRunning) {
11389                cpi = cpr.info;
11390                String msg;
11391                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11392                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11393                        != null) {
11394                    throw new SecurityException(msg);
11395                }
11396                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11397
11398                if (r != null && cpr.canRunHere(r)) {
11399                    // This provider has been published or is in the process
11400                    // of being published...  but it is also allowed to run
11401                    // in the caller's process, so don't make a connection
11402                    // and just let the caller instantiate its own instance.
11403                    ContentProviderHolder holder = cpr.newHolder(null);
11404                    // don't give caller the provider object, it needs
11405                    // to make its own.
11406                    holder.provider = null;
11407                    return holder;
11408                }
11409                // Don't expose providers between normal apps and instant apps
11410                try {
11411                    if (AppGlobals.getPackageManager()
11412                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11413                        return null;
11414                    }
11415                } catch (RemoteException e) {
11416                }
11417
11418                final long origId = Binder.clearCallingIdentity();
11419
11420                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11421
11422                // In this case the provider instance already exists, so we can
11423                // return it right away.
11424                conn = incProviderCountLocked(r, cpr, token, stable);
11425                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11426                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11427                        // If this is a perceptible app accessing the provider,
11428                        // make sure to count it as being accessed and thus
11429                        // back up on the LRU list.  This is good because
11430                        // content providers are often expensive to start.
11431                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11432                        updateLruProcessLocked(cpr.proc, false, null);
11433                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11434                    }
11435                }
11436
11437                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11438                final int verifiedAdj = cpr.proc.verifiedAdj;
11439                boolean success = updateOomAdjLocked(cpr.proc, true);
11440                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11441                // if the process has been successfully adjusted.  So to reduce races with
11442                // it, we will check whether the process still exists.  Note that this doesn't
11443                // completely get rid of races with LMK killing the process, but should make
11444                // them much smaller.
11445                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11446                    success = false;
11447                }
11448                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11449                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11450                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11451                // NOTE: there is still a race here where a signal could be
11452                // pending on the process even though we managed to update its
11453                // adj level.  Not sure what to do about this, but at least
11454                // the race is now smaller.
11455                if (!success) {
11456                    // Uh oh...  it looks like the provider's process
11457                    // has been killed on us.  We need to wait for a new
11458                    // process to be started, and make sure its death
11459                    // doesn't kill our process.
11460                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11461                            + " is crashing; detaching " + r);
11462                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11463                    checkTime(startTime, "getContentProviderImpl: before appDied");
11464                    appDiedLocked(cpr.proc);
11465                    checkTime(startTime, "getContentProviderImpl: after appDied");
11466                    if (!lastRef) {
11467                        // This wasn't the last ref our process had on
11468                        // the provider...  we have now been killed, bail.
11469                        return null;
11470                    }
11471                    providerRunning = false;
11472                    conn = null;
11473                } else {
11474                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11475                }
11476
11477                Binder.restoreCallingIdentity(origId);
11478            }
11479
11480            if (!providerRunning) {
11481                try {
11482                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11483                    cpi = AppGlobals.getPackageManager().
11484                        resolveContentProvider(name,
11485                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11486                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11487                } catch (RemoteException ex) {
11488                }
11489                if (cpi == null) {
11490                    return null;
11491                }
11492                // If the provider is a singleton AND
11493                // (it's a call within the same user || the provider is a
11494                // privileged app)
11495                // Then allow connecting to the singleton provider
11496                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11497                        cpi.name, cpi.flags)
11498                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11499                if (singleton) {
11500                    userId = UserHandle.USER_SYSTEM;
11501                }
11502                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11503                checkTime(startTime, "getContentProviderImpl: got app info for user");
11504
11505                String msg;
11506                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11507                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11508                        != null) {
11509                    throw new SecurityException(msg);
11510                }
11511                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11512
11513                if (!mProcessesReady
11514                        && !cpi.processName.equals("system")) {
11515                    // If this content provider does not run in the system
11516                    // process, and the system is not yet ready to run other
11517                    // processes, then fail fast instead of hanging.
11518                    throw new IllegalArgumentException(
11519                            "Attempt to launch content provider before system ready");
11520                }
11521
11522                // Make sure that the user who owns this provider is running.  If not,
11523                // we don't want to allow it to run.
11524                if (!mUserController.isUserRunningLocked(userId, 0)) {
11525                    Slog.w(TAG, "Unable to launch app "
11526                            + cpi.applicationInfo.packageName + "/"
11527                            + cpi.applicationInfo.uid + " for provider "
11528                            + name + ": user " + userId + " is stopped");
11529                    return null;
11530                }
11531
11532                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11533                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11534                cpr = mProviderMap.getProviderByClass(comp, userId);
11535                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11536                final boolean firstClass = cpr == null;
11537                if (firstClass) {
11538                    final long ident = Binder.clearCallingIdentity();
11539
11540                    // If permissions need a review before any of the app components can run,
11541                    // we return no provider and launch a review activity if the calling app
11542                    // is in the foreground.
11543                    if (mPermissionReviewRequired) {
11544                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11545                            return null;
11546                        }
11547                    }
11548
11549                    try {
11550                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11551                        ApplicationInfo ai =
11552                            AppGlobals.getPackageManager().
11553                                getApplicationInfo(
11554                                        cpi.applicationInfo.packageName,
11555                                        STOCK_PM_FLAGS, userId);
11556                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11557                        if (ai == null) {
11558                            Slog.w(TAG, "No package info for content provider "
11559                                    + cpi.name);
11560                            return null;
11561                        }
11562                        ai = getAppInfoForUser(ai, userId);
11563                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11564                    } catch (RemoteException ex) {
11565                        // pm is in same process, this will never happen.
11566                    } finally {
11567                        Binder.restoreCallingIdentity(ident);
11568                    }
11569                }
11570
11571                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11572
11573                if (r != null && cpr.canRunHere(r)) {
11574                    // If this is a multiprocess provider, then just return its
11575                    // info and allow the caller to instantiate it.  Only do
11576                    // this if the provider is the same user as the caller's
11577                    // process, or can run as root (so can be in any process).
11578                    return cpr.newHolder(null);
11579                }
11580
11581                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11582                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11583                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11584
11585                // This is single process, and our app is now connecting to it.
11586                // See if we are already in the process of launching this
11587                // provider.
11588                final int N = mLaunchingProviders.size();
11589                int i;
11590                for (i = 0; i < N; i++) {
11591                    if (mLaunchingProviders.get(i) == cpr) {
11592                        break;
11593                    }
11594                }
11595
11596                // If the provider is not already being launched, then get it
11597                // started.
11598                if (i >= N) {
11599                    final long origId = Binder.clearCallingIdentity();
11600
11601                    try {
11602                        // Content provider is now in use, its package can't be stopped.
11603                        try {
11604                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11605                            AppGlobals.getPackageManager().setPackageStoppedState(
11606                                    cpr.appInfo.packageName, false, userId);
11607                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11608                        } catch (RemoteException e) {
11609                        } catch (IllegalArgumentException e) {
11610                            Slog.w(TAG, "Failed trying to unstop package "
11611                                    + cpr.appInfo.packageName + ": " + e);
11612                        }
11613
11614                        // Use existing process if already started
11615                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11616                        ProcessRecord proc = getProcessRecordLocked(
11617                                cpi.processName, cpr.appInfo.uid, false);
11618                        if (proc != null && proc.thread != null && !proc.killed) {
11619                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11620                                    "Installing in existing process " + proc);
11621                            if (!proc.pubProviders.containsKey(cpi.name)) {
11622                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11623                                proc.pubProviders.put(cpi.name, cpr);
11624                                try {
11625                                    proc.thread.scheduleInstallProvider(cpi);
11626                                } catch (RemoteException e) {
11627                                }
11628                            }
11629                        } else {
11630                            checkTime(startTime, "getContentProviderImpl: before start process");
11631                            proc = startProcessLocked(cpi.processName,
11632                                    cpr.appInfo, false, 0, "content provider",
11633                                    new ComponentName(cpi.applicationInfo.packageName,
11634                                            cpi.name), false, false, false);
11635                            checkTime(startTime, "getContentProviderImpl: after start process");
11636                            if (proc == null) {
11637                                Slog.w(TAG, "Unable to launch app "
11638                                        + cpi.applicationInfo.packageName + "/"
11639                                        + cpi.applicationInfo.uid + " for provider "
11640                                        + name + ": process is bad");
11641                                return null;
11642                            }
11643                        }
11644                        cpr.launchingApp = proc;
11645                        mLaunchingProviders.add(cpr);
11646                    } finally {
11647                        Binder.restoreCallingIdentity(origId);
11648                    }
11649                }
11650
11651                checkTime(startTime, "getContentProviderImpl: updating data structures");
11652
11653                // Make sure the provider is published (the same provider class
11654                // may be published under multiple names).
11655                if (firstClass) {
11656                    mProviderMap.putProviderByClass(comp, cpr);
11657                }
11658
11659                mProviderMap.putProviderByName(name, cpr);
11660                conn = incProviderCountLocked(r, cpr, token, stable);
11661                if (conn != null) {
11662                    conn.waiting = true;
11663                }
11664            }
11665            checkTime(startTime, "getContentProviderImpl: done!");
11666
11667            grantEphemeralAccessLocked(userId, null /*intent*/,
11668                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11669        }
11670
11671        // Wait for the provider to be published...
11672        synchronized (cpr) {
11673            while (cpr.provider == null) {
11674                if (cpr.launchingApp == null) {
11675                    Slog.w(TAG, "Unable to launch app "
11676                            + cpi.applicationInfo.packageName + "/"
11677                            + cpi.applicationInfo.uid + " for provider "
11678                            + name + ": launching app became null");
11679                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11680                            UserHandle.getUserId(cpi.applicationInfo.uid),
11681                            cpi.applicationInfo.packageName,
11682                            cpi.applicationInfo.uid, name);
11683                    return null;
11684                }
11685                try {
11686                    if (DEBUG_MU) Slog.v(TAG_MU,
11687                            "Waiting to start provider " + cpr
11688                            + " launchingApp=" + cpr.launchingApp);
11689                    if (conn != null) {
11690                        conn.waiting = true;
11691                    }
11692                    cpr.wait();
11693                } catch (InterruptedException ex) {
11694                } finally {
11695                    if (conn != null) {
11696                        conn.waiting = false;
11697                    }
11698                }
11699            }
11700        }
11701        return cpr != null ? cpr.newHolder(conn) : null;
11702    }
11703
11704    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11705            ProcessRecord r, final int userId) {
11706        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11707                cpi.packageName, userId)) {
11708
11709            final boolean callerForeground = r == null || r.setSchedGroup
11710                    != ProcessList.SCHED_GROUP_BACKGROUND;
11711
11712            // Show a permission review UI only for starting from a foreground app
11713            if (!callerForeground) {
11714                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11715                        + cpi.packageName + " requires a permissions review");
11716                return false;
11717            }
11718
11719            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11720            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11721                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11722            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11723
11724            if (DEBUG_PERMISSIONS_REVIEW) {
11725                Slog.i(TAG, "u" + userId + " Launching permission review "
11726                        + "for package " + cpi.packageName);
11727            }
11728
11729            final UserHandle userHandle = new UserHandle(userId);
11730            mHandler.post(new Runnable() {
11731                @Override
11732                public void run() {
11733                    mContext.startActivityAsUser(intent, userHandle);
11734                }
11735            });
11736
11737            return false;
11738        }
11739
11740        return true;
11741    }
11742
11743    PackageManagerInternal getPackageManagerInternalLocked() {
11744        if (mPackageManagerInt == null) {
11745            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11746        }
11747        return mPackageManagerInt;
11748    }
11749
11750    @Override
11751    public final ContentProviderHolder getContentProvider(
11752            IApplicationThread caller, String name, int userId, boolean stable) {
11753        enforceNotIsolatedCaller("getContentProvider");
11754        if (caller == null) {
11755            String msg = "null IApplicationThread when getting content provider "
11756                    + name;
11757            Slog.w(TAG, msg);
11758            throw new SecurityException(msg);
11759        }
11760        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11761        // with cross-user grant.
11762        return getContentProviderImpl(caller, name, null, stable, userId);
11763    }
11764
11765    public ContentProviderHolder getContentProviderExternal(
11766            String name, int userId, IBinder token) {
11767        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11768            "Do not have permission in call getContentProviderExternal()");
11769        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11770                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11771        return getContentProviderExternalUnchecked(name, token, userId);
11772    }
11773
11774    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11775            IBinder token, int userId) {
11776        return getContentProviderImpl(null, name, token, true, userId);
11777    }
11778
11779    /**
11780     * Drop a content provider from a ProcessRecord's bookkeeping
11781     */
11782    public void removeContentProvider(IBinder connection, boolean stable) {
11783        enforceNotIsolatedCaller("removeContentProvider");
11784        long ident = Binder.clearCallingIdentity();
11785        try {
11786            synchronized (this) {
11787                ContentProviderConnection conn;
11788                try {
11789                    conn = (ContentProviderConnection)connection;
11790                } catch (ClassCastException e) {
11791                    String msg ="removeContentProvider: " + connection
11792                            + " not a ContentProviderConnection";
11793                    Slog.w(TAG, msg);
11794                    throw new IllegalArgumentException(msg);
11795                }
11796                if (conn == null) {
11797                    throw new NullPointerException("connection is null");
11798                }
11799                if (decProviderCountLocked(conn, null, null, stable)) {
11800                    updateOomAdjLocked();
11801                }
11802            }
11803        } finally {
11804            Binder.restoreCallingIdentity(ident);
11805        }
11806    }
11807
11808    public void removeContentProviderExternal(String name, IBinder token) {
11809        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11810            "Do not have permission in call removeContentProviderExternal()");
11811        int userId = UserHandle.getCallingUserId();
11812        long ident = Binder.clearCallingIdentity();
11813        try {
11814            removeContentProviderExternalUnchecked(name, token, userId);
11815        } finally {
11816            Binder.restoreCallingIdentity(ident);
11817        }
11818    }
11819
11820    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11821        synchronized (this) {
11822            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11823            if(cpr == null) {
11824                //remove from mProvidersByClass
11825                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11826                return;
11827            }
11828
11829            //update content provider record entry info
11830            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11831            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11832            if (localCpr.hasExternalProcessHandles()) {
11833                if (localCpr.removeExternalProcessHandleLocked(token)) {
11834                    updateOomAdjLocked();
11835                } else {
11836                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11837                            + " with no external reference for token: "
11838                            + token + ".");
11839                }
11840            } else {
11841                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11842                        + " with no external references.");
11843            }
11844        }
11845    }
11846
11847    public final void publishContentProviders(IApplicationThread caller,
11848            List<ContentProviderHolder> providers) {
11849        if (providers == null) {
11850            return;
11851        }
11852
11853        enforceNotIsolatedCaller("publishContentProviders");
11854        synchronized (this) {
11855            final ProcessRecord r = getRecordForAppLocked(caller);
11856            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11857            if (r == null) {
11858                throw new SecurityException(
11859                        "Unable to find app for caller " + caller
11860                      + " (pid=" + Binder.getCallingPid()
11861                      + ") when publishing content providers");
11862            }
11863
11864            final long origId = Binder.clearCallingIdentity();
11865
11866            final int N = providers.size();
11867            for (int i = 0; i < N; i++) {
11868                ContentProviderHolder src = providers.get(i);
11869                if (src == null || src.info == null || src.provider == null) {
11870                    continue;
11871                }
11872                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11873                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11874                if (dst != null) {
11875                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11876                    mProviderMap.putProviderByClass(comp, dst);
11877                    String names[] = dst.info.authority.split(";");
11878                    for (int j = 0; j < names.length; j++) {
11879                        mProviderMap.putProviderByName(names[j], dst);
11880                    }
11881
11882                    int launchingCount = mLaunchingProviders.size();
11883                    int j;
11884                    boolean wasInLaunchingProviders = false;
11885                    for (j = 0; j < launchingCount; j++) {
11886                        if (mLaunchingProviders.get(j) == dst) {
11887                            mLaunchingProviders.remove(j);
11888                            wasInLaunchingProviders = true;
11889                            j--;
11890                            launchingCount--;
11891                        }
11892                    }
11893                    if (wasInLaunchingProviders) {
11894                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11895                    }
11896                    synchronized (dst) {
11897                        dst.provider = src.provider;
11898                        dst.proc = r;
11899                        dst.notifyAll();
11900                    }
11901                    updateOomAdjLocked(r, true);
11902                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11903                            src.info.authority);
11904                }
11905            }
11906
11907            Binder.restoreCallingIdentity(origId);
11908        }
11909    }
11910
11911    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11912        ContentProviderConnection conn;
11913        try {
11914            conn = (ContentProviderConnection)connection;
11915        } catch (ClassCastException e) {
11916            String msg ="refContentProvider: " + connection
11917                    + " not a ContentProviderConnection";
11918            Slog.w(TAG, msg);
11919            throw new IllegalArgumentException(msg);
11920        }
11921        if (conn == null) {
11922            throw new NullPointerException("connection is null");
11923        }
11924
11925        synchronized (this) {
11926            if (stable > 0) {
11927                conn.numStableIncs += stable;
11928            }
11929            stable = conn.stableCount + stable;
11930            if (stable < 0) {
11931                throw new IllegalStateException("stableCount < 0: " + stable);
11932            }
11933
11934            if (unstable > 0) {
11935                conn.numUnstableIncs += unstable;
11936            }
11937            unstable = conn.unstableCount + unstable;
11938            if (unstable < 0) {
11939                throw new IllegalStateException("unstableCount < 0: " + unstable);
11940            }
11941
11942            if ((stable+unstable) <= 0) {
11943                throw new IllegalStateException("ref counts can't go to zero here: stable="
11944                        + stable + " unstable=" + unstable);
11945            }
11946            conn.stableCount = stable;
11947            conn.unstableCount = unstable;
11948            return !conn.dead;
11949        }
11950    }
11951
11952    public void unstableProviderDied(IBinder connection) {
11953        ContentProviderConnection conn;
11954        try {
11955            conn = (ContentProviderConnection)connection;
11956        } catch (ClassCastException e) {
11957            String msg ="refContentProvider: " + connection
11958                    + " not a ContentProviderConnection";
11959            Slog.w(TAG, msg);
11960            throw new IllegalArgumentException(msg);
11961        }
11962        if (conn == null) {
11963            throw new NullPointerException("connection is null");
11964        }
11965
11966        // Safely retrieve the content provider associated with the connection.
11967        IContentProvider provider;
11968        synchronized (this) {
11969            provider = conn.provider.provider;
11970        }
11971
11972        if (provider == null) {
11973            // Um, yeah, we're way ahead of you.
11974            return;
11975        }
11976
11977        // Make sure the caller is being honest with us.
11978        if (provider.asBinder().pingBinder()) {
11979            // Er, no, still looks good to us.
11980            synchronized (this) {
11981                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11982                        + " says " + conn + " died, but we don't agree");
11983                return;
11984            }
11985        }
11986
11987        // Well look at that!  It's dead!
11988        synchronized (this) {
11989            if (conn.provider.provider != provider) {
11990                // But something changed...  good enough.
11991                return;
11992            }
11993
11994            ProcessRecord proc = conn.provider.proc;
11995            if (proc == null || proc.thread == null) {
11996                // Seems like the process is already cleaned up.
11997                return;
11998            }
11999
12000            // As far as we're concerned, this is just like receiving a
12001            // death notification...  just a bit prematurely.
12002            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12003                    + ") early provider death");
12004            final long ident = Binder.clearCallingIdentity();
12005            try {
12006                appDiedLocked(proc);
12007            } finally {
12008                Binder.restoreCallingIdentity(ident);
12009            }
12010        }
12011    }
12012
12013    @Override
12014    public void appNotRespondingViaProvider(IBinder connection) {
12015        enforceCallingPermission(
12016                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12017
12018        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12019        if (conn == null) {
12020            Slog.w(TAG, "ContentProviderConnection is null");
12021            return;
12022        }
12023
12024        final ProcessRecord host = conn.provider.proc;
12025        if (host == null) {
12026            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12027            return;
12028        }
12029
12030        mHandler.post(new Runnable() {
12031            @Override
12032            public void run() {
12033                mAppErrors.appNotResponding(host, null, null, false,
12034                        "ContentProvider not responding");
12035            }
12036        });
12037    }
12038
12039    public final void installSystemProviders() {
12040        List<ProviderInfo> providers;
12041        synchronized (this) {
12042            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12043            providers = generateApplicationProvidersLocked(app);
12044            if (providers != null) {
12045                for (int i=providers.size()-1; i>=0; i--) {
12046                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12047                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12048                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12049                                + ": not system .apk");
12050                        providers.remove(i);
12051                    }
12052                }
12053            }
12054        }
12055        if (providers != null) {
12056            mSystemThread.installSystemProviders(providers);
12057        }
12058
12059        mConstants.start(mContext.getContentResolver());
12060        mCoreSettingsObserver = new CoreSettingsObserver(this);
12061        mFontScaleSettingObserver = new FontScaleSettingObserver();
12062
12063        // Now that the settings provider is published we can consider sending
12064        // in a rescue party.
12065        RescueParty.onSettingsProviderPublished(mContext);
12066
12067        //mUsageStatsService.monitorPackages();
12068    }
12069
12070    private void startPersistentApps(int matchFlags) {
12071        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12072
12073        synchronized (this) {
12074            try {
12075                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12076                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12077                for (ApplicationInfo app : apps) {
12078                    if (!"android".equals(app.packageName)) {
12079                        addAppLocked(app, null, false, null /* ABI override */);
12080                    }
12081                }
12082            } catch (RemoteException ex) {
12083            }
12084        }
12085    }
12086
12087    /**
12088     * When a user is unlocked, we need to install encryption-unaware providers
12089     * belonging to any running apps.
12090     */
12091    private void installEncryptionUnawareProviders(int userId) {
12092        // We're only interested in providers that are encryption unaware, and
12093        // we don't care about uninstalled apps, since there's no way they're
12094        // running at this point.
12095        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12096
12097        synchronized (this) {
12098            final int NP = mProcessNames.getMap().size();
12099            for (int ip = 0; ip < NP; ip++) {
12100                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12101                final int NA = apps.size();
12102                for (int ia = 0; ia < NA; ia++) {
12103                    final ProcessRecord app = apps.valueAt(ia);
12104                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12105
12106                    final int NG = app.pkgList.size();
12107                    for (int ig = 0; ig < NG; ig++) {
12108                        try {
12109                            final String pkgName = app.pkgList.keyAt(ig);
12110                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12111                                    .getPackageInfo(pkgName, matchFlags, userId);
12112                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12113                                for (ProviderInfo pi : pkgInfo.providers) {
12114                                    // TODO: keep in sync with generateApplicationProvidersLocked
12115                                    final boolean processMatch = Objects.equals(pi.processName,
12116                                            app.processName) || pi.multiprocess;
12117                                    final boolean userMatch = isSingleton(pi.processName,
12118                                            pi.applicationInfo, pi.name, pi.flags)
12119                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12120                                    if (processMatch && userMatch) {
12121                                        Log.v(TAG, "Installing " + pi);
12122                                        app.thread.scheduleInstallProvider(pi);
12123                                    } else {
12124                                        Log.v(TAG, "Skipping " + pi);
12125                                    }
12126                                }
12127                            }
12128                        } catch (RemoteException ignored) {
12129                        }
12130                    }
12131                }
12132            }
12133        }
12134    }
12135
12136    /**
12137     * Allows apps to retrieve the MIME type of a URI.
12138     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12139     * users, then it does not need permission to access the ContentProvider.
12140     * Either, it needs cross-user uri grants.
12141     *
12142     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12143     *
12144     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12145     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12146     */
12147    public String getProviderMimeType(Uri uri, int userId) {
12148        enforceNotIsolatedCaller("getProviderMimeType");
12149        final String name = uri.getAuthority();
12150        int callingUid = Binder.getCallingUid();
12151        int callingPid = Binder.getCallingPid();
12152        long ident = 0;
12153        boolean clearedIdentity = false;
12154        synchronized (this) {
12155            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12156        }
12157        if (canClearIdentity(callingPid, callingUid, userId)) {
12158            clearedIdentity = true;
12159            ident = Binder.clearCallingIdentity();
12160        }
12161        ContentProviderHolder holder = null;
12162        try {
12163            holder = getContentProviderExternalUnchecked(name, null, userId);
12164            if (holder != null) {
12165                return holder.provider.getType(uri);
12166            }
12167        } catch (RemoteException e) {
12168            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12169            return null;
12170        } catch (Exception e) {
12171            Log.w(TAG, "Exception while determining type of " + uri, e);
12172            return null;
12173        } finally {
12174            // We need to clear the identity to call removeContentProviderExternalUnchecked
12175            if (!clearedIdentity) {
12176                ident = Binder.clearCallingIdentity();
12177            }
12178            try {
12179                if (holder != null) {
12180                    removeContentProviderExternalUnchecked(name, null, userId);
12181                }
12182            } finally {
12183                Binder.restoreCallingIdentity(ident);
12184            }
12185        }
12186
12187        return null;
12188    }
12189
12190    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12191        if (UserHandle.getUserId(callingUid) == userId) {
12192            return true;
12193        }
12194        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12195                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12196                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12197                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12198                return true;
12199        }
12200        return false;
12201    }
12202
12203    // =========================================================
12204    // GLOBAL MANAGEMENT
12205    // =========================================================
12206
12207    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12208            boolean isolated, int isolatedUid) {
12209        String proc = customProcess != null ? customProcess : info.processName;
12210        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12211        final int userId = UserHandle.getUserId(info.uid);
12212        int uid = info.uid;
12213        if (isolated) {
12214            if (isolatedUid == 0) {
12215                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12216                while (true) {
12217                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12218                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12219                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12220                    }
12221                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12222                    mNextIsolatedProcessUid++;
12223                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12224                        // No process for this uid, use it.
12225                        break;
12226                    }
12227                    stepsLeft--;
12228                    if (stepsLeft <= 0) {
12229                        return null;
12230                    }
12231                }
12232            } else {
12233                // Special case for startIsolatedProcess (internal only), where
12234                // the uid of the isolated process is specified by the caller.
12235                uid = isolatedUid;
12236            }
12237            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12238
12239            // Register the isolated UID with this application so BatteryStats knows to
12240            // attribute resource usage to the application.
12241            //
12242            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12243            // about the process state of the isolated UID *before* it is registered with the
12244            // owning application.
12245            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12246        }
12247        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12248        if (!mBooted && !mBooting
12249                && userId == UserHandle.USER_SYSTEM
12250                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12251            r.persistent = true;
12252            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12253        }
12254        addProcessNameLocked(r);
12255        return r;
12256    }
12257
12258    private boolean uidOnBackgroundWhitelist(final int uid) {
12259        final int appId = UserHandle.getAppId(uid);
12260        final int[] whitelist = mBackgroundAppIdWhitelist;
12261        final int N = whitelist.length;
12262        for (int i = 0; i < N; i++) {
12263            if (appId == whitelist[i]) {
12264                return true;
12265            }
12266        }
12267        return false;
12268    }
12269
12270    @Override
12271    public void backgroundWhitelistUid(final int uid) {
12272        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12273            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12274        }
12275
12276        if (DEBUG_BACKGROUND_CHECK) {
12277            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12278        }
12279        synchronized (this) {
12280            final int N = mBackgroundAppIdWhitelist.length;
12281            int[] newList = new int[N+1];
12282            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12283            newList[N] = UserHandle.getAppId(uid);
12284            mBackgroundAppIdWhitelist = newList;
12285        }
12286    }
12287
12288    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12289            String abiOverride) {
12290        ProcessRecord app;
12291        if (!isolated) {
12292            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12293                    info.uid, true);
12294        } else {
12295            app = null;
12296        }
12297
12298        if (app == null) {
12299            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12300            updateLruProcessLocked(app, false, null);
12301            updateOomAdjLocked();
12302        }
12303
12304        // This package really, really can not be stopped.
12305        try {
12306            AppGlobals.getPackageManager().setPackageStoppedState(
12307                    info.packageName, false, UserHandle.getUserId(app.uid));
12308        } catch (RemoteException e) {
12309        } catch (IllegalArgumentException e) {
12310            Slog.w(TAG, "Failed trying to unstop package "
12311                    + info.packageName + ": " + e);
12312        }
12313
12314        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12315            app.persistent = true;
12316            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12317        }
12318        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12319            mPersistentStartingProcesses.add(app);
12320            startProcessLocked(app, "added application",
12321                    customProcess != null ? customProcess : app.processName, abiOverride,
12322                    null /* entryPoint */, null /* entryPointArgs */);
12323        }
12324
12325        return app;
12326    }
12327
12328    public void unhandledBack() {
12329        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12330                "unhandledBack()");
12331
12332        synchronized(this) {
12333            final long origId = Binder.clearCallingIdentity();
12334            try {
12335                getFocusedStack().unhandledBackLocked();
12336            } finally {
12337                Binder.restoreCallingIdentity(origId);
12338            }
12339        }
12340    }
12341
12342    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12343        enforceNotIsolatedCaller("openContentUri");
12344        final int userId = UserHandle.getCallingUserId();
12345        final Uri uri = Uri.parse(uriString);
12346        String name = uri.getAuthority();
12347        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12348        ParcelFileDescriptor pfd = null;
12349        if (cph != null) {
12350            // We record the binder invoker's uid in thread-local storage before
12351            // going to the content provider to open the file.  Later, in the code
12352            // that handles all permissions checks, we look for this uid and use
12353            // that rather than the Activity Manager's own uid.  The effect is that
12354            // we do the check against the caller's permissions even though it looks
12355            // to the content provider like the Activity Manager itself is making
12356            // the request.
12357            Binder token = new Binder();
12358            sCallerIdentity.set(new Identity(
12359                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12360            try {
12361                pfd = cph.provider.openFile(null, uri, "r", null, token);
12362            } catch (FileNotFoundException e) {
12363                // do nothing; pfd will be returned null
12364            } finally {
12365                // Ensure that whatever happens, we clean up the identity state
12366                sCallerIdentity.remove();
12367                // Ensure we're done with the provider.
12368                removeContentProviderExternalUnchecked(name, null, userId);
12369            }
12370        } else {
12371            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12372        }
12373        return pfd;
12374    }
12375
12376    // Actually is sleeping or shutting down or whatever else in the future
12377    // is an inactive state.
12378    boolean isSleepingOrShuttingDownLocked() {
12379        return isSleepingLocked() || mShuttingDown;
12380    }
12381
12382    boolean isShuttingDownLocked() {
12383        return mShuttingDown;
12384    }
12385
12386    boolean isSleepingLocked() {
12387        return mSleeping;
12388    }
12389
12390    void onWakefulnessChanged(int wakefulness) {
12391        synchronized(this) {
12392            mWakefulness = wakefulness;
12393            updateSleepIfNeededLocked();
12394        }
12395    }
12396
12397    void finishRunningVoiceLocked() {
12398        if (mRunningVoice != null) {
12399            mRunningVoice = null;
12400            mVoiceWakeLock.release();
12401            updateSleepIfNeededLocked();
12402        }
12403    }
12404
12405    void startTimeTrackingFocusedActivityLocked() {
12406        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12407        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12408            mCurAppTimeTracker.start(resumedActivity.packageName);
12409        }
12410    }
12411
12412    void updateSleepIfNeededLocked() {
12413        final boolean shouldSleep = shouldSleepLocked();
12414        if (mSleeping && !shouldSleep) {
12415            mSleeping = false;
12416            startTimeTrackingFocusedActivityLocked();
12417            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12418            mStackSupervisor.comeOutOfSleepIfNeededLocked();
12419            sendNotifyVrManagerOfSleepState(false);
12420            updateOomAdjLocked();
12421        } else if (!mSleeping && shouldSleep) {
12422            mSleeping = true;
12423            if (mCurAppTimeTracker != null) {
12424                mCurAppTimeTracker.stop();
12425            }
12426            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12427            mStackSupervisor.goingToSleepLocked();
12428            sendNotifyVrManagerOfSleepState(true);
12429            updateOomAdjLocked();
12430
12431            // Initialize the wake times of all processes.
12432            checkExcessivePowerUsageLocked(false);
12433            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12434            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12435            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
12436        }
12437
12438        // Also update state in a special way for running foreground services UI.
12439        switch (mWakefulness) {
12440            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12441            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12442            case PowerManagerInternal.WAKEFULNESS_DOZING:
12443                mServices.updateScreenStateLocked(false);
12444                break;
12445            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12446            default:
12447                mServices.updateScreenStateLocked(true);
12448                break;
12449        }
12450    }
12451
12452    private boolean shouldSleepLocked() {
12453        // Resume applications while running a voice interactor.
12454        if (mRunningVoice != null) {
12455            return false;
12456        }
12457
12458        // TODO: Transform the lock screen state into a sleep token instead.
12459        switch (mWakefulness) {
12460            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12461            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12462            case PowerManagerInternal.WAKEFULNESS_DOZING:
12463                // Pause applications whenever the lock screen is shown or any sleep
12464                // tokens have been acquired.
12465                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12466            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12467            default:
12468                // If we're asleep then pause applications unconditionally.
12469                return true;
12470        }
12471    }
12472
12473    /** Pokes the task persister. */
12474    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12475        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12476    }
12477
12478    /**
12479     * Notifies all listeners when the pinned stack animation starts.
12480     */
12481    @Override
12482    public void notifyPinnedStackAnimationStarted() {
12483        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12484    }
12485
12486    /**
12487     * Notifies all listeners when the pinned stack animation ends.
12488     */
12489    @Override
12490    public void notifyPinnedStackAnimationEnded() {
12491        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12492    }
12493
12494    @Override
12495    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12496        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12497    }
12498
12499    @Override
12500    public boolean shutdown(int timeout) {
12501        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12502                != PackageManager.PERMISSION_GRANTED) {
12503            throw new SecurityException("Requires permission "
12504                    + android.Manifest.permission.SHUTDOWN);
12505        }
12506
12507        boolean timedout = false;
12508
12509        synchronized(this) {
12510            mShuttingDown = true;
12511            updateEventDispatchingLocked();
12512            timedout = mStackSupervisor.shutdownLocked(timeout);
12513        }
12514
12515        mAppOpsService.shutdown();
12516        if (mUsageStatsService != null) {
12517            mUsageStatsService.prepareShutdown();
12518        }
12519        mBatteryStatsService.shutdown();
12520        synchronized (this) {
12521            mProcessStats.shutdownLocked();
12522            notifyTaskPersisterLocked(null, true);
12523        }
12524
12525        return timedout;
12526    }
12527
12528    public final void activitySlept(IBinder token) {
12529        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12530
12531        final long origId = Binder.clearCallingIdentity();
12532
12533        synchronized (this) {
12534            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12535            if (r != null) {
12536                mStackSupervisor.activitySleptLocked(r);
12537            }
12538        }
12539
12540        Binder.restoreCallingIdentity(origId);
12541    }
12542
12543    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12544        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12545        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12546        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12547            boolean wasRunningVoice = mRunningVoice != null;
12548            mRunningVoice = session;
12549            if (!wasRunningVoice) {
12550                mVoiceWakeLock.acquire();
12551                updateSleepIfNeededLocked();
12552            }
12553        }
12554    }
12555
12556    private void updateEventDispatchingLocked() {
12557        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12558    }
12559
12560    @Override
12561    public void setLockScreenShown(boolean showing) {
12562        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12563                != PackageManager.PERMISSION_GRANTED) {
12564            throw new SecurityException("Requires permission "
12565                    + android.Manifest.permission.DEVICE_POWER);
12566        }
12567
12568        synchronized(this) {
12569            long ident = Binder.clearCallingIdentity();
12570            try {
12571                mKeyguardController.setKeyguardShown(showing);
12572            } finally {
12573                Binder.restoreCallingIdentity(ident);
12574            }
12575        }
12576        closeSystemDialogs("setLockScreenShown");
12577    }
12578
12579    @Override
12580    public void notifyLockedProfile(@UserIdInt int userId) {
12581        try {
12582            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12583                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12584            }
12585        } catch (RemoteException ex) {
12586            throw new SecurityException("Fail to check is caller a privileged app", ex);
12587        }
12588
12589        synchronized (this) {
12590            final long ident = Binder.clearCallingIdentity();
12591            try {
12592                if (mUserController.shouldConfirmCredentials(userId)) {
12593                    if (mKeyguardController.isKeyguardLocked()) {
12594                        // Showing launcher to avoid user entering credential twice.
12595                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12596                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12597                    }
12598                    mStackSupervisor.lockAllProfileTasks(userId);
12599                }
12600            } finally {
12601                Binder.restoreCallingIdentity(ident);
12602            }
12603        }
12604    }
12605
12606    @Override
12607    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12608        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12609        synchronized (this) {
12610            final long ident = Binder.clearCallingIdentity();
12611            try {
12612                mActivityStarter.startConfirmCredentialIntent(intent, options);
12613            } finally {
12614                Binder.restoreCallingIdentity(ident);
12615            }
12616        }
12617    }
12618
12619    @Override
12620    public void stopAppSwitches() {
12621        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12622                != PackageManager.PERMISSION_GRANTED) {
12623            throw new SecurityException("viewquires permission "
12624                    + android.Manifest.permission.STOP_APP_SWITCHES);
12625        }
12626
12627        synchronized(this) {
12628            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12629                    + APP_SWITCH_DELAY_TIME;
12630            mDidAppSwitch = false;
12631            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12632            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12633            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12634        }
12635    }
12636
12637    public void resumeAppSwitches() {
12638        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12639                != PackageManager.PERMISSION_GRANTED) {
12640            throw new SecurityException("Requires permission "
12641                    + android.Manifest.permission.STOP_APP_SWITCHES);
12642        }
12643
12644        synchronized(this) {
12645            // Note that we don't execute any pending app switches... we will
12646            // let those wait until either the timeout, or the next start
12647            // activity request.
12648            mAppSwitchesAllowedTime = 0;
12649        }
12650    }
12651
12652    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12653            int callingPid, int callingUid, String name) {
12654        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12655            return true;
12656        }
12657
12658        int perm = checkComponentPermission(
12659                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12660                sourceUid, -1, true);
12661        if (perm == PackageManager.PERMISSION_GRANTED) {
12662            return true;
12663        }
12664
12665        // If the actual IPC caller is different from the logical source, then
12666        // also see if they are allowed to control app switches.
12667        if (callingUid != -1 && callingUid != sourceUid) {
12668            perm = checkComponentPermission(
12669                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12670                    callingUid, -1, true);
12671            if (perm == PackageManager.PERMISSION_GRANTED) {
12672                return true;
12673            }
12674        }
12675
12676        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12677        return false;
12678    }
12679
12680    public void setDebugApp(String packageName, boolean waitForDebugger,
12681            boolean persistent) {
12682        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12683                "setDebugApp()");
12684
12685        long ident = Binder.clearCallingIdentity();
12686        try {
12687            // Note that this is not really thread safe if there are multiple
12688            // callers into it at the same time, but that's not a situation we
12689            // care about.
12690            if (persistent) {
12691                final ContentResolver resolver = mContext.getContentResolver();
12692                Settings.Global.putString(
12693                    resolver, Settings.Global.DEBUG_APP,
12694                    packageName);
12695                Settings.Global.putInt(
12696                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12697                    waitForDebugger ? 1 : 0);
12698            }
12699
12700            synchronized (this) {
12701                if (!persistent) {
12702                    mOrigDebugApp = mDebugApp;
12703                    mOrigWaitForDebugger = mWaitForDebugger;
12704                }
12705                mDebugApp = packageName;
12706                mWaitForDebugger = waitForDebugger;
12707                mDebugTransient = !persistent;
12708                if (packageName != null) {
12709                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12710                            false, UserHandle.USER_ALL, "set debug app");
12711                }
12712            }
12713        } finally {
12714            Binder.restoreCallingIdentity(ident);
12715        }
12716    }
12717
12718    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12719        synchronized (this) {
12720            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12721            if (!isDebuggable) {
12722                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12723                    throw new SecurityException("Process not debuggable: " + app.packageName);
12724                }
12725            }
12726
12727            mTrackAllocationApp = processName;
12728        }
12729    }
12730
12731    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12732        synchronized (this) {
12733            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12734            if (!isDebuggable) {
12735                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12736                    throw new SecurityException("Process not debuggable: " + app.packageName);
12737                }
12738            }
12739            mProfileApp = processName;
12740            mProfileFile = profilerInfo.profileFile;
12741            if (mProfileFd != null) {
12742                try {
12743                    mProfileFd.close();
12744                } catch (IOException e) {
12745                }
12746                mProfileFd = null;
12747            }
12748            mProfileFd = profilerInfo.profileFd;
12749            mSamplingInterval = profilerInfo.samplingInterval;
12750            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12751            mStreamingOutput = profilerInfo.streamingOutput;
12752            mProfileType = 0;
12753        }
12754    }
12755
12756    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12757        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12758        if (!isDebuggable) {
12759            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12760                throw new SecurityException("Process not debuggable: " + app.packageName);
12761            }
12762        }
12763        mNativeDebuggingApp = processName;
12764    }
12765
12766    @Override
12767    public void setAlwaysFinish(boolean enabled) {
12768        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12769                "setAlwaysFinish()");
12770
12771        long ident = Binder.clearCallingIdentity();
12772        try {
12773            Settings.Global.putInt(
12774                    mContext.getContentResolver(),
12775                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12776
12777            synchronized (this) {
12778                mAlwaysFinishActivities = enabled;
12779            }
12780        } finally {
12781            Binder.restoreCallingIdentity(ident);
12782        }
12783    }
12784
12785    @Override
12786    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12787        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12788                "setActivityController()");
12789        synchronized (this) {
12790            mController = controller;
12791            mControllerIsAMonkey = imAMonkey;
12792            Watchdog.getInstance().setActivityController(controller);
12793        }
12794    }
12795
12796    @Override
12797    public void setUserIsMonkey(boolean userIsMonkey) {
12798        synchronized (this) {
12799            synchronized (mPidsSelfLocked) {
12800                final int callingPid = Binder.getCallingPid();
12801                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12802                if (proc == null) {
12803                    throw new SecurityException("Unknown process: " + callingPid);
12804                }
12805                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12806                    throw new SecurityException("Only an instrumentation process "
12807                            + "with a UiAutomation can call setUserIsMonkey");
12808                }
12809            }
12810            mUserIsMonkey = userIsMonkey;
12811        }
12812    }
12813
12814    @Override
12815    public boolean isUserAMonkey() {
12816        synchronized (this) {
12817            // If there is a controller also implies the user is a monkey.
12818            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12819        }
12820    }
12821
12822    /**
12823     * @deprecated This method is only used by a few internal components and it will soon be
12824     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12825     * No new code should be calling it.
12826     */
12827    @Deprecated
12828    @Override
12829    public void requestBugReport(int bugreportType) {
12830        String extraOptions = null;
12831        switch (bugreportType) {
12832            case ActivityManager.BUGREPORT_OPTION_FULL:
12833                // Default options.
12834                break;
12835            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12836                extraOptions = "bugreportplus";
12837                break;
12838            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12839                extraOptions = "bugreportremote";
12840                break;
12841            case ActivityManager.BUGREPORT_OPTION_WEAR:
12842                extraOptions = "bugreportwear";
12843                break;
12844            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12845                extraOptions = "bugreporttelephony";
12846                break;
12847            default:
12848                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12849                        + bugreportType);
12850        }
12851        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12852        if (extraOptions != null) {
12853            SystemProperties.set("dumpstate.options", extraOptions);
12854        }
12855        SystemProperties.set("ctl.start", "bugreport");
12856    }
12857
12858    /**
12859     * @deprecated This method is only used by a few internal components and it will soon be
12860     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12861     * No new code should be calling it.
12862     */
12863    @Deprecated
12864    @Override
12865    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12866
12867        if (!TextUtils.isEmpty(shareTitle)) {
12868            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12869                String errorStr = "shareTitle should be less than " +
12870                        MAX_BUGREPORT_TITLE_SIZE + " characters";
12871                throw new IllegalArgumentException(errorStr);
12872            } else {
12873                if (!TextUtils.isEmpty(shareDescription)) {
12874                    int length;
12875                    try {
12876                        length = shareDescription.getBytes("UTF-8").length;
12877                    } catch (UnsupportedEncodingException e) {
12878                        String errorStr = "shareDescription: UnsupportedEncodingException";
12879                        throw new IllegalArgumentException(errorStr);
12880                    }
12881                    if (length > SystemProperties.PROP_VALUE_MAX) {
12882                        String errorStr = "shareTitle should be less than " +
12883                                SystemProperties.PROP_VALUE_MAX + " bytes";
12884                        throw new IllegalArgumentException(errorStr);
12885                    } else {
12886                        SystemProperties.set("dumpstate.options.description", shareDescription);
12887                    }
12888                }
12889                SystemProperties.set("dumpstate.options.title", shareTitle);
12890            }
12891        }
12892
12893        Slog.d(TAG, "Bugreport notification title " + shareTitle
12894                + " description " + shareDescription);
12895        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12896    }
12897
12898    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12899        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12900    }
12901
12902    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12903        if (r != null && (r.instr != null || r.usingWrapper)) {
12904            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12905        }
12906        return KEY_DISPATCHING_TIMEOUT;
12907    }
12908
12909    @Override
12910    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12911        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12912                != PackageManager.PERMISSION_GRANTED) {
12913            throw new SecurityException("Requires permission "
12914                    + android.Manifest.permission.FILTER_EVENTS);
12915        }
12916        ProcessRecord proc;
12917        long timeout;
12918        synchronized (this) {
12919            synchronized (mPidsSelfLocked) {
12920                proc = mPidsSelfLocked.get(pid);
12921            }
12922            timeout = getInputDispatchingTimeoutLocked(proc);
12923        }
12924
12925        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12926            return -1;
12927        }
12928
12929        return timeout;
12930    }
12931
12932    /**
12933     * Handle input dispatching timeouts.
12934     * Returns whether input dispatching should be aborted or not.
12935     */
12936    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12937            final ActivityRecord activity, final ActivityRecord parent,
12938            final boolean aboveSystem, String reason) {
12939        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12940                != PackageManager.PERMISSION_GRANTED) {
12941            throw new SecurityException("Requires permission "
12942                    + android.Manifest.permission.FILTER_EVENTS);
12943        }
12944
12945        final String annotation;
12946        if (reason == null) {
12947            annotation = "Input dispatching timed out";
12948        } else {
12949            annotation = "Input dispatching timed out (" + reason + ")";
12950        }
12951
12952        if (proc != null) {
12953            synchronized (this) {
12954                if (proc.debugging) {
12955                    return false;
12956                }
12957
12958                if (proc.instr != null) {
12959                    Bundle info = new Bundle();
12960                    info.putString("shortMsg", "keyDispatchingTimedOut");
12961                    info.putString("longMsg", annotation);
12962                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12963                    return true;
12964                }
12965            }
12966            mHandler.post(new Runnable() {
12967                @Override
12968                public void run() {
12969                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12970                }
12971            });
12972        }
12973
12974        return true;
12975    }
12976
12977    @Override
12978    public Bundle getAssistContextExtras(int requestType) {
12979        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12980                null, null, true /* focused */, true /* newSessionId */,
12981                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12982        if (pae == null) {
12983            return null;
12984        }
12985        synchronized (pae) {
12986            while (!pae.haveResult) {
12987                try {
12988                    pae.wait();
12989                } catch (InterruptedException e) {
12990                }
12991            }
12992        }
12993        synchronized (this) {
12994            buildAssistBundleLocked(pae, pae.result);
12995            mPendingAssistExtras.remove(pae);
12996            mUiHandler.removeCallbacks(pae);
12997        }
12998        return pae.extras;
12999    }
13000
13001    @Override
13002    public boolean isAssistDataAllowedOnCurrentActivity() {
13003        int userId;
13004        synchronized (this) {
13005            final ActivityStack focusedStack = getFocusedStack();
13006            if (focusedStack == null || focusedStack.isAssistantStack()) {
13007                return false;
13008            }
13009
13010            final ActivityRecord activity = focusedStack.topActivity();
13011            if (activity == null) {
13012                return false;
13013            }
13014            userId = activity.userId;
13015        }
13016        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13017                Context.DEVICE_POLICY_SERVICE);
13018        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13019    }
13020
13021    @Override
13022    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13023        long ident = Binder.clearCallingIdentity();
13024        try {
13025            synchronized (this) {
13026                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13027                ActivityRecord top = getFocusedStack().topActivity();
13028                if (top != caller) {
13029                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13030                            + " is not current top " + top);
13031                    return false;
13032                }
13033                if (!top.nowVisible) {
13034                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13035                            + " is not visible");
13036                    return false;
13037                }
13038            }
13039            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13040                    token);
13041        } finally {
13042            Binder.restoreCallingIdentity(ident);
13043        }
13044    }
13045
13046    @Override
13047    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13048            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13049        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13050                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13051                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13052    }
13053
13054    @Override
13055    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13056            IBinder activityToken, int flags) {
13057        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13058                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13059                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13060    }
13061
13062    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13063            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13064            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13065            int flags) {
13066        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13067                "enqueueAssistContext()");
13068
13069        synchronized (this) {
13070            ActivityRecord activity = getFocusedStack().topActivity();
13071            if (activity == null) {
13072                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13073                return null;
13074            }
13075            if (activity.app == null || activity.app.thread == null) {
13076                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13077                return null;
13078            }
13079            if (focused) {
13080                if (activityToken != null) {
13081                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13082                    if (activity != caller) {
13083                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13084                                + " is not current top " + activity);
13085                        return null;
13086                    }
13087                }
13088            } else {
13089                activity = ActivityRecord.forTokenLocked(activityToken);
13090                if (activity == null) {
13091                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13092                            + " couldn't be found");
13093                    return null;
13094                }
13095            }
13096
13097            PendingAssistExtras pae;
13098            Bundle extras = new Bundle();
13099            if (args != null) {
13100                extras.putAll(args);
13101            }
13102            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13103            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13104
13105            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13106                    userHandle);
13107            pae.isHome = activity.isHomeActivity();
13108
13109            // Increment the sessionId if necessary
13110            if (newSessionId) {
13111                mViSessionId++;
13112            }
13113            try {
13114                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13115                        mViSessionId, flags);
13116                mPendingAssistExtras.add(pae);
13117                mUiHandler.postDelayed(pae, timeout);
13118            } catch (RemoteException e) {
13119                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13120                return null;
13121            }
13122            return pae;
13123        }
13124    }
13125
13126    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13127        IResultReceiver receiver;
13128        synchronized (this) {
13129            mPendingAssistExtras.remove(pae);
13130            receiver = pae.receiver;
13131        }
13132        if (receiver != null) {
13133            // Caller wants result sent back to them.
13134            Bundle sendBundle = new Bundle();
13135            // At least return the receiver extras
13136            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13137                    pae.receiverExtras);
13138            try {
13139                pae.receiver.send(0, sendBundle);
13140            } catch (RemoteException e) {
13141            }
13142        }
13143    }
13144
13145    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13146        if (result != null) {
13147            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13148        }
13149        if (pae.hint != null) {
13150            pae.extras.putBoolean(pae.hint, true);
13151        }
13152    }
13153
13154    /** Called from an app when assist data is ready. */
13155    @Override
13156    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13157            AssistContent content, Uri referrer) {
13158        PendingAssistExtras pae = (PendingAssistExtras)token;
13159        synchronized (pae) {
13160            pae.result = extras;
13161            pae.structure = structure;
13162            pae.content = content;
13163            if (referrer != null) {
13164                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13165            }
13166            if (structure != null) {
13167                structure.setHomeActivity(pae.isHome);
13168            }
13169            pae.haveResult = true;
13170            pae.notifyAll();
13171            if (pae.intent == null && pae.receiver == null) {
13172                // Caller is just waiting for the result.
13173                return;
13174            }
13175        }
13176
13177        // We are now ready to launch the assist activity.
13178        IResultReceiver sendReceiver = null;
13179        Bundle sendBundle = null;
13180        synchronized (this) {
13181            buildAssistBundleLocked(pae, extras);
13182            boolean exists = mPendingAssistExtras.remove(pae);
13183            mUiHandler.removeCallbacks(pae);
13184            if (!exists) {
13185                // Timed out.
13186                return;
13187            }
13188            if ((sendReceiver=pae.receiver) != null) {
13189                // Caller wants result sent back to them.
13190                sendBundle = new Bundle();
13191                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13192                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13193                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13194                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13195                        pae.receiverExtras);
13196            }
13197        }
13198        if (sendReceiver != null) {
13199            try {
13200                sendReceiver.send(0, sendBundle);
13201            } catch (RemoteException e) {
13202            }
13203            return;
13204        }
13205
13206        long ident = Binder.clearCallingIdentity();
13207        try {
13208            pae.intent.replaceExtras(pae.extras);
13209            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13210                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
13211                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13212            closeSystemDialogs("assist");
13213            try {
13214                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13215            } catch (ActivityNotFoundException e) {
13216                Slog.w(TAG, "No activity to handle assist action.", e);
13217            }
13218        } finally {
13219            Binder.restoreCallingIdentity(ident);
13220        }
13221    }
13222
13223    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13224            Bundle args) {
13225        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13226                true /* focused */, true /* newSessionId */, userHandle, args,
13227                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13228    }
13229
13230    public void registerProcessObserver(IProcessObserver observer) {
13231        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13232                "registerProcessObserver()");
13233        synchronized (this) {
13234            mProcessObservers.register(observer);
13235        }
13236    }
13237
13238    @Override
13239    public void unregisterProcessObserver(IProcessObserver observer) {
13240        synchronized (this) {
13241            mProcessObservers.unregister(observer);
13242        }
13243    }
13244
13245    @Override
13246    public int getUidProcessState(int uid, String callingPackage) {
13247        if (!hasUsageStatsPermission(callingPackage)) {
13248            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13249                    "getUidProcessState");
13250        }
13251
13252        synchronized (this) {
13253            UidRecord uidRec = mActiveUids.get(uid);
13254            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13255        }
13256    }
13257
13258    @Override
13259    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13260            String callingPackage) {
13261        if (!hasUsageStatsPermission(callingPackage)) {
13262            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13263                    "registerUidObserver");
13264        }
13265        synchronized (this) {
13266            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13267                    callingPackage, which, cutpoint));
13268        }
13269    }
13270
13271    @Override
13272    public void unregisterUidObserver(IUidObserver observer) {
13273        synchronized (this) {
13274            mUidObservers.unregister(observer);
13275        }
13276    }
13277
13278    @Override
13279    public boolean convertFromTranslucent(IBinder token) {
13280        final long origId = Binder.clearCallingIdentity();
13281        try {
13282            synchronized (this) {
13283                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13284                if (r == null) {
13285                    return false;
13286                }
13287                final boolean translucentChanged = r.changeWindowTranslucency(true);
13288                if (translucentChanged) {
13289                    r.getStack().releaseBackgroundResources(r);
13290                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13291                }
13292                mWindowManager.setAppFullscreen(token, true);
13293                return translucentChanged;
13294            }
13295        } finally {
13296            Binder.restoreCallingIdentity(origId);
13297        }
13298    }
13299
13300    @Override
13301    public boolean convertToTranslucent(IBinder token, Bundle options) {
13302        final long origId = Binder.clearCallingIdentity();
13303        try {
13304            synchronized (this) {
13305                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13306                if (r == null) {
13307                    return false;
13308                }
13309                final TaskRecord task = r.getTask();
13310                int index = task.mActivities.lastIndexOf(r);
13311                if (index > 0) {
13312                    ActivityRecord under = task.mActivities.get(index - 1);
13313                    under.returningOptions = ActivityOptions.fromBundle(options);
13314                }
13315                final boolean translucentChanged = r.changeWindowTranslucency(false);
13316                if (translucentChanged) {
13317                    r.getStack().convertActivityToTranslucent(r);
13318                }
13319                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13320                mWindowManager.setAppFullscreen(token, false);
13321                return translucentChanged;
13322            }
13323        } finally {
13324            Binder.restoreCallingIdentity(origId);
13325        }
13326    }
13327
13328    @Override
13329    public boolean requestVisibleBehind(IBinder token, boolean visible) {
13330        final long origId = Binder.clearCallingIdentity();
13331        try {
13332            synchronized (this) {
13333                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13334                if (r != null) {
13335                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13336                }
13337            }
13338            return false;
13339        } finally {
13340            Binder.restoreCallingIdentity(origId);
13341        }
13342    }
13343
13344    @Override
13345    public boolean isBackgroundVisibleBehind(IBinder token) {
13346        final long origId = Binder.clearCallingIdentity();
13347        try {
13348            synchronized (this) {
13349                final ActivityStack stack = ActivityRecord.getStackLocked(token);
13350                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13351                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13352                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13353                return visible;
13354            }
13355        } finally {
13356            Binder.restoreCallingIdentity(origId);
13357        }
13358    }
13359
13360    @Override
13361    public Bundle getActivityOptions(IBinder token) {
13362        final long origId = Binder.clearCallingIdentity();
13363        try {
13364            synchronized (this) {
13365                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13366                if (r != null) {
13367                    final ActivityOptions activityOptions = r.pendingOptions;
13368                    r.pendingOptions = null;
13369                    return activityOptions == null ? null : activityOptions.toBundle();
13370                }
13371                return null;
13372            }
13373        } finally {
13374            Binder.restoreCallingIdentity(origId);
13375        }
13376    }
13377
13378    @Override
13379    public void setImmersive(IBinder token, boolean immersive) {
13380        synchronized(this) {
13381            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13382            if (r == null) {
13383                throw new IllegalArgumentException();
13384            }
13385            r.immersive = immersive;
13386
13387            // update associated state if we're frontmost
13388            if (r == mStackSupervisor.getResumedActivityLocked()) {
13389                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13390                applyUpdateLockStateLocked(r);
13391            }
13392        }
13393    }
13394
13395    @Override
13396    public boolean isImmersive(IBinder token) {
13397        synchronized (this) {
13398            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13399            if (r == null) {
13400                throw new IllegalArgumentException();
13401            }
13402            return r.immersive;
13403        }
13404    }
13405
13406    @Override
13407    public void setVrThread(int tid) {
13408        enforceSystemHasVrFeature();
13409        synchronized (this) {
13410            synchronized (mPidsSelfLocked) {
13411                final int pid = Binder.getCallingPid();
13412                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13413                mVrController.setVrThreadLocked(tid, pid, proc);
13414            }
13415        }
13416    }
13417
13418    @Override
13419    public void setPersistentVrThread(int tid) {
13420        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13421            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13422                    + Binder.getCallingPid()
13423                    + ", uid=" + Binder.getCallingUid()
13424                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13425            Slog.w(TAG, msg);
13426            throw new SecurityException(msg);
13427        }
13428        enforceSystemHasVrFeature();
13429        synchronized (this) {
13430            synchronized (mPidsSelfLocked) {
13431                final int pid = Binder.getCallingPid();
13432                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13433                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13434            }
13435        }
13436    }
13437
13438    /**
13439     * Schedule the given thread a normal scheduling priority.
13440     *
13441     * @param newTid the tid of the thread to adjust the scheduling of.
13442     * @param suppressLogs {@code true} if any error logging should be disabled.
13443     *
13444     * @return {@code true} if this succeeded.
13445     */
13446    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13447        try {
13448            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13449            return true;
13450        } catch (IllegalArgumentException e) {
13451            if (!suppressLogs) {
13452                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13453            }
13454        }
13455        return false;
13456    }
13457
13458    /**
13459     * Schedule the given thread an FIFO scheduling priority.
13460     *
13461     * @param newTid the tid of the thread to adjust the scheduling of.
13462     * @param suppressLogs {@code true} if any error logging should be disabled.
13463     *
13464     * @return {@code true} if this succeeded.
13465     */
13466    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13467        try {
13468            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13469            return true;
13470        } catch (IllegalArgumentException e) {
13471            if (!suppressLogs) {
13472                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13473            }
13474        }
13475        return false;
13476    }
13477
13478    /**
13479     * Check that we have the features required for VR-related API calls, and throw an exception if
13480     * not.
13481     */
13482    private void enforceSystemHasVrFeature() {
13483        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13484            throw new UnsupportedOperationException("VR mode not supported on this device!");
13485        }
13486    }
13487
13488    @Override
13489    public void setRenderThread(int tid) {
13490        synchronized (this) {
13491            ProcessRecord proc;
13492            int pid = Binder.getCallingPid();
13493            if (pid == Process.myPid()) {
13494                demoteSystemServerRenderThread(tid);
13495                return;
13496            }
13497            synchronized (mPidsSelfLocked) {
13498                proc = mPidsSelfLocked.get(pid);
13499                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13500                    // ensure the tid belongs to the process
13501                    if (!isThreadInProcess(pid, tid)) {
13502                        throw new IllegalArgumentException(
13503                            "Render thread does not belong to process");
13504                    }
13505                    proc.renderThreadTid = tid;
13506                    if (DEBUG_OOM_ADJ) {
13507                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13508                    }
13509                    // promote to FIFO now
13510                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13511                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13512                        if (mUseFifoUiScheduling) {
13513                            setThreadScheduler(proc.renderThreadTid,
13514                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13515                        } else {
13516                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13517                        }
13518                    }
13519                } else {
13520                    if (DEBUG_OOM_ADJ) {
13521                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13522                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13523                               mUseFifoUiScheduling);
13524                    }
13525                }
13526            }
13527        }
13528    }
13529
13530    /**
13531     * We only use RenderThread in system_server to store task snapshots to the disk, which should
13532     * happen in the background. Thus, demote render thread from system_server to a lower priority.
13533     *
13534     * @param tid the tid of the RenderThread
13535     */
13536    private void demoteSystemServerRenderThread(int tid) {
13537        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13538    }
13539
13540    @Override
13541    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13542        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13543            throw new UnsupportedOperationException("VR mode not supported on this device!");
13544        }
13545
13546        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13547
13548        ActivityRecord r;
13549        synchronized (this) {
13550            r = ActivityRecord.isInStackLocked(token);
13551        }
13552
13553        if (r == null) {
13554            throw new IllegalArgumentException();
13555        }
13556
13557        int err;
13558        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13559                VrManagerInternal.NO_ERROR) {
13560            return err;
13561        }
13562
13563        synchronized(this) {
13564            r.requestedVrComponent = (enabled) ? packageName : null;
13565
13566            // Update associated state if this activity is currently focused
13567            if (r == mStackSupervisor.getResumedActivityLocked()) {
13568                applyUpdateVrModeLocked(r);
13569            }
13570            return 0;
13571        }
13572    }
13573
13574    @Override
13575    public boolean isVrModePackageEnabled(ComponentName packageName) {
13576        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13577            throw new UnsupportedOperationException("VR mode not supported on this device!");
13578        }
13579
13580        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13581
13582        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13583                VrManagerInternal.NO_ERROR;
13584    }
13585
13586    public boolean isTopActivityImmersive() {
13587        enforceNotIsolatedCaller("startActivity");
13588        synchronized (this) {
13589            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13590            return (r != null) ? r.immersive : false;
13591        }
13592    }
13593
13594    /**
13595     * @return whether the system should disable UI modes incompatible with VR mode.
13596     */
13597    boolean shouldDisableNonVrUiLocked() {
13598        return mVrController.shouldDisableNonVrUiLocked();
13599    }
13600
13601    @Override
13602    public boolean isTopOfTask(IBinder token) {
13603        synchronized (this) {
13604            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13605            if (r == null) {
13606                throw new IllegalArgumentException();
13607            }
13608            return r.getTask().getTopActivity() == r;
13609        }
13610    }
13611
13612    @Override
13613    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13614        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13615            String msg = "Permission Denial: setHasTopUi() from pid="
13616                    + Binder.getCallingPid()
13617                    + ", uid=" + Binder.getCallingUid()
13618                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13619            Slog.w(TAG, msg);
13620            throw new SecurityException(msg);
13621        }
13622        final int pid = Binder.getCallingPid();
13623        final long origId = Binder.clearCallingIdentity();
13624        try {
13625            synchronized (this) {
13626                boolean changed = false;
13627                ProcessRecord pr;
13628                synchronized (mPidsSelfLocked) {
13629                    pr = mPidsSelfLocked.get(pid);
13630                    if (pr == null) {
13631                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13632                        return;
13633                    }
13634                    if (pr.hasTopUi != hasTopUi) {
13635                        if (DEBUG_OOM_ADJ) {
13636                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13637                        }
13638                        pr.hasTopUi = hasTopUi;
13639                        changed = true;
13640                    }
13641                }
13642                if (changed) {
13643                    updateOomAdjLocked(pr, true);
13644                }
13645            }
13646        } finally {
13647            Binder.restoreCallingIdentity(origId);
13648        }
13649    }
13650
13651    public final void enterSafeMode() {
13652        synchronized(this) {
13653            // It only makes sense to do this before the system is ready
13654            // and started launching other packages.
13655            if (!mSystemReady) {
13656                try {
13657                    AppGlobals.getPackageManager().enterSafeMode();
13658                } catch (RemoteException e) {
13659                }
13660            }
13661
13662            mSafeMode = true;
13663        }
13664    }
13665
13666    public final void showSafeModeOverlay() {
13667        View v = LayoutInflater.from(mContext).inflate(
13668                com.android.internal.R.layout.safe_mode, null);
13669        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13670        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13671        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13672        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13673        lp.gravity = Gravity.BOTTOM | Gravity.START;
13674        lp.format = v.getBackground().getOpacity();
13675        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13676                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13677        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13678        ((WindowManager)mContext.getSystemService(
13679                Context.WINDOW_SERVICE)).addView(v, lp);
13680    }
13681
13682    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13683        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13684            return;
13685        }
13686        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13687        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13688        synchronized (stats) {
13689            if (mBatteryStatsService.isOnBattery()) {
13690                mBatteryStatsService.enforceCallingPermission();
13691                int MY_UID = Binder.getCallingUid();
13692                final int uid;
13693                if (sender == null) {
13694                    uid = sourceUid;
13695                } else {
13696                    uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13697                }
13698                BatteryStatsImpl.Uid.Pkg pkg =
13699                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13700                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13701                pkg.noteWakeupAlarmLocked(tag);
13702            }
13703        }
13704    }
13705
13706    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13707        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13708            return;
13709        }
13710        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13711        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13712        synchronized (stats) {
13713            mBatteryStatsService.enforceCallingPermission();
13714            int MY_UID = Binder.getCallingUid();
13715            final int uid;
13716            if (sender == null) {
13717                uid = sourceUid;
13718            } else {
13719                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13720            }
13721            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13722        }
13723    }
13724
13725    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13726        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13727            return;
13728        }
13729        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13730        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13731        synchronized (stats) {
13732            mBatteryStatsService.enforceCallingPermission();
13733            int MY_UID = Binder.getCallingUid();
13734            final int uid;
13735            if (sender == null) {
13736                uid = sourceUid;
13737            } else {
13738                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13739            }
13740            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13741        }
13742    }
13743
13744    public boolean killPids(int[] pids, String pReason, boolean secure) {
13745        if (Binder.getCallingUid() != SYSTEM_UID) {
13746            throw new SecurityException("killPids only available to the system");
13747        }
13748        String reason = (pReason == null) ? "Unknown" : pReason;
13749        // XXX Note: don't acquire main activity lock here, because the window
13750        // manager calls in with its locks held.
13751
13752        boolean killed = false;
13753        synchronized (mPidsSelfLocked) {
13754            int worstType = 0;
13755            for (int i=0; i<pids.length; i++) {
13756                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13757                if (proc != null) {
13758                    int type = proc.setAdj;
13759                    if (type > worstType) {
13760                        worstType = type;
13761                    }
13762                }
13763            }
13764
13765            // If the worst oom_adj is somewhere in the cached proc LRU range,
13766            // then constrain it so we will kill all cached procs.
13767            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13768                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13769                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13770            }
13771
13772            // If this is not a secure call, don't let it kill processes that
13773            // are important.
13774            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13775                worstType = ProcessList.SERVICE_ADJ;
13776            }
13777
13778            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13779            for (int i=0; i<pids.length; i++) {
13780                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13781                if (proc == null) {
13782                    continue;
13783                }
13784                int adj = proc.setAdj;
13785                if (adj >= worstType && !proc.killedByAm) {
13786                    proc.kill(reason, true);
13787                    killed = true;
13788                }
13789            }
13790        }
13791        return killed;
13792    }
13793
13794    @Override
13795    public void killUid(int appId, int userId, String reason) {
13796        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13797        synchronized (this) {
13798            final long identity = Binder.clearCallingIdentity();
13799            try {
13800                killPackageProcessesLocked(null, appId, userId,
13801                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13802                        reason != null ? reason : "kill uid");
13803            } finally {
13804                Binder.restoreCallingIdentity(identity);
13805            }
13806        }
13807    }
13808
13809    @Override
13810    public boolean killProcessesBelowForeground(String reason) {
13811        if (Binder.getCallingUid() != SYSTEM_UID) {
13812            throw new SecurityException("killProcessesBelowForeground() only available to system");
13813        }
13814
13815        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13816    }
13817
13818    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13819        if (Binder.getCallingUid() != SYSTEM_UID) {
13820            throw new SecurityException("killProcessesBelowAdj() only available to system");
13821        }
13822
13823        boolean killed = false;
13824        synchronized (mPidsSelfLocked) {
13825            final int size = mPidsSelfLocked.size();
13826            for (int i = 0; i < size; i++) {
13827                final int pid = mPidsSelfLocked.keyAt(i);
13828                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13829                if (proc == null) continue;
13830
13831                final int adj = proc.setAdj;
13832                if (adj > belowAdj && !proc.killedByAm) {
13833                    proc.kill(reason, true);
13834                    killed = true;
13835                }
13836            }
13837        }
13838        return killed;
13839    }
13840
13841    @Override
13842    public void hang(final IBinder who, boolean allowRestart) {
13843        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13844                != PackageManager.PERMISSION_GRANTED) {
13845            throw new SecurityException("Requires permission "
13846                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13847        }
13848
13849        final IBinder.DeathRecipient death = new DeathRecipient() {
13850            @Override
13851            public void binderDied() {
13852                synchronized (this) {
13853                    notifyAll();
13854                }
13855            }
13856        };
13857
13858        try {
13859            who.linkToDeath(death, 0);
13860        } catch (RemoteException e) {
13861            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13862            return;
13863        }
13864
13865        synchronized (this) {
13866            Watchdog.getInstance().setAllowRestart(allowRestart);
13867            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13868            synchronized (death) {
13869                while (who.isBinderAlive()) {
13870                    try {
13871                        death.wait();
13872                    } catch (InterruptedException e) {
13873                    }
13874                }
13875            }
13876            Watchdog.getInstance().setAllowRestart(true);
13877        }
13878    }
13879
13880    @Override
13881    public void restart() {
13882        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13883                != PackageManager.PERMISSION_GRANTED) {
13884            throw new SecurityException("Requires permission "
13885                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13886        }
13887
13888        Log.i(TAG, "Sending shutdown broadcast...");
13889
13890        BroadcastReceiver br = new BroadcastReceiver() {
13891            @Override public void onReceive(Context context, Intent intent) {
13892                // Now the broadcast is done, finish up the low-level shutdown.
13893                Log.i(TAG, "Shutting down activity manager...");
13894                shutdown(10000);
13895                Log.i(TAG, "Shutdown complete, restarting!");
13896                killProcess(myPid());
13897                System.exit(10);
13898            }
13899        };
13900
13901        // First send the high-level shut down broadcast.
13902        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13903        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13904        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13905        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13906        mContext.sendOrderedBroadcastAsUser(intent,
13907                UserHandle.ALL, null, br, mHandler, 0, null, null);
13908        */
13909        br.onReceive(mContext, intent);
13910    }
13911
13912    private long getLowRamTimeSinceIdle(long now) {
13913        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13914    }
13915
13916    @Override
13917    public void performIdleMaintenance() {
13918        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13919                != PackageManager.PERMISSION_GRANTED) {
13920            throw new SecurityException("Requires permission "
13921                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13922        }
13923
13924        synchronized (this) {
13925            final long now = SystemClock.uptimeMillis();
13926            final long timeSinceLastIdle = now - mLastIdleTime;
13927            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13928            mLastIdleTime = now;
13929            mLowRamTimeSinceLastIdle = 0;
13930            if (mLowRamStartTime != 0) {
13931                mLowRamStartTime = now;
13932            }
13933
13934            StringBuilder sb = new StringBuilder(128);
13935            sb.append("Idle maintenance over ");
13936            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13937            sb.append(" low RAM for ");
13938            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13939            Slog.i(TAG, sb.toString());
13940
13941            // If at least 1/3 of our time since the last idle period has been spent
13942            // with RAM low, then we want to kill processes.
13943            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13944
13945            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13946                ProcessRecord proc = mLruProcesses.get(i);
13947                if (proc.notCachedSinceIdle) {
13948                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13949                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13950                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13951                        if (doKilling && proc.initialIdlePss != 0
13952                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13953                            sb = new StringBuilder(128);
13954                            sb.append("Kill");
13955                            sb.append(proc.processName);
13956                            sb.append(" in idle maint: pss=");
13957                            sb.append(proc.lastPss);
13958                            sb.append(", swapPss=");
13959                            sb.append(proc.lastSwapPss);
13960                            sb.append(", initialPss=");
13961                            sb.append(proc.initialIdlePss);
13962                            sb.append(", period=");
13963                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13964                            sb.append(", lowRamPeriod=");
13965                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13966                            Slog.wtfQuiet(TAG, sb.toString());
13967                            proc.kill("idle maint (pss " + proc.lastPss
13968                                    + " from " + proc.initialIdlePss + ")", true);
13969                        }
13970                    }
13971                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13972                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13973                    proc.notCachedSinceIdle = true;
13974                    proc.initialIdlePss = 0;
13975                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13976                            mTestPssMode, isSleepingLocked(), now);
13977                }
13978            }
13979
13980            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13981            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13982        }
13983    }
13984
13985    @Override
13986    public void sendIdleJobTrigger() {
13987        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13988                != PackageManager.PERMISSION_GRANTED) {
13989            throw new SecurityException("Requires permission "
13990                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13991        }
13992
13993        final long ident = Binder.clearCallingIdentity();
13994        try {
13995            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13996                    .setPackage("android")
13997                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13998            broadcastIntent(null, intent, null, null, 0, null, null, null,
13999                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14000        } finally {
14001            Binder.restoreCallingIdentity(ident);
14002        }
14003    }
14004
14005    private void retrieveSettings() {
14006        final ContentResolver resolver = mContext.getContentResolver();
14007        final boolean freeformWindowManagement =
14008                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14009                        || Settings.Global.getInt(
14010                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14011        final boolean supportsPictureInPicture =
14012                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14013
14014        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14015        final boolean supportsSplitScreenMultiWindow =
14016                ActivityManager.supportsSplitScreenMultiWindow(mContext);
14017        final boolean supportsMultiDisplay = mContext.getPackageManager()
14018                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14019        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14020        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14021        final boolean alwaysFinishActivities =
14022                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14023        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14024        final boolean forceResizable = Settings.Global.getInt(
14025                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14026        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14027                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14028        final boolean supportsLeanbackOnly =
14029                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14030
14031        // Transfer any global setting for forcing RTL layout, into a System Property
14032        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14033
14034        final Configuration configuration = new Configuration();
14035        Settings.System.getConfiguration(resolver, configuration);
14036        if (forceRtl) {
14037            // This will take care of setting the correct layout direction flags
14038            configuration.setLayoutDirection(configuration.locale);
14039        }
14040
14041        synchronized (this) {
14042            mDebugApp = mOrigDebugApp = debugApp;
14043            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14044            mAlwaysFinishActivities = alwaysFinishActivities;
14045            mSupportsLeanbackOnly = supportsLeanbackOnly;
14046            mForceResizableActivities = forceResizable;
14047            final boolean multiWindowFormEnabled = freeformWindowManagement
14048                    || supportsSplitScreenMultiWindow
14049                    || supportsPictureInPicture
14050                    || supportsMultiDisplay;
14051            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14052                mSupportsMultiWindow = true;
14053                mSupportsFreeformWindowManagement = freeformWindowManagement;
14054                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14055                mSupportsPictureInPicture = supportsPictureInPicture;
14056                mSupportsMultiDisplay = supportsMultiDisplay;
14057            } else {
14058                mSupportsMultiWindow = false;
14059                mSupportsFreeformWindowManagement = false;
14060                mSupportsSplitScreenMultiWindow = false;
14061                mSupportsPictureInPicture = false;
14062                mSupportsMultiDisplay = false;
14063            }
14064            mWindowManager.setForceResizableTasks(mForceResizableActivities);
14065            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14066            // This happens before any activities are started, so we can change global configuration
14067            // in-place.
14068            updateConfigurationLocked(configuration, null, true);
14069            final Configuration globalConfig = getGlobalConfiguration();
14070            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14071
14072            // Load resources only after the current configuration has been set.
14073            final Resources res = mContext.getResources();
14074            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14075            mThumbnailWidth = res.getDimensionPixelSize(
14076                    com.android.internal.R.dimen.thumbnail_width);
14077            mThumbnailHeight = res.getDimensionPixelSize(
14078                    com.android.internal.R.dimen.thumbnail_height);
14079            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14080                    com.android.internal.R.string.config_appsNotReportingCrashes));
14081            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14082                    com.android.internal.R.bool.config_customUserSwitchUi);
14083            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14084                mFullscreenThumbnailScale = (float) res
14085                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14086                    (float) globalConfig.screenWidthDp;
14087            } else {
14088                mFullscreenThumbnailScale = res.getFraction(
14089                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14090            }
14091            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14092        }
14093    }
14094
14095    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
14096        traceLog.traceBegin("PhaseActivityManagerReady");
14097        synchronized(this) {
14098            if (mSystemReady) {
14099                // If we're done calling all the receivers, run the next "boot phase" passed in
14100                // by the SystemServer
14101                if (goingCallback != null) {
14102                    goingCallback.run();
14103                }
14104                return;
14105            }
14106
14107            mLocalDeviceIdleController
14108                    = LocalServices.getService(DeviceIdleController.LocalService.class);
14109            mAssistUtils = new AssistUtils(mContext);
14110            mVrController.onSystemReady();
14111            // Make sure we have the current profile info, since it is needed for security checks.
14112            mUserController.onSystemReady();
14113            mRecentTasks.onSystemReadyLocked();
14114            mAppOpsService.systemReady();
14115            mSystemReady = true;
14116        }
14117
14118        ArrayList<ProcessRecord> procsToKill = null;
14119        synchronized(mPidsSelfLocked) {
14120            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14121                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14122                if (!isAllowedWhileBooting(proc.info)){
14123                    if (procsToKill == null) {
14124                        procsToKill = new ArrayList<ProcessRecord>();
14125                    }
14126                    procsToKill.add(proc);
14127                }
14128            }
14129        }
14130
14131        synchronized(this) {
14132            if (procsToKill != null) {
14133                for (int i=procsToKill.size()-1; i>=0; i--) {
14134                    ProcessRecord proc = procsToKill.get(i);
14135                    Slog.i(TAG, "Removing system update proc: " + proc);
14136                    removeProcessLocked(proc, true, false, "system update done");
14137                }
14138            }
14139
14140            // Now that we have cleaned up any update processes, we
14141            // are ready to start launching real processes and know that
14142            // we won't trample on them any more.
14143            mProcessesReady = true;
14144        }
14145
14146        Slog.i(TAG, "System now ready");
14147        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14148            SystemClock.uptimeMillis());
14149
14150        synchronized(this) {
14151            // Make sure we have no pre-ready processes sitting around.
14152
14153            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14154                ResolveInfo ri = mContext.getPackageManager()
14155                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14156                                STOCK_PM_FLAGS);
14157                CharSequence errorMsg = null;
14158                if (ri != null) {
14159                    ActivityInfo ai = ri.activityInfo;
14160                    ApplicationInfo app = ai.applicationInfo;
14161                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14162                        mTopAction = Intent.ACTION_FACTORY_TEST;
14163                        mTopData = null;
14164                        mTopComponent = new ComponentName(app.packageName,
14165                                ai.name);
14166                    } else {
14167                        errorMsg = mContext.getResources().getText(
14168                                com.android.internal.R.string.factorytest_not_system);
14169                    }
14170                } else {
14171                    errorMsg = mContext.getResources().getText(
14172                            com.android.internal.R.string.factorytest_no_action);
14173                }
14174                if (errorMsg != null) {
14175                    mTopAction = null;
14176                    mTopData = null;
14177                    mTopComponent = null;
14178                    Message msg = Message.obtain();
14179                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14180                    msg.getData().putCharSequence("msg", errorMsg);
14181                    mUiHandler.sendMessage(msg);
14182                }
14183            }
14184        }
14185
14186        retrieveSettings();
14187        final int currentUserId;
14188        synchronized (this) {
14189            currentUserId = mUserController.getCurrentUserIdLocked();
14190            readGrantedUriPermissionsLocked();
14191        }
14192
14193        if (goingCallback != null) goingCallback.run();
14194        traceLog.traceBegin("ActivityManagerStartApps");
14195        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14196                Integer.toString(currentUserId), currentUserId);
14197        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14198                Integer.toString(currentUserId), currentUserId);
14199        mSystemServiceManager.startUser(currentUserId);
14200
14201        synchronized (this) {
14202            // Only start up encryption-aware persistent apps; once user is
14203            // unlocked we'll come back around and start unaware apps
14204            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14205
14206            // Start up initial activity.
14207            mBooting = true;
14208            // Enable home activity for system user, so that the system can always boot. We don't
14209            // do this when the system user is not setup since the setup wizard should be the one
14210            // to handle home activity in this case.
14211            if (UserManager.isSplitSystemUser() &&
14212                    Settings.Secure.getInt(mContext.getContentResolver(),
14213                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14214                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14215                try {
14216                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14217                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14218                            UserHandle.USER_SYSTEM);
14219                } catch (RemoteException e) {
14220                    throw e.rethrowAsRuntimeException();
14221                }
14222            }
14223            startHomeActivityLocked(currentUserId, "systemReady");
14224
14225            try {
14226                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14227                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14228                            + " data partition or your device will be unstable.");
14229                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14230                }
14231            } catch (RemoteException e) {
14232            }
14233
14234            if (!Build.isBuildConsistent()) {
14235                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14236                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14237            }
14238
14239            long ident = Binder.clearCallingIdentity();
14240            try {
14241                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14242                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14243                        | Intent.FLAG_RECEIVER_FOREGROUND);
14244                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14245                broadcastIntentLocked(null, null, intent,
14246                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14247                        null, false, false, MY_PID, SYSTEM_UID,
14248                        currentUserId);
14249                intent = new Intent(Intent.ACTION_USER_STARTING);
14250                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14251                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14252                broadcastIntentLocked(null, null, intent,
14253                        null, new IIntentReceiver.Stub() {
14254                            @Override
14255                            public void performReceive(Intent intent, int resultCode, String data,
14256                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14257                                    throws RemoteException {
14258                            }
14259                        }, 0, null, null,
14260                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14261                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14262            } catch (Throwable t) {
14263                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14264            } finally {
14265                Binder.restoreCallingIdentity(ident);
14266            }
14267            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14268            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14269            traceLog.traceEnd(); // ActivityManagerStartApps
14270            traceLog.traceEnd(); // PhaseActivityManagerReady
14271        }
14272    }
14273
14274    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14275        synchronized (this) {
14276            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14277        }
14278    }
14279
14280    void skipCurrentReceiverLocked(ProcessRecord app) {
14281        for (BroadcastQueue queue : mBroadcastQueues) {
14282            queue.skipCurrentReceiverLocked(app);
14283        }
14284    }
14285
14286    /**
14287     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14288     * The application process will exit immediately after this call returns.
14289     * @param app object of the crashing app, null for the system server
14290     * @param crashInfo describing the exception
14291     */
14292    public void handleApplicationCrash(IBinder app,
14293            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14294        ProcessRecord r = findAppProcess(app, "Crash");
14295        final String processName = app == null ? "system_server"
14296                : (r == null ? "unknown" : r.processName);
14297
14298        handleApplicationCrashInner("crash", r, processName, crashInfo);
14299    }
14300
14301    /* Native crash reporting uses this inner version because it needs to be somewhat
14302     * decoupled from the AM-managed cleanup lifecycle
14303     */
14304    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14305            ApplicationErrorReport.CrashInfo crashInfo) {
14306        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14307                UserHandle.getUserId(Binder.getCallingUid()), processName,
14308                r == null ? -1 : r.info.flags,
14309                crashInfo.exceptionClassName,
14310                crashInfo.exceptionMessage,
14311                crashInfo.throwFileName,
14312                crashInfo.throwLineNumber);
14313
14314        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14315
14316        mAppErrors.crashApplication(r, crashInfo);
14317    }
14318
14319    public void handleApplicationStrictModeViolation(
14320            IBinder app,
14321            int violationMask,
14322            StrictMode.ViolationInfo info) {
14323        ProcessRecord r = findAppProcess(app, "StrictMode");
14324        if (r == null) {
14325            return;
14326        }
14327
14328        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14329            Integer stackFingerprint = info.hashCode();
14330            boolean logIt = true;
14331            synchronized (mAlreadyLoggedViolatedStacks) {
14332                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14333                    logIt = false;
14334                    // TODO: sub-sample into EventLog for these, with
14335                    // the info.durationMillis?  Then we'd get
14336                    // the relative pain numbers, without logging all
14337                    // the stack traces repeatedly.  We'd want to do
14338                    // likewise in the client code, which also does
14339                    // dup suppression, before the Binder call.
14340                } else {
14341                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14342                        mAlreadyLoggedViolatedStacks.clear();
14343                    }
14344                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14345                }
14346            }
14347            if (logIt) {
14348                logStrictModeViolationToDropBox(r, info);
14349            }
14350        }
14351
14352        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14353            AppErrorResult result = new AppErrorResult();
14354            synchronized (this) {
14355                final long origId = Binder.clearCallingIdentity();
14356
14357                Message msg = Message.obtain();
14358                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14359                HashMap<String, Object> data = new HashMap<String, Object>();
14360                data.put("result", result);
14361                data.put("app", r);
14362                data.put("violationMask", violationMask);
14363                data.put("info", info);
14364                msg.obj = data;
14365                mUiHandler.sendMessage(msg);
14366
14367                Binder.restoreCallingIdentity(origId);
14368            }
14369            int res = result.get();
14370            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14371        }
14372    }
14373
14374    // Depending on the policy in effect, there could be a bunch of
14375    // these in quick succession so we try to batch these together to
14376    // minimize disk writes, number of dropbox entries, and maximize
14377    // compression, by having more fewer, larger records.
14378    private void logStrictModeViolationToDropBox(
14379            ProcessRecord process,
14380            StrictMode.ViolationInfo info) {
14381        if (info == null) {
14382            return;
14383        }
14384        final boolean isSystemApp = process == null ||
14385                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14386                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14387        final String processName = process == null ? "unknown" : process.processName;
14388        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14389        final DropBoxManager dbox = (DropBoxManager)
14390                mContext.getSystemService(Context.DROPBOX_SERVICE);
14391
14392        // Exit early if the dropbox isn't configured to accept this report type.
14393        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14394
14395        boolean bufferWasEmpty;
14396        boolean needsFlush;
14397        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14398        synchronized (sb) {
14399            bufferWasEmpty = sb.length() == 0;
14400            appendDropBoxProcessHeaders(process, processName, sb);
14401            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14402            sb.append("System-App: ").append(isSystemApp).append("\n");
14403            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14404            if (info.violationNumThisLoop != 0) {
14405                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14406            }
14407            if (info.numAnimationsRunning != 0) {
14408                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14409            }
14410            if (info.broadcastIntentAction != null) {
14411                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14412            }
14413            if (info.durationMillis != -1) {
14414                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14415            }
14416            if (info.numInstances != -1) {
14417                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14418            }
14419            if (info.tags != null) {
14420                for (String tag : info.tags) {
14421                    sb.append("Span-Tag: ").append(tag).append("\n");
14422                }
14423            }
14424            sb.append("\n");
14425            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14426                sb.append(info.crashInfo.stackTrace);
14427                sb.append("\n");
14428            }
14429            if (info.message != null) {
14430                sb.append(info.message);
14431                sb.append("\n");
14432            }
14433
14434            // Only buffer up to ~64k.  Various logging bits truncate
14435            // things at 128k.
14436            needsFlush = (sb.length() > 64 * 1024);
14437        }
14438
14439        // Flush immediately if the buffer's grown too large, or this
14440        // is a non-system app.  Non-system apps are isolated with a
14441        // different tag & policy and not batched.
14442        //
14443        // Batching is useful during internal testing with
14444        // StrictMode settings turned up high.  Without batching,
14445        // thousands of separate files could be created on boot.
14446        if (!isSystemApp || needsFlush) {
14447            new Thread("Error dump: " + dropboxTag) {
14448                @Override
14449                public void run() {
14450                    String report;
14451                    synchronized (sb) {
14452                        report = sb.toString();
14453                        sb.delete(0, sb.length());
14454                        sb.trimToSize();
14455                    }
14456                    if (report.length() != 0) {
14457                        dbox.addText(dropboxTag, report);
14458                    }
14459                }
14460            }.start();
14461            return;
14462        }
14463
14464        // System app batching:
14465        if (!bufferWasEmpty) {
14466            // An existing dropbox-writing thread is outstanding, so
14467            // we don't need to start it up.  The existing thread will
14468            // catch the buffer appends we just did.
14469            return;
14470        }
14471
14472        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14473        // (After this point, we shouldn't access AMS internal data structures.)
14474        new Thread("Error dump: " + dropboxTag) {
14475            @Override
14476            public void run() {
14477                // 5 second sleep to let stacks arrive and be batched together
14478                try {
14479                    Thread.sleep(5000);  // 5 seconds
14480                } catch (InterruptedException e) {}
14481
14482                String errorReport;
14483                synchronized (mStrictModeBuffer) {
14484                    errorReport = mStrictModeBuffer.toString();
14485                    if (errorReport.length() == 0) {
14486                        return;
14487                    }
14488                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14489                    mStrictModeBuffer.trimToSize();
14490                }
14491                dbox.addText(dropboxTag, errorReport);
14492            }
14493        }.start();
14494    }
14495
14496    /**
14497     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14498     * @param app object of the crashing app, null for the system server
14499     * @param tag reported by the caller
14500     * @param system whether this wtf is coming from the system
14501     * @param crashInfo describing the context of the error
14502     * @return true if the process should exit immediately (WTF is fatal)
14503     */
14504    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14505            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14506        final int callingUid = Binder.getCallingUid();
14507        final int callingPid = Binder.getCallingPid();
14508
14509        if (system) {
14510            // If this is coming from the system, we could very well have low-level
14511            // system locks held, so we want to do this all asynchronously.  And we
14512            // never want this to become fatal, so there is that too.
14513            mHandler.post(new Runnable() {
14514                @Override public void run() {
14515                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14516                }
14517            });
14518            return false;
14519        }
14520
14521        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14522                crashInfo);
14523
14524        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14525                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14526        final boolean isSystem = (r == null) || r.persistent;
14527
14528        if (isFatal && !isSystem) {
14529            mAppErrors.crashApplication(r, crashInfo);
14530            return true;
14531        } else {
14532            return false;
14533        }
14534    }
14535
14536    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14537            final ApplicationErrorReport.CrashInfo crashInfo) {
14538        final ProcessRecord r = findAppProcess(app, "WTF");
14539        final String processName = app == null ? "system_server"
14540                : (r == null ? "unknown" : r.processName);
14541
14542        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14543                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14544
14545        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14546
14547        return r;
14548    }
14549
14550    /**
14551     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14552     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14553     */
14554    private ProcessRecord findAppProcess(IBinder app, String reason) {
14555        if (app == null) {
14556            return null;
14557        }
14558
14559        synchronized (this) {
14560            final int NP = mProcessNames.getMap().size();
14561            for (int ip=0; ip<NP; ip++) {
14562                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14563                final int NA = apps.size();
14564                for (int ia=0; ia<NA; ia++) {
14565                    ProcessRecord p = apps.valueAt(ia);
14566                    if (p.thread != null && p.thread.asBinder() == app) {
14567                        return p;
14568                    }
14569                }
14570            }
14571
14572            Slog.w(TAG, "Can't find mystery application for " + reason
14573                    + " from pid=" + Binder.getCallingPid()
14574                    + " uid=" + Binder.getCallingUid() + ": " + app);
14575            return null;
14576        }
14577    }
14578
14579    /**
14580     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14581     * to append various headers to the dropbox log text.
14582     */
14583    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14584            StringBuilder sb) {
14585        // Watchdog thread ends up invoking this function (with
14586        // a null ProcessRecord) to add the stack file to dropbox.
14587        // Do not acquire a lock on this (am) in such cases, as it
14588        // could cause a potential deadlock, if and when watchdog
14589        // is invoked due to unavailability of lock on am and it
14590        // would prevent watchdog from killing system_server.
14591        if (process == null) {
14592            sb.append("Process: ").append(processName).append("\n");
14593            return;
14594        }
14595        // Note: ProcessRecord 'process' is guarded by the service
14596        // instance.  (notably process.pkgList, which could otherwise change
14597        // concurrently during execution of this method)
14598        synchronized (this) {
14599            sb.append("Process: ").append(processName).append("\n");
14600            sb.append("PID: ").append(process.pid).append("\n");
14601            int flags = process.info.flags;
14602            IPackageManager pm = AppGlobals.getPackageManager();
14603            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14604            for (int ip=0; ip<process.pkgList.size(); ip++) {
14605                String pkg = process.pkgList.keyAt(ip);
14606                sb.append("Package: ").append(pkg);
14607                try {
14608                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14609                    if (pi != null) {
14610                        sb.append(" v").append(pi.versionCode);
14611                        if (pi.versionName != null) {
14612                            sb.append(" (").append(pi.versionName).append(")");
14613                        }
14614                    }
14615                } catch (RemoteException e) {
14616                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14617                }
14618                sb.append("\n");
14619            }
14620        }
14621    }
14622
14623    private static String processClass(ProcessRecord process) {
14624        if (process == null || process.pid == MY_PID) {
14625            return "system_server";
14626        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14627            return "system_app";
14628        } else {
14629            return "data_app";
14630        }
14631    }
14632
14633    private volatile long mWtfClusterStart;
14634    private volatile int mWtfClusterCount;
14635
14636    /**
14637     * Write a description of an error (crash, WTF, ANR) to the drop box.
14638     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14639     * @param process which caused the error, null means the system server
14640     * @param activity which triggered the error, null if unknown
14641     * @param parent activity related to the error, null if unknown
14642     * @param subject line related to the error, null if absent
14643     * @param report in long form describing the error, null if absent
14644     * @param dataFile text file to include in the report, null if none
14645     * @param crashInfo giving an application stack trace, null if absent
14646     */
14647    public void addErrorToDropBox(String eventType,
14648            ProcessRecord process, String processName, ActivityRecord activity,
14649            ActivityRecord parent, String subject,
14650            final String report, final File dataFile,
14651            final ApplicationErrorReport.CrashInfo crashInfo) {
14652        // NOTE -- this must never acquire the ActivityManagerService lock,
14653        // otherwise the watchdog may be prevented from resetting the system.
14654
14655        // Bail early if not published yet
14656        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14657        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14658
14659        // Exit early if the dropbox isn't configured to accept this report type.
14660        final String dropboxTag = processClass(process) + "_" + eventType;
14661        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14662
14663        // Rate-limit how often we're willing to do the heavy lifting below to
14664        // collect and record logs; currently 5 logs per 10 second period.
14665        final long now = SystemClock.elapsedRealtime();
14666        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14667            mWtfClusterStart = now;
14668            mWtfClusterCount = 1;
14669        } else {
14670            if (mWtfClusterCount++ >= 5) return;
14671        }
14672
14673        final StringBuilder sb = new StringBuilder(1024);
14674        appendDropBoxProcessHeaders(process, processName, sb);
14675        if (process != null) {
14676            sb.append("Foreground: ")
14677                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14678                    .append("\n");
14679        }
14680        if (activity != null) {
14681            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14682        }
14683        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14684            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14685        }
14686        if (parent != null && parent != activity) {
14687            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14688        }
14689        if (subject != null) {
14690            sb.append("Subject: ").append(subject).append("\n");
14691        }
14692        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14693        if (Debug.isDebuggerConnected()) {
14694            sb.append("Debugger: Connected\n");
14695        }
14696        sb.append("\n");
14697
14698        // Do the rest in a worker thread to avoid blocking the caller on I/O
14699        // (After this point, we shouldn't access AMS internal data structures.)
14700        Thread worker = new Thread("Error dump: " + dropboxTag) {
14701            @Override
14702            public void run() {
14703                if (report != null) {
14704                    sb.append(report);
14705                }
14706
14707                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14708                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14709                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14710                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14711
14712                if (dataFile != null && maxDataFileSize > 0) {
14713                    try {
14714                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14715                                    "\n\n[[TRUNCATED]]"));
14716                    } catch (IOException e) {
14717                        Slog.e(TAG, "Error reading " + dataFile, e);
14718                    }
14719                }
14720                if (crashInfo != null && crashInfo.stackTrace != null) {
14721                    sb.append(crashInfo.stackTrace);
14722                }
14723
14724                if (lines > 0) {
14725                    sb.append("\n");
14726
14727                    // Merge several logcat streams, and take the last N lines
14728                    InputStreamReader input = null;
14729                    try {
14730                        java.lang.Process logcat = new ProcessBuilder(
14731                                "/system/bin/timeout", "-k", "15s", "10s",
14732                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14733                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14734                                        .redirectErrorStream(true).start();
14735
14736                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14737                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14738                        input = new InputStreamReader(logcat.getInputStream());
14739
14740                        int num;
14741                        char[] buf = new char[8192];
14742                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14743                    } catch (IOException e) {
14744                        Slog.e(TAG, "Error running logcat", e);
14745                    } finally {
14746                        if (input != null) try { input.close(); } catch (IOException e) {}
14747                    }
14748                }
14749
14750                dbox.addText(dropboxTag, sb.toString());
14751            }
14752        };
14753
14754        if (process == null) {
14755            // If process is null, we are being called from some internal code
14756            // and may be about to die -- run this synchronously.
14757            worker.run();
14758        } else {
14759            worker.start();
14760        }
14761    }
14762
14763    @Override
14764    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14765        enforceNotIsolatedCaller("getProcessesInErrorState");
14766        // assume our apps are happy - lazy create the list
14767        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14768
14769        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14770                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14771        int userId = UserHandle.getUserId(Binder.getCallingUid());
14772
14773        synchronized (this) {
14774
14775            // iterate across all processes
14776            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14777                ProcessRecord app = mLruProcesses.get(i);
14778                if (!allUsers && app.userId != userId) {
14779                    continue;
14780                }
14781                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14782                    // This one's in trouble, so we'll generate a report for it
14783                    // crashes are higher priority (in case there's a crash *and* an anr)
14784                    ActivityManager.ProcessErrorStateInfo report = null;
14785                    if (app.crashing) {
14786                        report = app.crashingReport;
14787                    } else if (app.notResponding) {
14788                        report = app.notRespondingReport;
14789                    }
14790
14791                    if (report != null) {
14792                        if (errList == null) {
14793                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14794                        }
14795                        errList.add(report);
14796                    } else {
14797                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14798                                " crashing = " + app.crashing +
14799                                " notResponding = " + app.notResponding);
14800                    }
14801                }
14802            }
14803        }
14804
14805        return errList;
14806    }
14807
14808    static int procStateToImportance(int procState, int memAdj,
14809            ActivityManager.RunningAppProcessInfo currApp,
14810            int clientTargetSdk) {
14811        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14812                procState, clientTargetSdk);
14813        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14814            currApp.lru = memAdj;
14815        } else {
14816            currApp.lru = 0;
14817        }
14818        return imp;
14819    }
14820
14821    private void fillInProcMemInfo(ProcessRecord app,
14822            ActivityManager.RunningAppProcessInfo outInfo,
14823            int clientTargetSdk) {
14824        outInfo.pid = app.pid;
14825        outInfo.uid = app.info.uid;
14826        if (mHeavyWeightProcess == app) {
14827            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14828        }
14829        if (app.persistent) {
14830            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14831        }
14832        if (app.activities.size() > 0) {
14833            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14834        }
14835        outInfo.lastTrimLevel = app.trimMemoryLevel;
14836        int adj = app.curAdj;
14837        int procState = app.curProcState;
14838        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14839        outInfo.importanceReasonCode = app.adjTypeCode;
14840        outInfo.processState = app.curProcState;
14841    }
14842
14843    @Override
14844    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14845        enforceNotIsolatedCaller("getRunningAppProcesses");
14846
14847        final int callingUid = Binder.getCallingUid();
14848        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14849
14850        // Lazy instantiation of list
14851        List<ActivityManager.RunningAppProcessInfo> runList = null;
14852        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14853                callingUid) == PackageManager.PERMISSION_GRANTED;
14854        final int userId = UserHandle.getUserId(callingUid);
14855        final boolean allUids = isGetTasksAllowed(
14856                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14857
14858        synchronized (this) {
14859            // Iterate across all processes
14860            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14861                ProcessRecord app = mLruProcesses.get(i);
14862                if ((!allUsers && app.userId != userId)
14863                        || (!allUids && app.uid != callingUid)) {
14864                    continue;
14865                }
14866                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14867                    // Generate process state info for running application
14868                    ActivityManager.RunningAppProcessInfo currApp =
14869                        new ActivityManager.RunningAppProcessInfo(app.processName,
14870                                app.pid, app.getPackageList());
14871                    fillInProcMemInfo(app, currApp, clientTargetSdk);
14872                    if (app.adjSource instanceof ProcessRecord) {
14873                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14874                        currApp.importanceReasonImportance =
14875                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14876                                        app.adjSourceProcState);
14877                    } else if (app.adjSource instanceof ActivityRecord) {
14878                        ActivityRecord r = (ActivityRecord)app.adjSource;
14879                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14880                    }
14881                    if (app.adjTarget instanceof ComponentName) {
14882                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14883                    }
14884                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14885                    //        + " lru=" + currApp.lru);
14886                    if (runList == null) {
14887                        runList = new ArrayList<>();
14888                    }
14889                    runList.add(currApp);
14890                }
14891            }
14892        }
14893        return runList;
14894    }
14895
14896    @Override
14897    public List<ApplicationInfo> getRunningExternalApplications() {
14898        enforceNotIsolatedCaller("getRunningExternalApplications");
14899        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14900        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14901        if (runningApps != null && runningApps.size() > 0) {
14902            Set<String> extList = new HashSet<String>();
14903            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14904                if (app.pkgList != null) {
14905                    for (String pkg : app.pkgList) {
14906                        extList.add(pkg);
14907                    }
14908                }
14909            }
14910            IPackageManager pm = AppGlobals.getPackageManager();
14911            for (String pkg : extList) {
14912                try {
14913                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14914                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14915                        retList.add(info);
14916                    }
14917                } catch (RemoteException e) {
14918                }
14919            }
14920        }
14921        return retList;
14922    }
14923
14924    @Override
14925    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14926        enforceNotIsolatedCaller("getMyMemoryState");
14927
14928        final int callingUid = Binder.getCallingUid();
14929        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14930
14931        synchronized (this) {
14932            ProcessRecord proc;
14933            synchronized (mPidsSelfLocked) {
14934                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14935            }
14936            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14937        }
14938    }
14939
14940    @Override
14941    public int getMemoryTrimLevel() {
14942        enforceNotIsolatedCaller("getMyMemoryState");
14943        synchronized (this) {
14944            return mLastMemoryLevel;
14945        }
14946    }
14947
14948    @Override
14949    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14950            FileDescriptor err, String[] args, ShellCallback callback,
14951            ResultReceiver resultReceiver) {
14952        (new ActivityManagerShellCommand(this, false)).exec(
14953                this, in, out, err, args, callback, resultReceiver);
14954    }
14955
14956    @Override
14957    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14958        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14959
14960        boolean dumpAll = false;
14961        boolean dumpClient = false;
14962        boolean dumpCheckin = false;
14963        boolean dumpCheckinFormat = false;
14964        boolean dumpVisibleStacksOnly = false;
14965        boolean dumpFocusedStackOnly = false;
14966        String dumpPackage = null;
14967
14968        int opti = 0;
14969        while (opti < args.length) {
14970            String opt = args[opti];
14971            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14972                break;
14973            }
14974            opti++;
14975            if ("-a".equals(opt)) {
14976                dumpAll = true;
14977            } else if ("-c".equals(opt)) {
14978                dumpClient = true;
14979            } else if ("-v".equals(opt)) {
14980                dumpVisibleStacksOnly = true;
14981            } else if ("-f".equals(opt)) {
14982                dumpFocusedStackOnly = true;
14983            } else if ("-p".equals(opt)) {
14984                if (opti < args.length) {
14985                    dumpPackage = args[opti];
14986                    opti++;
14987                } else {
14988                    pw.println("Error: -p option requires package argument");
14989                    return;
14990                }
14991                dumpClient = true;
14992            } else if ("--checkin".equals(opt)) {
14993                dumpCheckin = dumpCheckinFormat = true;
14994            } else if ("-C".equals(opt)) {
14995                dumpCheckinFormat = true;
14996            } else if ("-h".equals(opt)) {
14997                ActivityManagerShellCommand.dumpHelp(pw, true);
14998                return;
14999            } else {
15000                pw.println("Unknown argument: " + opt + "; use -h for help");
15001            }
15002        }
15003
15004        long origId = Binder.clearCallingIdentity();
15005        boolean more = false;
15006        // Is the caller requesting to dump a particular piece of data?
15007        if (opti < args.length) {
15008            String cmd = args[opti];
15009            opti++;
15010            if ("activities".equals(cmd) || "a".equals(cmd)) {
15011                synchronized (this) {
15012                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15013                }
15014            } else if ("lastanr".equals(cmd)) {
15015                synchronized (this) {
15016                    dumpLastANRLocked(pw);
15017                }
15018            } else if ("starter".equals(cmd)) {
15019                synchronized (this) {
15020                    dumpActivityStarterLocked(pw);
15021                }
15022            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15023                synchronized (this) {
15024                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15025                }
15026            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15027                String[] newArgs;
15028                String name;
15029                if (opti >= args.length) {
15030                    name = null;
15031                    newArgs = EMPTY_STRING_ARRAY;
15032                } else {
15033                    dumpPackage = args[opti];
15034                    opti++;
15035                    newArgs = new String[args.length - opti];
15036                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15037                            args.length - opti);
15038                }
15039                synchronized (this) {
15040                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15041                }
15042            } else if ("broadcast-stats".equals(cmd)) {
15043                String[] newArgs;
15044                String name;
15045                if (opti >= args.length) {
15046                    name = null;
15047                    newArgs = EMPTY_STRING_ARRAY;
15048                } else {
15049                    dumpPackage = args[opti];
15050                    opti++;
15051                    newArgs = new String[args.length - opti];
15052                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15053                            args.length - opti);
15054                }
15055                synchronized (this) {
15056                    if (dumpCheckinFormat) {
15057                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15058                                dumpPackage);
15059                    } else {
15060                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15061                    }
15062                }
15063            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15064                String[] newArgs;
15065                String name;
15066                if (opti >= args.length) {
15067                    name = null;
15068                    newArgs = EMPTY_STRING_ARRAY;
15069                } else {
15070                    dumpPackage = args[opti];
15071                    opti++;
15072                    newArgs = new String[args.length - opti];
15073                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15074                            args.length - opti);
15075                }
15076                synchronized (this) {
15077                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15078                }
15079            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15080                String[] newArgs;
15081                String name;
15082                if (opti >= args.length) {
15083                    name = null;
15084                    newArgs = EMPTY_STRING_ARRAY;
15085                } else {
15086                    dumpPackage = args[opti];
15087                    opti++;
15088                    newArgs = new String[args.length - opti];
15089                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15090                            args.length - opti);
15091                }
15092                synchronized (this) {
15093                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15094                }
15095            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15096                synchronized (this) {
15097                    dumpOomLocked(fd, pw, args, opti, true);
15098                }
15099            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15100                synchronized (this) {
15101                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15102                }
15103            } else if ("provider".equals(cmd)) {
15104                String[] newArgs;
15105                String name;
15106                if (opti >= args.length) {
15107                    name = null;
15108                    newArgs = EMPTY_STRING_ARRAY;
15109                } else {
15110                    name = args[opti];
15111                    opti++;
15112                    newArgs = new String[args.length - opti];
15113                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15114                }
15115                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15116                    pw.println("No providers match: " + name);
15117                    pw.println("Use -h for help.");
15118                }
15119            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15120                synchronized (this) {
15121                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15122                }
15123            } else if ("service".equals(cmd)) {
15124                String[] newArgs;
15125                String name;
15126                if (opti >= args.length) {
15127                    name = null;
15128                    newArgs = EMPTY_STRING_ARRAY;
15129                } else {
15130                    name = args[opti];
15131                    opti++;
15132                    newArgs = new String[args.length - opti];
15133                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15134                            args.length - opti);
15135                }
15136                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15137                    pw.println("No services match: " + name);
15138                    pw.println("Use -h for help.");
15139                }
15140            } else if ("package".equals(cmd)) {
15141                String[] newArgs;
15142                if (opti >= args.length) {
15143                    pw.println("package: no package name specified");
15144                    pw.println("Use -h for help.");
15145                } else {
15146                    dumpPackage = args[opti];
15147                    opti++;
15148                    newArgs = new String[args.length - opti];
15149                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15150                            args.length - opti);
15151                    args = newArgs;
15152                    opti = 0;
15153                    more = true;
15154                }
15155            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15156                synchronized (this) {
15157                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15158                }
15159            } else if ("settings".equals(cmd)) {
15160                synchronized (this) {
15161                    mConstants.dump(pw);
15162                }
15163            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15164                if (dumpClient) {
15165                    ActiveServices.ServiceDumper dumper;
15166                    synchronized (this) {
15167                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15168                                dumpPackage);
15169                    }
15170                    dumper.dumpWithClient();
15171                } else {
15172                    synchronized (this) {
15173                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15174                                dumpPackage).dumpLocked();
15175                    }
15176                }
15177            } else if ("locks".equals(cmd)) {
15178                LockGuard.dump(fd, pw, args);
15179            } else {
15180                // Dumping a single activity?
15181                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15182                        dumpFocusedStackOnly)) {
15183                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15184                    int res = shell.exec(this, null, fd, null, args, null,
15185                            new ResultReceiver(null));
15186                    if (res < 0) {
15187                        pw.println("Bad activity command, or no activities match: " + cmd);
15188                        pw.println("Use -h for help.");
15189                    }
15190                }
15191            }
15192            if (!more) {
15193                Binder.restoreCallingIdentity(origId);
15194                return;
15195            }
15196        }
15197
15198        // No piece of data specified, dump everything.
15199        if (dumpCheckinFormat) {
15200            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15201        } else if (dumpClient) {
15202            ActiveServices.ServiceDumper sdumper;
15203            synchronized (this) {
15204                mConstants.dump(pw);
15205                pw.println();
15206                if (dumpAll) {
15207                    pw.println("-------------------------------------------------------------------------------");
15208                }
15209                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15210                pw.println();
15211                if (dumpAll) {
15212                    pw.println("-------------------------------------------------------------------------------");
15213                }
15214                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15215                pw.println();
15216                if (dumpAll) {
15217                    pw.println("-------------------------------------------------------------------------------");
15218                }
15219                if (dumpAll || dumpPackage != null) {
15220                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15221                    pw.println();
15222                    if (dumpAll) {
15223                        pw.println("-------------------------------------------------------------------------------");
15224                    }
15225                }
15226                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15227                pw.println();
15228                if (dumpAll) {
15229                    pw.println("-------------------------------------------------------------------------------");
15230                }
15231                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15232                pw.println();
15233                if (dumpAll) {
15234                    pw.println("-------------------------------------------------------------------------------");
15235                }
15236                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15237                        dumpPackage);
15238            }
15239            sdumper.dumpWithClient();
15240            pw.println();
15241            synchronized (this) {
15242                if (dumpAll) {
15243                    pw.println("-------------------------------------------------------------------------------");
15244                }
15245                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15246                pw.println();
15247                if (dumpAll) {
15248                    pw.println("-------------------------------------------------------------------------------");
15249                }
15250                dumpLastANRLocked(pw);
15251                pw.println();
15252                if (dumpAll) {
15253                    pw.println("-------------------------------------------------------------------------------");
15254                }
15255                dumpActivityStarterLocked(pw);
15256                pw.println();
15257                if (dumpAll) {
15258                    pw.println("-------------------------------------------------------------------------------");
15259                }
15260                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15261                if (mAssociations.size() > 0) {
15262                    pw.println();
15263                    if (dumpAll) {
15264                        pw.println("-------------------------------------------------------------------------------");
15265                    }
15266                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15267                }
15268                pw.println();
15269                if (dumpAll) {
15270                    pw.println("-------------------------------------------------------------------------------");
15271                }
15272                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15273            }
15274
15275        } else {
15276            synchronized (this) {
15277                mConstants.dump(pw);
15278                pw.println();
15279                if (dumpAll) {
15280                    pw.println("-------------------------------------------------------------------------------");
15281                }
15282                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15283                pw.println();
15284                if (dumpAll) {
15285                    pw.println("-------------------------------------------------------------------------------");
15286                }
15287                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15288                pw.println();
15289                if (dumpAll) {
15290                    pw.println("-------------------------------------------------------------------------------");
15291                }
15292                if (dumpAll || dumpPackage != null) {
15293                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15294                    pw.println();
15295                    if (dumpAll) {
15296                        pw.println("-------------------------------------------------------------------------------");
15297                    }
15298                }
15299                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15300                pw.println();
15301                if (dumpAll) {
15302                    pw.println("-------------------------------------------------------------------------------");
15303                }
15304                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15305                pw.println();
15306                if (dumpAll) {
15307                    pw.println("-------------------------------------------------------------------------------");
15308                }
15309                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15310                        .dumpLocked();
15311                pw.println();
15312                if (dumpAll) {
15313                    pw.println("-------------------------------------------------------------------------------");
15314                }
15315                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15316                pw.println();
15317                if (dumpAll) {
15318                    pw.println("-------------------------------------------------------------------------------");
15319                }
15320                dumpLastANRLocked(pw);
15321                pw.println();
15322                if (dumpAll) {
15323                    pw.println("-------------------------------------------------------------------------------");
15324                }
15325                dumpActivityStarterLocked(pw);
15326                pw.println();
15327                if (dumpAll) {
15328                    pw.println("-------------------------------------------------------------------------------");
15329                }
15330                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15331                if (mAssociations.size() > 0) {
15332                    pw.println();
15333                    if (dumpAll) {
15334                        pw.println("-------------------------------------------------------------------------------");
15335                    }
15336                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15337                }
15338                pw.println();
15339                if (dumpAll) {
15340                    pw.println("-------------------------------------------------------------------------------");
15341                }
15342                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15343            }
15344        }
15345        Binder.restoreCallingIdentity(origId);
15346    }
15347
15348    private void dumpLastANRLocked(PrintWriter pw) {
15349        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)");
15350        if (mLastANRState == null) {
15351            pw.println("  <no ANR has occurred since boot>");
15352        } else {
15353            pw.println(mLastANRState);
15354        }
15355    }
15356
15357    private void dumpActivityStarterLocked(PrintWriter pw) {
15358        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)");
15359        mActivityStarter.dump(pw, "");
15360    }
15361
15362    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15363            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15364        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15365                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15366    }
15367
15368    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15369            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15370        pw.println(header);
15371
15372        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15373                dumpPackage);
15374        boolean needSep = printedAnything;
15375
15376        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15377                mStackSupervisor.getResumedActivityLocked(),
15378                dumpPackage, needSep, "  ResumedActivity: ");
15379        if (printed) {
15380            printedAnything = true;
15381            needSep = false;
15382        }
15383
15384        if (dumpPackage == null) {
15385            if (needSep) {
15386                pw.println();
15387            }
15388            printedAnything = true;
15389            mStackSupervisor.dump(pw, "  ");
15390        }
15391
15392        if (!printedAnything) {
15393            pw.println("  (nothing)");
15394        }
15395    }
15396
15397    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15398            int opti, boolean dumpAll, String dumpPackage) {
15399        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15400
15401        boolean printedAnything = false;
15402
15403        if (mRecentTasks != null && mRecentTasks.size() > 0) {
15404            boolean printedHeader = false;
15405
15406            final int N = mRecentTasks.size();
15407            for (int i=0; i<N; i++) {
15408                TaskRecord tr = mRecentTasks.get(i);
15409                if (dumpPackage != null) {
15410                    if (tr.realActivity == null ||
15411                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
15412                        continue;
15413                    }
15414                }
15415                if (!printedHeader) {
15416                    pw.println("  Recent tasks:");
15417                    printedHeader = true;
15418                    printedAnything = true;
15419                }
15420                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15421                        pw.println(tr);
15422                if (dumpAll) {
15423                    mRecentTasks.get(i).dump(pw, "    ");
15424                }
15425            }
15426        }
15427
15428        if (!printedAnything) {
15429            pw.println("  (nothing)");
15430        }
15431    }
15432
15433    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15434            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15435        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15436
15437        int dumpUid = 0;
15438        if (dumpPackage != null) {
15439            IPackageManager pm = AppGlobals.getPackageManager();
15440            try {
15441                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15442            } catch (RemoteException e) {
15443            }
15444        }
15445
15446        boolean printedAnything = false;
15447
15448        final long now = SystemClock.uptimeMillis();
15449
15450        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15451            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15452                    = mAssociations.valueAt(i1);
15453            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15454                SparseArray<ArrayMap<String, Association>> sourceUids
15455                        = targetComponents.valueAt(i2);
15456                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15457                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15458                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15459                        Association ass = sourceProcesses.valueAt(i4);
15460                        if (dumpPackage != null) {
15461                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15462                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15463                                continue;
15464                            }
15465                        }
15466                        printedAnything = true;
15467                        pw.print("  ");
15468                        pw.print(ass.mTargetProcess);
15469                        pw.print("/");
15470                        UserHandle.formatUid(pw, ass.mTargetUid);
15471                        pw.print(" <- ");
15472                        pw.print(ass.mSourceProcess);
15473                        pw.print("/");
15474                        UserHandle.formatUid(pw, ass.mSourceUid);
15475                        pw.println();
15476                        pw.print("    via ");
15477                        pw.print(ass.mTargetComponent.flattenToShortString());
15478                        pw.println();
15479                        pw.print("    ");
15480                        long dur = ass.mTime;
15481                        if (ass.mNesting > 0) {
15482                            dur += now - ass.mStartTime;
15483                        }
15484                        TimeUtils.formatDuration(dur, pw);
15485                        pw.print(" (");
15486                        pw.print(ass.mCount);
15487                        pw.print(" times)");
15488                        pw.print("  ");
15489                        for (int i=0; i<ass.mStateTimes.length; i++) {
15490                            long amt = ass.mStateTimes[i];
15491                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15492                                amt += now - ass.mLastStateUptime;
15493                            }
15494                            if (amt != 0) {
15495                                pw.print(" ");
15496                                pw.print(ProcessList.makeProcStateString(
15497                                            i + ActivityManager.MIN_PROCESS_STATE));
15498                                pw.print("=");
15499                                TimeUtils.formatDuration(amt, pw);
15500                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15501                                    pw.print("*");
15502                                }
15503                            }
15504                        }
15505                        pw.println();
15506                        if (ass.mNesting > 0) {
15507                            pw.print("    Currently active: ");
15508                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15509                            pw.println();
15510                        }
15511                    }
15512                }
15513            }
15514
15515        }
15516
15517        if (!printedAnything) {
15518            pw.println("  (nothing)");
15519        }
15520    }
15521
15522    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15523            String header, boolean needSep) {
15524        boolean printed = false;
15525        int whichAppId = -1;
15526        if (dumpPackage != null) {
15527            try {
15528                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15529                        dumpPackage, 0);
15530                whichAppId = UserHandle.getAppId(info.uid);
15531            } catch (NameNotFoundException e) {
15532                e.printStackTrace();
15533            }
15534        }
15535        for (int i=0; i<uids.size(); i++) {
15536            UidRecord uidRec = uids.valueAt(i);
15537            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15538                continue;
15539            }
15540            if (!printed) {
15541                printed = true;
15542                if (needSep) {
15543                    pw.println();
15544                }
15545                pw.print("  ");
15546                pw.println(header);
15547                needSep = true;
15548            }
15549            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15550            pw.print(": "); pw.println(uidRec);
15551        }
15552        return printed;
15553    }
15554
15555    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15556            int opti, boolean dumpAll, String dumpPackage) {
15557        boolean needSep = false;
15558        boolean printedAnything = false;
15559        int numPers = 0;
15560
15561        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15562
15563        if (dumpAll) {
15564            final int NP = mProcessNames.getMap().size();
15565            for (int ip=0; ip<NP; ip++) {
15566                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15567                final int NA = procs.size();
15568                for (int ia=0; ia<NA; ia++) {
15569                    ProcessRecord r = procs.valueAt(ia);
15570                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15571                        continue;
15572                    }
15573                    if (!needSep) {
15574                        pw.println("  All known processes:");
15575                        needSep = true;
15576                        printedAnything = true;
15577                    }
15578                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15579                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15580                        pw.print(" "); pw.println(r);
15581                    r.dump(pw, "    ");
15582                    if (r.persistent) {
15583                        numPers++;
15584                    }
15585                }
15586            }
15587        }
15588
15589        if (mIsolatedProcesses.size() > 0) {
15590            boolean printed = false;
15591            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15592                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15593                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15594                    continue;
15595                }
15596                if (!printed) {
15597                    if (needSep) {
15598                        pw.println();
15599                    }
15600                    pw.println("  Isolated process list (sorted by uid):");
15601                    printedAnything = true;
15602                    printed = true;
15603                    needSep = true;
15604                }
15605                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15606                pw.println(r);
15607            }
15608        }
15609
15610        if (mActiveInstrumentation.size() > 0) {
15611            boolean printed = false;
15612            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15613                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15614                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15615                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15616                    continue;
15617                }
15618                if (!printed) {
15619                    if (needSep) {
15620                        pw.println();
15621                    }
15622                    pw.println("  Active instrumentation:");
15623                    printedAnything = true;
15624                    printed = true;
15625                    needSep = true;
15626                }
15627                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15628                pw.println(ai);
15629                ai.dump(pw, "      ");
15630            }
15631        }
15632
15633        if (mActiveUids.size() > 0) {
15634            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15635                printedAnything = needSep = true;
15636            }
15637        }
15638        if (dumpAll) {
15639            if (mValidateUids.size() > 0) {
15640                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15641                    printedAnything = needSep = true;
15642                }
15643            }
15644        }
15645
15646        if (mLruProcesses.size() > 0) {
15647            if (needSep) {
15648                pw.println();
15649            }
15650            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15651                    pw.print(" total, non-act at ");
15652                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15653                    pw.print(", non-svc at ");
15654                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15655                    pw.println("):");
15656            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15657            needSep = true;
15658            printedAnything = true;
15659        }
15660
15661        if (dumpAll || dumpPackage != null) {
15662            synchronized (mPidsSelfLocked) {
15663                boolean printed = false;
15664                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15665                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15666                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15667                        continue;
15668                    }
15669                    if (!printed) {
15670                        if (needSep) pw.println();
15671                        needSep = true;
15672                        pw.println("  PID mappings:");
15673                        printed = true;
15674                        printedAnything = true;
15675                    }
15676                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15677                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15678                }
15679            }
15680        }
15681
15682        if (mImportantProcesses.size() > 0) {
15683            synchronized (mPidsSelfLocked) {
15684                boolean printed = false;
15685                for (int i = 0; i< mImportantProcesses.size(); i++) {
15686                    ProcessRecord r = mPidsSelfLocked.get(
15687                            mImportantProcesses.valueAt(i).pid);
15688                    if (dumpPackage != null && (r == null
15689                            || !r.pkgList.containsKey(dumpPackage))) {
15690                        continue;
15691                    }
15692                    if (!printed) {
15693                        if (needSep) pw.println();
15694                        needSep = true;
15695                        pw.println("  Foreground Processes:");
15696                        printed = true;
15697                        printedAnything = true;
15698                    }
15699                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15700                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15701                }
15702            }
15703        }
15704
15705        if (mPersistentStartingProcesses.size() > 0) {
15706            if (needSep) pw.println();
15707            needSep = true;
15708            printedAnything = true;
15709            pw.println("  Persisent processes that are starting:");
15710            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15711                    "Starting Norm", "Restarting PERS", dumpPackage);
15712        }
15713
15714        if (mRemovedProcesses.size() > 0) {
15715            if (needSep) pw.println();
15716            needSep = true;
15717            printedAnything = true;
15718            pw.println("  Processes that are being removed:");
15719            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15720                    "Removed Norm", "Removed PERS", dumpPackage);
15721        }
15722
15723        if (mProcessesOnHold.size() > 0) {
15724            if (needSep) pw.println();
15725            needSep = true;
15726            printedAnything = true;
15727            pw.println("  Processes that are on old until the system is ready:");
15728            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15729                    "OnHold Norm", "OnHold PERS", dumpPackage);
15730        }
15731
15732        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15733
15734        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15735        if (needSep) {
15736            printedAnything = true;
15737        }
15738
15739        if (dumpPackage == null) {
15740            pw.println();
15741            needSep = false;
15742            mUserController.dump(pw, dumpAll);
15743        }
15744        if (mHomeProcess != null && (dumpPackage == null
15745                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15746            if (needSep) {
15747                pw.println();
15748                needSep = false;
15749            }
15750            pw.println("  mHomeProcess: " + mHomeProcess);
15751        }
15752        if (mPreviousProcess != null && (dumpPackage == null
15753                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15754            if (needSep) {
15755                pw.println();
15756                needSep = false;
15757            }
15758            pw.println("  mPreviousProcess: " + mPreviousProcess);
15759        }
15760        if (dumpAll) {
15761            StringBuilder sb = new StringBuilder(128);
15762            sb.append("  mPreviousProcessVisibleTime: ");
15763            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15764            pw.println(sb);
15765        }
15766        if (mHeavyWeightProcess != null && (dumpPackage == null
15767                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15768            if (needSep) {
15769                pw.println();
15770                needSep = false;
15771            }
15772            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15773        }
15774        if (dumpPackage == null) {
15775            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15776            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15777        }
15778        if (dumpAll) {
15779            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15780            if (mCompatModePackages.getPackages().size() > 0) {
15781                boolean printed = false;
15782                for (Map.Entry<String, Integer> entry
15783                        : mCompatModePackages.getPackages().entrySet()) {
15784                    String pkg = entry.getKey();
15785                    int mode = entry.getValue();
15786                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15787                        continue;
15788                    }
15789                    if (!printed) {
15790                        pw.println("  mScreenCompatPackages:");
15791                        printed = true;
15792                    }
15793                    pw.print("    "); pw.print(pkg); pw.print(": ");
15794                            pw.print(mode); pw.println();
15795                }
15796            }
15797            final int NI = mUidObservers.getRegisteredCallbackCount();
15798            boolean printed = false;
15799            for (int i=0; i<NI; i++) {
15800                final UidObserverRegistration reg = (UidObserverRegistration)
15801                        mUidObservers.getRegisteredCallbackCookie(i);
15802                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15803                    if (!printed) {
15804                        pw.println("  mUidObservers:");
15805                        printed = true;
15806                    }
15807                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15808                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15809                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15810                        pw.print(" IDLE");
15811                    }
15812                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15813                        pw.print(" ACT" );
15814                    }
15815                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15816                        pw.print(" GONE");
15817                    }
15818                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15819                        pw.print(" STATE");
15820                        pw.print(" (cut="); pw.print(reg.cutpoint);
15821                        pw.print(")");
15822                    }
15823                    pw.println();
15824                    if (reg.lastProcStates != null) {
15825                        final int NJ = reg.lastProcStates.size();
15826                        for (int j=0; j<NJ; j++) {
15827                            pw.print("      Last ");
15828                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15829                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15830                        }
15831                    }
15832                }
15833            }
15834            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15835            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15836            if (mPendingTempWhitelist.size() > 0) {
15837                pw.println("  mPendingTempWhitelist:");
15838                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15839                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15840                    pw.print("    ");
15841                    UserHandle.formatUid(pw, ptw.targetUid);
15842                    pw.print(": ");
15843                    TimeUtils.formatDuration(ptw.duration, pw);
15844                    pw.print(" ");
15845                    pw.println(ptw.tag);
15846                }
15847            }
15848        }
15849        if (dumpPackage == null) {
15850            pw.println("  mWakefulness="
15851                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15852            pw.println("  mSleepTokens=" + mSleepTokens);
15853            pw.println("  mSleeping=" + mSleeping);
15854            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15855            if (mRunningVoice != null) {
15856                pw.println("  mRunningVoice=" + mRunningVoice);
15857                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15858            }
15859        }
15860        pw.println("  mVrController=" + mVrController);
15861        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15862                || mOrigWaitForDebugger) {
15863            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15864                    || dumpPackage.equals(mOrigDebugApp)) {
15865                if (needSep) {
15866                    pw.println();
15867                    needSep = false;
15868                }
15869                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15870                        + " mDebugTransient=" + mDebugTransient
15871                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15872            }
15873        }
15874        if (mCurAppTimeTracker != null) {
15875            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15876        }
15877        if (mMemWatchProcesses.getMap().size() > 0) {
15878            pw.println("  Mem watch processes:");
15879            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15880                    = mMemWatchProcesses.getMap();
15881            for (int i=0; i<procs.size(); i++) {
15882                final String proc = procs.keyAt(i);
15883                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15884                for (int j=0; j<uids.size(); j++) {
15885                    if (needSep) {
15886                        pw.println();
15887                        needSep = false;
15888                    }
15889                    StringBuilder sb = new StringBuilder();
15890                    sb.append("    ").append(proc).append('/');
15891                    UserHandle.formatUid(sb, uids.keyAt(j));
15892                    Pair<Long, String> val = uids.valueAt(j);
15893                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15894                    if (val.second != null) {
15895                        sb.append(", report to ").append(val.second);
15896                    }
15897                    pw.println(sb.toString());
15898                }
15899            }
15900            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15901            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15902            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15903                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15904        }
15905        if (mTrackAllocationApp != null) {
15906            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15907                if (needSep) {
15908                    pw.println();
15909                    needSep = false;
15910                }
15911                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15912            }
15913        }
15914        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15915                || mProfileFd != null) {
15916            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15917                if (needSep) {
15918                    pw.println();
15919                    needSep = false;
15920                }
15921                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15922                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15923                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15924                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15925                pw.println("  mProfileType=" + mProfileType);
15926            }
15927        }
15928        if (mNativeDebuggingApp != null) {
15929            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15930                if (needSep) {
15931                    pw.println();
15932                    needSep = false;
15933                }
15934                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15935            }
15936        }
15937        if (dumpPackage == null) {
15938            if (mAlwaysFinishActivities) {
15939                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15940            }
15941            if (mController != null) {
15942                pw.println("  mController=" + mController
15943                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15944            }
15945            if (dumpAll) {
15946                pw.println("  Total persistent processes: " + numPers);
15947                pw.println("  mProcessesReady=" + mProcessesReady
15948                        + " mSystemReady=" + mSystemReady
15949                        + " mBooted=" + mBooted
15950                        + " mFactoryTest=" + mFactoryTest);
15951                pw.println("  mBooting=" + mBooting
15952                        + " mCallFinishBooting=" + mCallFinishBooting
15953                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15954                pw.print("  mLastPowerCheckRealtime=");
15955                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15956                        pw.println("");
15957                pw.print("  mLastPowerCheckUptime=");
15958                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15959                        pw.println("");
15960                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15961                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15962                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15963                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15964                        + " (" + mLruProcesses.size() + " total)"
15965                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15966                        + " mNumServiceProcs=" + mNumServiceProcs
15967                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15968                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15969                        + " mLastMemoryLevel=" + mLastMemoryLevel
15970                        + " mLastNumProcesses=" + mLastNumProcesses);
15971                long now = SystemClock.uptimeMillis();
15972                pw.print("  mLastIdleTime=");
15973                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15974                        pw.print(" mLowRamSinceLastIdle=");
15975                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15976                        pw.println();
15977            }
15978        }
15979
15980        if (!printedAnything) {
15981            pw.println("  (nothing)");
15982        }
15983    }
15984
15985    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15986            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15987        if (mProcessesToGc.size() > 0) {
15988            boolean printed = false;
15989            long now = SystemClock.uptimeMillis();
15990            for (int i=0; i<mProcessesToGc.size(); i++) {
15991                ProcessRecord proc = mProcessesToGc.get(i);
15992                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15993                    continue;
15994                }
15995                if (!printed) {
15996                    if (needSep) pw.println();
15997                    needSep = true;
15998                    pw.println("  Processes that are waiting to GC:");
15999                    printed = true;
16000                }
16001                pw.print("    Process "); pw.println(proc);
16002                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16003                        pw.print(", last gced=");
16004                        pw.print(now-proc.lastRequestedGc);
16005                        pw.print(" ms ago, last lowMem=");
16006                        pw.print(now-proc.lastLowMemory);
16007                        pw.println(" ms ago");
16008
16009            }
16010        }
16011        return needSep;
16012    }
16013
16014    void printOomLevel(PrintWriter pw, String name, int adj) {
16015        pw.print("    ");
16016        if (adj >= 0) {
16017            pw.print(' ');
16018            if (adj < 10) pw.print(' ');
16019        } else {
16020            if (adj > -10) pw.print(' ');
16021        }
16022        pw.print(adj);
16023        pw.print(": ");
16024        pw.print(name);
16025        pw.print(" (");
16026        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16027        pw.println(")");
16028    }
16029
16030    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16031            int opti, boolean dumpAll) {
16032        boolean needSep = false;
16033
16034        if (mLruProcesses.size() > 0) {
16035            if (needSep) pw.println();
16036            needSep = true;
16037            pw.println("  OOM levels:");
16038            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16039            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16040            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16041            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16042            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16043            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16044            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16045            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16046            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16047            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16048            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16049            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16050            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16051            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16052
16053            if (needSep) pw.println();
16054            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16055                    pw.print(" total, non-act at ");
16056                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16057                    pw.print(", non-svc at ");
16058                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16059                    pw.println("):");
16060            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16061            needSep = true;
16062        }
16063
16064        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16065
16066        pw.println();
16067        pw.println("  mHomeProcess: " + mHomeProcess);
16068        pw.println("  mPreviousProcess: " + mPreviousProcess);
16069        if (mHeavyWeightProcess != null) {
16070            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16071        }
16072
16073        return true;
16074    }
16075
16076    /**
16077     * There are three ways to call this:
16078     *  - no provider specified: dump all the providers
16079     *  - a flattened component name that matched an existing provider was specified as the
16080     *    first arg: dump that one provider
16081     *  - the first arg isn't the flattened component name of an existing provider:
16082     *    dump all providers whose component contains the first arg as a substring
16083     */
16084    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16085            int opti, boolean dumpAll) {
16086        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16087    }
16088
16089    static class ItemMatcher {
16090        ArrayList<ComponentName> components;
16091        ArrayList<String> strings;
16092        ArrayList<Integer> objects;
16093        boolean all;
16094
16095        ItemMatcher() {
16096            all = true;
16097        }
16098
16099        void build(String name) {
16100            ComponentName componentName = ComponentName.unflattenFromString(name);
16101            if (componentName != null) {
16102                if (components == null) {
16103                    components = new ArrayList<ComponentName>();
16104                }
16105                components.add(componentName);
16106                all = false;
16107            } else {
16108                int objectId = 0;
16109                // Not a '/' separated full component name; maybe an object ID?
16110                try {
16111                    objectId = Integer.parseInt(name, 16);
16112                    if (objects == null) {
16113                        objects = new ArrayList<Integer>();
16114                    }
16115                    objects.add(objectId);
16116                    all = false;
16117                } catch (RuntimeException e) {
16118                    // Not an integer; just do string match.
16119                    if (strings == null) {
16120                        strings = new ArrayList<String>();
16121                    }
16122                    strings.add(name);
16123                    all = false;
16124                }
16125            }
16126        }
16127
16128        int build(String[] args, int opti) {
16129            for (; opti<args.length; opti++) {
16130                String name = args[opti];
16131                if ("--".equals(name)) {
16132                    return opti+1;
16133                }
16134                build(name);
16135            }
16136            return opti;
16137        }
16138
16139        boolean match(Object object, ComponentName comp) {
16140            if (all) {
16141                return true;
16142            }
16143            if (components != null) {
16144                for (int i=0; i<components.size(); i++) {
16145                    if (components.get(i).equals(comp)) {
16146                        return true;
16147                    }
16148                }
16149            }
16150            if (objects != null) {
16151                for (int i=0; i<objects.size(); i++) {
16152                    if (System.identityHashCode(object) == objects.get(i)) {
16153                        return true;
16154                    }
16155                }
16156            }
16157            if (strings != null) {
16158                String flat = comp.flattenToString();
16159                for (int i=0; i<strings.size(); i++) {
16160                    if (flat.contains(strings.get(i))) {
16161                        return true;
16162                    }
16163                }
16164            }
16165            return false;
16166        }
16167    }
16168
16169    /**
16170     * There are three things that cmd can be:
16171     *  - a flattened component name that matches an existing activity
16172     *  - the cmd arg isn't the flattened component name of an existing activity:
16173     *    dump all activity whose component contains the cmd as a substring
16174     *  - A hex number of the ActivityRecord object instance.
16175     *
16176     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16177     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16178     */
16179    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16180            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16181        ArrayList<ActivityRecord> activities;
16182
16183        synchronized (this) {
16184            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16185                    dumpFocusedStackOnly);
16186        }
16187
16188        if (activities.size() <= 0) {
16189            return false;
16190        }
16191
16192        String[] newArgs = new String[args.length - opti];
16193        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16194
16195        TaskRecord lastTask = null;
16196        boolean needSep = false;
16197        for (int i=activities.size()-1; i>=0; i--) {
16198            ActivityRecord r = activities.get(i);
16199            if (needSep) {
16200                pw.println();
16201            }
16202            needSep = true;
16203            synchronized (this) {
16204                final TaskRecord task = r.getTask();
16205                if (lastTask != task) {
16206                    lastTask = task;
16207                    pw.print("TASK "); pw.print(lastTask.affinity);
16208                            pw.print(" id="); pw.print(lastTask.taskId);
16209                            pw.print(" userId="); pw.println(lastTask.userId);
16210                    if (dumpAll) {
16211                        lastTask.dump(pw, "  ");
16212                    }
16213                }
16214            }
16215            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16216        }
16217        return true;
16218    }
16219
16220    /**
16221     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16222     * there is a thread associated with the activity.
16223     */
16224    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16225            final ActivityRecord r, String[] args, boolean dumpAll) {
16226        String innerPrefix = prefix + "  ";
16227        synchronized (this) {
16228            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16229                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16230                    pw.print(" pid=");
16231                    if (r.app != null) pw.println(r.app.pid);
16232                    else pw.println("(not running)");
16233            if (dumpAll) {
16234                r.dump(pw, innerPrefix);
16235            }
16236        }
16237        if (r.app != null && r.app.thread != null) {
16238            // flush anything that is already in the PrintWriter since the thread is going
16239            // to write to the file descriptor directly
16240            pw.flush();
16241            try {
16242                TransferPipe tp = new TransferPipe();
16243                try {
16244                    r.app.thread.dumpActivity(tp.getWriteFd(),
16245                            r.appToken, innerPrefix, args);
16246                    tp.go(fd);
16247                } finally {
16248                    tp.kill();
16249                }
16250            } catch (IOException e) {
16251                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16252            } catch (RemoteException e) {
16253                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16254            }
16255        }
16256    }
16257
16258    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16259            int opti, boolean dumpAll, String dumpPackage) {
16260        boolean needSep = false;
16261        boolean onlyHistory = false;
16262        boolean printedAnything = false;
16263
16264        if ("history".equals(dumpPackage)) {
16265            if (opti < args.length && "-s".equals(args[opti])) {
16266                dumpAll = false;
16267            }
16268            onlyHistory = true;
16269            dumpPackage = null;
16270        }
16271
16272        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16273        if (!onlyHistory && dumpAll) {
16274            if (mRegisteredReceivers.size() > 0) {
16275                boolean printed = false;
16276                Iterator it = mRegisteredReceivers.values().iterator();
16277                while (it.hasNext()) {
16278                    ReceiverList r = (ReceiverList)it.next();
16279                    if (dumpPackage != null && (r.app == null ||
16280                            !dumpPackage.equals(r.app.info.packageName))) {
16281                        continue;
16282                    }
16283                    if (!printed) {
16284                        pw.println("  Registered Receivers:");
16285                        needSep = true;
16286                        printed = true;
16287                        printedAnything = true;
16288                    }
16289                    pw.print("  * "); pw.println(r);
16290                    r.dump(pw, "    ");
16291                }
16292            }
16293
16294            if (mReceiverResolver.dump(pw, needSep ?
16295                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16296                    "    ", dumpPackage, false, false)) {
16297                needSep = true;
16298                printedAnything = true;
16299            }
16300        }
16301
16302        for (BroadcastQueue q : mBroadcastQueues) {
16303            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16304            printedAnything |= needSep;
16305        }
16306
16307        needSep = true;
16308
16309        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16310            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16311                if (needSep) {
16312                    pw.println();
16313                }
16314                needSep = true;
16315                printedAnything = true;
16316                pw.print("  Sticky broadcasts for user ");
16317                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16318                StringBuilder sb = new StringBuilder(128);
16319                for (Map.Entry<String, ArrayList<Intent>> ent
16320                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16321                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16322                    if (dumpAll) {
16323                        pw.println(":");
16324                        ArrayList<Intent> intents = ent.getValue();
16325                        final int N = intents.size();
16326                        for (int i=0; i<N; i++) {
16327                            sb.setLength(0);
16328                            sb.append("    Intent: ");
16329                            intents.get(i).toShortString(sb, false, true, false, false);
16330                            pw.println(sb.toString());
16331                            Bundle bundle = intents.get(i).getExtras();
16332                            if (bundle != null) {
16333                                pw.print("      ");
16334                                pw.println(bundle.toString());
16335                            }
16336                        }
16337                    } else {
16338                        pw.println("");
16339                    }
16340                }
16341            }
16342        }
16343
16344        if (!onlyHistory && dumpAll) {
16345            pw.println();
16346            for (BroadcastQueue queue : mBroadcastQueues) {
16347                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16348                        + queue.mBroadcastsScheduled);
16349            }
16350            pw.println("  mHandler:");
16351            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16352            needSep = true;
16353            printedAnything = true;
16354        }
16355
16356        if (!printedAnything) {
16357            pw.println("  (nothing)");
16358        }
16359    }
16360
16361    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16362            int opti, boolean dumpAll, String dumpPackage) {
16363        if (mCurBroadcastStats == null) {
16364            return;
16365        }
16366
16367        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16368        final long now = SystemClock.elapsedRealtime();
16369        if (mLastBroadcastStats != null) {
16370            pw.print("  Last stats (from ");
16371            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16372            pw.print(" to ");
16373            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16374            pw.print(", ");
16375            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16376                    - mLastBroadcastStats.mStartUptime, pw);
16377            pw.println(" uptime):");
16378            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16379                pw.println("    (nothing)");
16380            }
16381            pw.println();
16382        }
16383        pw.print("  Current stats (from ");
16384        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16385        pw.print(" to now, ");
16386        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16387                - mCurBroadcastStats.mStartUptime, pw);
16388        pw.println(" uptime):");
16389        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16390            pw.println("    (nothing)");
16391        }
16392    }
16393
16394    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16395            int opti, boolean fullCheckin, String dumpPackage) {
16396        if (mCurBroadcastStats == null) {
16397            return;
16398        }
16399
16400        if (mLastBroadcastStats != null) {
16401            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16402            if (fullCheckin) {
16403                mLastBroadcastStats = null;
16404                return;
16405            }
16406        }
16407        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16408        if (fullCheckin) {
16409            mCurBroadcastStats = null;
16410        }
16411    }
16412
16413    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16414            int opti, boolean dumpAll, String dumpPackage) {
16415        boolean needSep;
16416        boolean printedAnything = false;
16417
16418        ItemMatcher matcher = new ItemMatcher();
16419        matcher.build(args, opti);
16420
16421        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16422
16423        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16424        printedAnything |= needSep;
16425
16426        if (mLaunchingProviders.size() > 0) {
16427            boolean printed = false;
16428            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16429                ContentProviderRecord r = mLaunchingProviders.get(i);
16430                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16431                    continue;
16432                }
16433                if (!printed) {
16434                    if (needSep) pw.println();
16435                    needSep = true;
16436                    pw.println("  Launching content providers:");
16437                    printed = true;
16438                    printedAnything = true;
16439                }
16440                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16441                        pw.println(r);
16442            }
16443        }
16444
16445        if (!printedAnything) {
16446            pw.println("  (nothing)");
16447        }
16448    }
16449
16450    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16451            int opti, boolean dumpAll, String dumpPackage) {
16452        boolean needSep = false;
16453        boolean printedAnything = false;
16454
16455        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16456
16457        if (mGrantedUriPermissions.size() > 0) {
16458            boolean printed = false;
16459            int dumpUid = -2;
16460            if (dumpPackage != null) {
16461                try {
16462                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16463                            MATCH_ANY_USER, 0);
16464                } catch (NameNotFoundException e) {
16465                    dumpUid = -1;
16466                }
16467            }
16468            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16469                int uid = mGrantedUriPermissions.keyAt(i);
16470                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16471                    continue;
16472                }
16473                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16474                if (!printed) {
16475                    if (needSep) pw.println();
16476                    needSep = true;
16477                    pw.println("  Granted Uri Permissions:");
16478                    printed = true;
16479                    printedAnything = true;
16480                }
16481                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16482                for (UriPermission perm : perms.values()) {
16483                    pw.print("    "); pw.println(perm);
16484                    if (dumpAll) {
16485                        perm.dump(pw, "      ");
16486                    }
16487                }
16488            }
16489        }
16490
16491        if (!printedAnything) {
16492            pw.println("  (nothing)");
16493        }
16494    }
16495
16496    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16497            int opti, boolean dumpAll, String dumpPackage) {
16498        boolean printed = false;
16499
16500        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16501
16502        if (mIntentSenderRecords.size() > 0) {
16503            // Organize these by package name, so they are easier to read.
16504            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16505            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16506            final Iterator<WeakReference<PendingIntentRecord>> it
16507                    = mIntentSenderRecords.values().iterator();
16508            while (it.hasNext()) {
16509                WeakReference<PendingIntentRecord> ref = it.next();
16510                PendingIntentRecord rec = ref != null ? ref.get() : null;
16511                if (rec == null) {
16512                    weakRefs.add(ref);
16513                    continue;
16514                }
16515                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16516                    continue;
16517                }
16518                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16519                if (list == null) {
16520                    list = new ArrayList<>();
16521                    byPackage.put(rec.key.packageName, list);
16522                }
16523                list.add(rec);
16524            }
16525            for (int i = 0; i < byPackage.size(); i++) {
16526                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16527                printed = true;
16528                pw.print("  * "); pw.print(byPackage.keyAt(i));
16529                pw.print(": "); pw.print(intents.size()); pw.println(" items");
16530                for (int j = 0; j < intents.size(); j++) {
16531                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16532                    if (dumpAll) {
16533                        intents.get(j).dump(pw, "      ");
16534                    }
16535                }
16536            }
16537            if (weakRefs.size() > 0) {
16538                printed = true;
16539                pw.println("  * WEAK REFS:");
16540                for (int i = 0; i < weakRefs.size(); i++) {
16541                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16542                }
16543            }
16544        }
16545
16546        if (!printed) {
16547            pw.println("  (nothing)");
16548        }
16549    }
16550
16551    private static final int dumpProcessList(PrintWriter pw,
16552            ActivityManagerService service, List list,
16553            String prefix, String normalLabel, String persistentLabel,
16554            String dumpPackage) {
16555        int numPers = 0;
16556        final int N = list.size()-1;
16557        for (int i=N; i>=0; i--) {
16558            ProcessRecord r = (ProcessRecord)list.get(i);
16559            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16560                continue;
16561            }
16562            pw.println(String.format("%s%s #%2d: %s",
16563                    prefix, (r.persistent ? persistentLabel : normalLabel),
16564                    i, r.toString()));
16565            if (r.persistent) {
16566                numPers++;
16567            }
16568        }
16569        return numPers;
16570    }
16571
16572    private static final boolean dumpProcessOomList(PrintWriter pw,
16573            ActivityManagerService service, List<ProcessRecord> origList,
16574            String prefix, String normalLabel, String persistentLabel,
16575            boolean inclDetails, String dumpPackage) {
16576
16577        ArrayList<Pair<ProcessRecord, Integer>> list
16578                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16579        for (int i=0; i<origList.size(); i++) {
16580            ProcessRecord r = origList.get(i);
16581            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16582                continue;
16583            }
16584            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16585        }
16586
16587        if (list.size() <= 0) {
16588            return false;
16589        }
16590
16591        Comparator<Pair<ProcessRecord, Integer>> comparator
16592                = new Comparator<Pair<ProcessRecord, Integer>>() {
16593            @Override
16594            public int compare(Pair<ProcessRecord, Integer> object1,
16595                    Pair<ProcessRecord, Integer> object2) {
16596                if (object1.first.setAdj != object2.first.setAdj) {
16597                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16598                }
16599                if (object1.first.setProcState != object2.first.setProcState) {
16600                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16601                }
16602                if (object1.second.intValue() != object2.second.intValue()) {
16603                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16604                }
16605                return 0;
16606            }
16607        };
16608
16609        Collections.sort(list, comparator);
16610
16611        final long curRealtime = SystemClock.elapsedRealtime();
16612        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16613        final long curUptime = SystemClock.uptimeMillis();
16614        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16615
16616        for (int i=list.size()-1; i>=0; i--) {
16617            ProcessRecord r = list.get(i).first;
16618            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16619            char schedGroup;
16620            switch (r.setSchedGroup) {
16621                case ProcessList.SCHED_GROUP_BACKGROUND:
16622                    schedGroup = 'B';
16623                    break;
16624                case ProcessList.SCHED_GROUP_DEFAULT:
16625                    schedGroup = 'F';
16626                    break;
16627                case ProcessList.SCHED_GROUP_TOP_APP:
16628                    schedGroup = 'T';
16629                    break;
16630                default:
16631                    schedGroup = '?';
16632                    break;
16633            }
16634            char foreground;
16635            if (r.foregroundActivities) {
16636                foreground = 'A';
16637            } else if (r.foregroundServices) {
16638                foreground = 'S';
16639            } else {
16640                foreground = ' ';
16641            }
16642            String procState = ProcessList.makeProcStateString(r.curProcState);
16643            pw.print(prefix);
16644            pw.print(r.persistent ? persistentLabel : normalLabel);
16645            pw.print(" #");
16646            int num = (origList.size()-1)-list.get(i).second;
16647            if (num < 10) pw.print(' ');
16648            pw.print(num);
16649            pw.print(": ");
16650            pw.print(oomAdj);
16651            pw.print(' ');
16652            pw.print(schedGroup);
16653            pw.print('/');
16654            pw.print(foreground);
16655            pw.print('/');
16656            pw.print(procState);
16657            pw.print(" trm:");
16658            if (r.trimMemoryLevel < 10) pw.print(' ');
16659            pw.print(r.trimMemoryLevel);
16660            pw.print(' ');
16661            pw.print(r.toShortString());
16662            pw.print(" (");
16663            pw.print(r.adjType);
16664            pw.println(')');
16665            if (r.adjSource != null || r.adjTarget != null) {
16666                pw.print(prefix);
16667                pw.print("    ");
16668                if (r.adjTarget instanceof ComponentName) {
16669                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16670                } else if (r.adjTarget != null) {
16671                    pw.print(r.adjTarget.toString());
16672                } else {
16673                    pw.print("{null}");
16674                }
16675                pw.print("<=");
16676                if (r.adjSource instanceof ProcessRecord) {
16677                    pw.print("Proc{");
16678                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16679                    pw.println("}");
16680                } else if (r.adjSource != null) {
16681                    pw.println(r.adjSource.toString());
16682                } else {
16683                    pw.println("{null}");
16684                }
16685            }
16686            if (inclDetails) {
16687                pw.print(prefix);
16688                pw.print("    ");
16689                pw.print("oom: max="); pw.print(r.maxAdj);
16690                pw.print(" curRaw="); pw.print(r.curRawAdj);
16691                pw.print(" setRaw="); pw.print(r.setRawAdj);
16692                pw.print(" cur="); pw.print(r.curAdj);
16693                pw.print(" set="); pw.println(r.setAdj);
16694                pw.print(prefix);
16695                pw.print("    ");
16696                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16697                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16698                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16699                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16700                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16701                pw.println();
16702                pw.print(prefix);
16703                pw.print("    ");
16704                pw.print("cached="); pw.print(r.cached);
16705                pw.print(" empty="); pw.print(r.empty);
16706                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16707
16708                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16709                    if (r.lastWakeTime != 0) {
16710                        long wtime;
16711                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16712                        synchronized (stats) {
16713                            wtime = stats.getProcessWakeTime(r.info.uid,
16714                                    r.pid, curRealtime);
16715                        }
16716                        long timeUsed = wtime - r.lastWakeTime;
16717                        pw.print(prefix);
16718                        pw.print("    ");
16719                        pw.print("keep awake over ");
16720                        TimeUtils.formatDuration(realtimeSince, pw);
16721                        pw.print(" used ");
16722                        TimeUtils.formatDuration(timeUsed, pw);
16723                        pw.print(" (");
16724                        pw.print((timeUsed*100)/realtimeSince);
16725                        pw.println("%)");
16726                    }
16727                    if (r.lastCpuTime != 0) {
16728                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16729                        pw.print(prefix);
16730                        pw.print("    ");
16731                        pw.print("run cpu over ");
16732                        TimeUtils.formatDuration(uptimeSince, pw);
16733                        pw.print(" used ");
16734                        TimeUtils.formatDuration(timeUsed, pw);
16735                        pw.print(" (");
16736                        pw.print((timeUsed*100)/uptimeSince);
16737                        pw.println("%)");
16738                    }
16739                }
16740            }
16741        }
16742        return true;
16743    }
16744
16745    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16746            String[] args) {
16747        ArrayList<ProcessRecord> procs;
16748        synchronized (this) {
16749            if (args != null && args.length > start
16750                    && args[start].charAt(0) != '-') {
16751                procs = new ArrayList<ProcessRecord>();
16752                int pid = -1;
16753                try {
16754                    pid = Integer.parseInt(args[start]);
16755                } catch (NumberFormatException e) {
16756                }
16757                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16758                    ProcessRecord proc = mLruProcesses.get(i);
16759                    if (proc.pid == pid) {
16760                        procs.add(proc);
16761                    } else if (allPkgs && proc.pkgList != null
16762                            && proc.pkgList.containsKey(args[start])) {
16763                        procs.add(proc);
16764                    } else if (proc.processName.equals(args[start])) {
16765                        procs.add(proc);
16766                    }
16767                }
16768                if (procs.size() <= 0) {
16769                    return null;
16770                }
16771            } else {
16772                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16773            }
16774        }
16775        return procs;
16776    }
16777
16778    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16779            PrintWriter pw, String[] args) {
16780        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16781        if (procs == null) {
16782            pw.println("No process found for: " + args[0]);
16783            return;
16784        }
16785
16786        long uptime = SystemClock.uptimeMillis();
16787        long realtime = SystemClock.elapsedRealtime();
16788        pw.println("Applications Graphics Acceleration Info:");
16789        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16790
16791        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16792            ProcessRecord r = procs.get(i);
16793            if (r.thread != null) {
16794                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16795                pw.flush();
16796                try {
16797                    TransferPipe tp = new TransferPipe();
16798                    try {
16799                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16800                        tp.go(fd);
16801                    } finally {
16802                        tp.kill();
16803                    }
16804                } catch (IOException e) {
16805                    pw.println("Failure while dumping the app: " + r);
16806                    pw.flush();
16807                } catch (RemoteException e) {
16808                    pw.println("Got a RemoteException while dumping the app " + r);
16809                    pw.flush();
16810                }
16811            }
16812        }
16813    }
16814
16815    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16816        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16817        if (procs == null) {
16818            pw.println("No process found for: " + args[0]);
16819            return;
16820        }
16821
16822        pw.println("Applications Database Info:");
16823
16824        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16825            ProcessRecord r = procs.get(i);
16826            if (r.thread != null) {
16827                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16828                pw.flush();
16829                try {
16830                    TransferPipe tp = new TransferPipe();
16831                    try {
16832                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16833                        tp.go(fd);
16834                    } finally {
16835                        tp.kill();
16836                    }
16837                } catch (IOException e) {
16838                    pw.println("Failure while dumping the app: " + r);
16839                    pw.flush();
16840                } catch (RemoteException e) {
16841                    pw.println("Got a RemoteException while dumping the app " + r);
16842                    pw.flush();
16843                }
16844            }
16845        }
16846    }
16847
16848    final static class MemItem {
16849        final boolean isProc;
16850        final String label;
16851        final String shortLabel;
16852        final long pss;
16853        final long swapPss;
16854        final int id;
16855        final boolean hasActivities;
16856        ArrayList<MemItem> subitems;
16857
16858        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16859                boolean _hasActivities) {
16860            isProc = true;
16861            label = _label;
16862            shortLabel = _shortLabel;
16863            pss = _pss;
16864            swapPss = _swapPss;
16865            id = _id;
16866            hasActivities = _hasActivities;
16867        }
16868
16869        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16870            isProc = false;
16871            label = _label;
16872            shortLabel = _shortLabel;
16873            pss = _pss;
16874            swapPss = _swapPss;
16875            id = _id;
16876            hasActivities = false;
16877        }
16878    }
16879
16880    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16881            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16882        if (sort && !isCompact) {
16883            Collections.sort(items, new Comparator<MemItem>() {
16884                @Override
16885                public int compare(MemItem lhs, MemItem rhs) {
16886                    if (lhs.pss < rhs.pss) {
16887                        return 1;
16888                    } else if (lhs.pss > rhs.pss) {
16889                        return -1;
16890                    }
16891                    return 0;
16892                }
16893            });
16894        }
16895
16896        for (int i=0; i<items.size(); i++) {
16897            MemItem mi = items.get(i);
16898            if (!isCompact) {
16899                if (dumpSwapPss) {
16900                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16901                            mi.label, stringifyKBSize(mi.swapPss));
16902                } else {
16903                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16904                }
16905            } else if (mi.isProc) {
16906                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16907                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16908                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16909                pw.println(mi.hasActivities ? ",a" : ",e");
16910            } else {
16911                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16912                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16913            }
16914            if (mi.subitems != null) {
16915                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16916                        true, isCompact, dumpSwapPss);
16917            }
16918        }
16919    }
16920
16921    // These are in KB.
16922    static final long[] DUMP_MEM_BUCKETS = new long[] {
16923        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16924        120*1024, 160*1024, 200*1024,
16925        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16926        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16927    };
16928
16929    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16930            boolean stackLike) {
16931        int start = label.lastIndexOf('.');
16932        if (start >= 0) start++;
16933        else start = 0;
16934        int end = label.length();
16935        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16936            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16937                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16938                out.append(bucket);
16939                out.append(stackLike ? "MB." : "MB ");
16940                out.append(label, start, end);
16941                return;
16942            }
16943        }
16944        out.append(memKB/1024);
16945        out.append(stackLike ? "MB." : "MB ");
16946        out.append(label, start, end);
16947    }
16948
16949    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16950            ProcessList.NATIVE_ADJ,
16951            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16952            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16953            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16954            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16955            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16956            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16957    };
16958    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16959            "Native",
16960            "System", "Persistent", "Persistent Service", "Foreground",
16961            "Visible", "Perceptible",
16962            "Heavy Weight", "Backup",
16963            "A Services", "Home",
16964            "Previous", "B Services", "Cached"
16965    };
16966    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16967            "native",
16968            "sys", "pers", "persvc", "fore",
16969            "vis", "percept",
16970            "heavy", "backup",
16971            "servicea", "home",
16972            "prev", "serviceb", "cached"
16973    };
16974
16975    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16976            long realtime, boolean isCheckinRequest, boolean isCompact) {
16977        if (isCompact) {
16978            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16979        }
16980        if (isCheckinRequest || isCompact) {
16981            // short checkin version
16982            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16983        } else {
16984            pw.println("Applications Memory Usage (in Kilobytes):");
16985            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16986        }
16987    }
16988
16989    private static final int KSM_SHARED = 0;
16990    private static final int KSM_SHARING = 1;
16991    private static final int KSM_UNSHARED = 2;
16992    private static final int KSM_VOLATILE = 3;
16993
16994    private final long[] getKsmInfo() {
16995        long[] longOut = new long[4];
16996        final int[] SINGLE_LONG_FORMAT = new int[] {
16997            PROC_SPACE_TERM| PROC_OUT_LONG
16998        };
16999        long[] longTmp = new long[1];
17000        readProcFile("/sys/kernel/mm/ksm/pages_shared",
17001                SINGLE_LONG_FORMAT, null, longTmp, null);
17002        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17003        longTmp[0] = 0;
17004        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17005                SINGLE_LONG_FORMAT, null, longTmp, null);
17006        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17007        longTmp[0] = 0;
17008        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17009                SINGLE_LONG_FORMAT, null, longTmp, null);
17010        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17011        longTmp[0] = 0;
17012        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17013                SINGLE_LONG_FORMAT, null, longTmp, null);
17014        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17015        return longOut;
17016    }
17017
17018    private static String stringifySize(long size, int order) {
17019        Locale locale = Locale.US;
17020        switch (order) {
17021            case 1:
17022                return String.format(locale, "%,13d", size);
17023            case 1024:
17024                return String.format(locale, "%,9dK", size / 1024);
17025            case 1024 * 1024:
17026                return String.format(locale, "%,5dM", size / 1024 / 1024);
17027            case 1024 * 1024 * 1024:
17028                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17029            default:
17030                throw new IllegalArgumentException("Invalid size order");
17031        }
17032    }
17033
17034    private static String stringifyKBSize(long size) {
17035        return stringifySize(size * 1024, 1024);
17036    }
17037
17038    // Update this version number in case you change the 'compact' format
17039    private static final int MEMINFO_COMPACT_VERSION = 1;
17040
17041    final void dumpApplicationMemoryUsage(FileDescriptor fd,
17042            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17043        boolean dumpDetails = false;
17044        boolean dumpFullDetails = false;
17045        boolean dumpDalvik = false;
17046        boolean dumpSummaryOnly = false;
17047        boolean dumpUnreachable = false;
17048        boolean oomOnly = false;
17049        boolean isCompact = false;
17050        boolean localOnly = false;
17051        boolean packages = false;
17052        boolean isCheckinRequest = false;
17053        boolean dumpSwapPss = false;
17054
17055        int opti = 0;
17056        while (opti < args.length) {
17057            String opt = args[opti];
17058            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17059                break;
17060            }
17061            opti++;
17062            if ("-a".equals(opt)) {
17063                dumpDetails = true;
17064                dumpFullDetails = true;
17065                dumpDalvik = true;
17066                dumpSwapPss = true;
17067            } else if ("-d".equals(opt)) {
17068                dumpDalvik = true;
17069            } else if ("-c".equals(opt)) {
17070                isCompact = true;
17071            } else if ("-s".equals(opt)) {
17072                dumpDetails = true;
17073                dumpSummaryOnly = true;
17074            } else if ("-S".equals(opt)) {
17075                dumpSwapPss = true;
17076            } else if ("--unreachable".equals(opt)) {
17077                dumpUnreachable = true;
17078            } else if ("--oom".equals(opt)) {
17079                oomOnly = true;
17080            } else if ("--local".equals(opt)) {
17081                localOnly = true;
17082            } else if ("--package".equals(opt)) {
17083                packages = true;
17084            } else if ("--checkin".equals(opt)) {
17085                isCheckinRequest = true;
17086
17087            } else if ("-h".equals(opt)) {
17088                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17089                pw.println("  -a: include all available information for each process.");
17090                pw.println("  -d: include dalvik details.");
17091                pw.println("  -c: dump in a compact machine-parseable representation.");
17092                pw.println("  -s: dump only summary of application memory usage.");
17093                pw.println("  -S: dump also SwapPss.");
17094                pw.println("  --oom: only show processes organized by oom adj.");
17095                pw.println("  --local: only collect details locally, don't call process.");
17096                pw.println("  --package: interpret process arg as package, dumping all");
17097                pw.println("             processes that have loaded that package.");
17098                pw.println("  --checkin: dump data for a checkin");
17099                pw.println("If [process] is specified it can be the name or ");
17100                pw.println("pid of a specific process to dump.");
17101                return;
17102            } else {
17103                pw.println("Unknown argument: " + opt + "; use -h for help");
17104            }
17105        }
17106
17107        long uptime = SystemClock.uptimeMillis();
17108        long realtime = SystemClock.elapsedRealtime();
17109        final long[] tmpLong = new long[1];
17110
17111        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17112        if (procs == null) {
17113            // No Java processes.  Maybe they want to print a native process.
17114            if (args != null && args.length > opti
17115                    && args[opti].charAt(0) != '-') {
17116                ArrayList<ProcessCpuTracker.Stats> nativeProcs
17117                        = new ArrayList<ProcessCpuTracker.Stats>();
17118                updateCpuStatsNow();
17119                int findPid = -1;
17120                try {
17121                    findPid = Integer.parseInt(args[opti]);
17122                } catch (NumberFormatException e) {
17123                }
17124                synchronized (mProcessCpuTracker) {
17125                    final int N = mProcessCpuTracker.countStats();
17126                    for (int i=0; i<N; i++) {
17127                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17128                        if (st.pid == findPid || (st.baseName != null
17129                                && st.baseName.equals(args[opti]))) {
17130                            nativeProcs.add(st);
17131                        }
17132                    }
17133                }
17134                if (nativeProcs.size() > 0) {
17135                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17136                            isCompact);
17137                    Debug.MemoryInfo mi = null;
17138                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17139                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17140                        final int pid = r.pid;
17141                        if (!isCheckinRequest && dumpDetails) {
17142                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17143                        }
17144                        if (mi == null) {
17145                            mi = new Debug.MemoryInfo();
17146                        }
17147                        if (dumpDetails || (!brief && !oomOnly)) {
17148                            Debug.getMemoryInfo(pid, mi);
17149                        } else {
17150                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17151                            mi.dalvikPrivateDirty = (int)tmpLong[0];
17152                        }
17153                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17154                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17155                        if (isCheckinRequest) {
17156                            pw.println();
17157                        }
17158                    }
17159                    return;
17160                }
17161            }
17162            pw.println("No process found for: " + args[opti]);
17163            return;
17164        }
17165
17166        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17167            dumpDetails = true;
17168        }
17169
17170        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17171
17172        String[] innerArgs = new String[args.length-opti];
17173        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17174
17175        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17176        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17177        long nativePss = 0;
17178        long nativeSwapPss = 0;
17179        long dalvikPss = 0;
17180        long dalvikSwapPss = 0;
17181        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17182                EmptyArray.LONG;
17183        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17184                EmptyArray.LONG;
17185        long otherPss = 0;
17186        long otherSwapPss = 0;
17187        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17188        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17189
17190        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17191        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17192        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17193                new ArrayList[DUMP_MEM_OOM_LABEL.length];
17194
17195        long totalPss = 0;
17196        long totalSwapPss = 0;
17197        long cachedPss = 0;
17198        long cachedSwapPss = 0;
17199        boolean hasSwapPss = false;
17200
17201        Debug.MemoryInfo mi = null;
17202        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17203            final ProcessRecord r = procs.get(i);
17204            final IApplicationThread thread;
17205            final int pid;
17206            final int oomAdj;
17207            final boolean hasActivities;
17208            synchronized (this) {
17209                thread = r.thread;
17210                pid = r.pid;
17211                oomAdj = r.getSetAdjWithServices();
17212                hasActivities = r.activities.size() > 0;
17213            }
17214            if (thread != null) {
17215                if (!isCheckinRequest && dumpDetails) {
17216                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17217                }
17218                if (mi == null) {
17219                    mi = new Debug.MemoryInfo();
17220                }
17221                if (dumpDetails || (!brief && !oomOnly)) {
17222                    Debug.getMemoryInfo(pid, mi);
17223                    hasSwapPss = mi.hasSwappedOutPss;
17224                } else {
17225                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17226                    mi.dalvikPrivateDirty = (int)tmpLong[0];
17227                }
17228                if (dumpDetails) {
17229                    if (localOnly) {
17230                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17231                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17232                        if (isCheckinRequest) {
17233                            pw.println();
17234                        }
17235                    } else {
17236                        pw.flush();
17237                        try {
17238                            TransferPipe tp = new TransferPipe();
17239                            try {
17240                                thread.dumpMemInfo(tp.getWriteFd(),
17241                                        mi, isCheckinRequest, dumpFullDetails,
17242                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17243                                tp.go(fd);
17244                            } finally {
17245                                tp.kill();
17246                            }
17247                        } catch (IOException e) {
17248                            if (!isCheckinRequest) {
17249                                pw.println("Got IoException!");
17250                                pw.flush();
17251                            }
17252                        } catch (RemoteException e) {
17253                            if (!isCheckinRequest) {
17254                                pw.println("Got RemoteException!");
17255                                pw.flush();
17256                            }
17257                        }
17258                    }
17259                }
17260
17261                final long myTotalPss = mi.getTotalPss();
17262                final long myTotalUss = mi.getTotalUss();
17263                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17264
17265                synchronized (this) {
17266                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17267                        // Record this for posterity if the process has been stable.
17268                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17269                    }
17270                }
17271
17272                if (!isCheckinRequest && mi != null) {
17273                    totalPss += myTotalPss;
17274                    totalSwapPss += myTotalSwapPss;
17275                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17276                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17277                            myTotalSwapPss, pid, hasActivities);
17278                    procMems.add(pssItem);
17279                    procMemsMap.put(pid, pssItem);
17280
17281                    nativePss += mi.nativePss;
17282                    nativeSwapPss += mi.nativeSwappedOutPss;
17283                    dalvikPss += mi.dalvikPss;
17284                    dalvikSwapPss += mi.dalvikSwappedOutPss;
17285                    for (int j=0; j<dalvikSubitemPss.length; j++) {
17286                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17287                        dalvikSubitemSwapPss[j] +=
17288                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17289                    }
17290                    otherPss += mi.otherPss;
17291                    otherSwapPss += mi.otherSwappedOutPss;
17292                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17293                        long mem = mi.getOtherPss(j);
17294                        miscPss[j] += mem;
17295                        otherPss -= mem;
17296                        mem = mi.getOtherSwappedOutPss(j);
17297                        miscSwapPss[j] += mem;
17298                        otherSwapPss -= mem;
17299                    }
17300
17301                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17302                        cachedPss += myTotalPss;
17303                        cachedSwapPss += myTotalSwapPss;
17304                    }
17305
17306                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17307                        if (oomIndex == (oomPss.length - 1)
17308                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17309                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17310                            oomPss[oomIndex] += myTotalPss;
17311                            oomSwapPss[oomIndex] += myTotalSwapPss;
17312                            if (oomProcs[oomIndex] == null) {
17313                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17314                            }
17315                            oomProcs[oomIndex].add(pssItem);
17316                            break;
17317                        }
17318                    }
17319                }
17320            }
17321        }
17322
17323        long nativeProcTotalPss = 0;
17324
17325        if (!isCheckinRequest && procs.size() > 1 && !packages) {
17326            // If we are showing aggregations, also look for native processes to
17327            // include so that our aggregations are more accurate.
17328            updateCpuStatsNow();
17329            mi = null;
17330            synchronized (mProcessCpuTracker) {
17331                final int N = mProcessCpuTracker.countStats();
17332                for (int i=0; i<N; i++) {
17333                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17334                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17335                        if (mi == null) {
17336                            mi = new Debug.MemoryInfo();
17337                        }
17338                        if (!brief && !oomOnly) {
17339                            Debug.getMemoryInfo(st.pid, mi);
17340                        } else {
17341                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17342                            mi.nativePrivateDirty = (int)tmpLong[0];
17343                        }
17344
17345                        final long myTotalPss = mi.getTotalPss();
17346                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17347                        totalPss += myTotalPss;
17348                        nativeProcTotalPss += myTotalPss;
17349
17350                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17351                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17352                        procMems.add(pssItem);
17353
17354                        nativePss += mi.nativePss;
17355                        nativeSwapPss += mi.nativeSwappedOutPss;
17356                        dalvikPss += mi.dalvikPss;
17357                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17358                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17359                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17360                            dalvikSubitemSwapPss[j] +=
17361                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17362                        }
17363                        otherPss += mi.otherPss;
17364                        otherSwapPss += mi.otherSwappedOutPss;
17365                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17366                            long mem = mi.getOtherPss(j);
17367                            miscPss[j] += mem;
17368                            otherPss -= mem;
17369                            mem = mi.getOtherSwappedOutPss(j);
17370                            miscSwapPss[j] += mem;
17371                            otherSwapPss -= mem;
17372                        }
17373                        oomPss[0] += myTotalPss;
17374                        oomSwapPss[0] += myTotalSwapPss;
17375                        if (oomProcs[0] == null) {
17376                            oomProcs[0] = new ArrayList<MemItem>();
17377                        }
17378                        oomProcs[0].add(pssItem);
17379                    }
17380                }
17381            }
17382
17383            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17384
17385            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17386            final MemItem dalvikItem =
17387                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17388            if (dalvikSubitemPss.length > 0) {
17389                dalvikItem.subitems = new ArrayList<MemItem>();
17390                for (int j=0; j<dalvikSubitemPss.length; j++) {
17391                    final String name = Debug.MemoryInfo.getOtherLabel(
17392                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
17393                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17394                                    dalvikSubitemSwapPss[j], j));
17395                }
17396            }
17397            catMems.add(dalvikItem);
17398            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17399            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17400                String label = Debug.MemoryInfo.getOtherLabel(j);
17401                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17402            }
17403
17404            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17405            for (int j=0; j<oomPss.length; j++) {
17406                if (oomPss[j] != 0) {
17407                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17408                            : DUMP_MEM_OOM_LABEL[j];
17409                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17410                            DUMP_MEM_OOM_ADJ[j]);
17411                    item.subitems = oomProcs[j];
17412                    oomMems.add(item);
17413                }
17414            }
17415
17416            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17417            if (!brief && !oomOnly && !isCompact) {
17418                pw.println();
17419                pw.println("Total PSS by process:");
17420                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17421                pw.println();
17422            }
17423            if (!isCompact) {
17424                pw.println("Total PSS by OOM adjustment:");
17425            }
17426            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17427            if (!brief && !oomOnly) {
17428                PrintWriter out = categoryPw != null ? categoryPw : pw;
17429                if (!isCompact) {
17430                    out.println();
17431                    out.println("Total PSS by category:");
17432                }
17433                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17434            }
17435            if (!isCompact) {
17436                pw.println();
17437            }
17438            MemInfoReader memInfo = new MemInfoReader();
17439            memInfo.readMemInfo();
17440            if (nativeProcTotalPss > 0) {
17441                synchronized (this) {
17442                    final long cachedKb = memInfo.getCachedSizeKb();
17443                    final long freeKb = memInfo.getFreeSizeKb();
17444                    final long zramKb = memInfo.getZramTotalSizeKb();
17445                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17446                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17447                            kernelKb*1024, nativeProcTotalPss*1024);
17448                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17449                            nativeProcTotalPss);
17450                }
17451            }
17452            if (!brief) {
17453                if (!isCompact) {
17454                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17455                    pw.print(" (status ");
17456                    switch (mLastMemoryLevel) {
17457                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17458                            pw.println("normal)");
17459                            break;
17460                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17461                            pw.println("moderate)");
17462                            break;
17463                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17464                            pw.println("low)");
17465                            break;
17466                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17467                            pw.println("critical)");
17468                            break;
17469                        default:
17470                            pw.print(mLastMemoryLevel);
17471                            pw.println(")");
17472                            break;
17473                    }
17474                    pw.print(" Free RAM: ");
17475                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17476                            + memInfo.getFreeSizeKb()));
17477                    pw.print(" (");
17478                    pw.print(stringifyKBSize(cachedPss));
17479                    pw.print(" cached pss + ");
17480                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17481                    pw.print(" cached kernel + ");
17482                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17483                    pw.println(" free)");
17484                } else {
17485                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17486                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17487                            + memInfo.getFreeSizeKb()); pw.print(",");
17488                    pw.println(totalPss - cachedPss);
17489                }
17490            }
17491            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17492                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17493                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17494            if (!isCompact) {
17495                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17496                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17497                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17498                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17499                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17500            } else {
17501                pw.print("lostram,"); pw.println(lostRAM);
17502            }
17503            if (!brief) {
17504                if (memInfo.getZramTotalSizeKb() != 0) {
17505                    if (!isCompact) {
17506                        pw.print("     ZRAM: ");
17507                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17508                                pw.print(" physical used for ");
17509                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17510                                        - memInfo.getSwapFreeSizeKb()));
17511                                pw.print(" in swap (");
17512                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17513                                pw.println(" total swap)");
17514                    } else {
17515                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17516                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17517                                pw.println(memInfo.getSwapFreeSizeKb());
17518                    }
17519                }
17520                final long[] ksm = getKsmInfo();
17521                if (!isCompact) {
17522                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17523                            || ksm[KSM_VOLATILE] != 0) {
17524                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17525                                pw.print(" saved from shared ");
17526                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17527                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17528                                pw.print(" unshared; ");
17529                                pw.print(stringifyKBSize(
17530                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17531                    }
17532                    pw.print("   Tuning: ");
17533                    pw.print(ActivityManager.staticGetMemoryClass());
17534                    pw.print(" (large ");
17535                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17536                    pw.print("), oom ");
17537                    pw.print(stringifySize(
17538                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17539                    pw.print(", restore limit ");
17540                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17541                    if (ActivityManager.isLowRamDeviceStatic()) {
17542                        pw.print(" (low-ram)");
17543                    }
17544                    if (ActivityManager.isHighEndGfx()) {
17545                        pw.print(" (high-end-gfx)");
17546                    }
17547                    pw.println();
17548                } else {
17549                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17550                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17551                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17552                    pw.print("tuning,");
17553                    pw.print(ActivityManager.staticGetMemoryClass());
17554                    pw.print(',');
17555                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17556                    pw.print(',');
17557                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17558                    if (ActivityManager.isLowRamDeviceStatic()) {
17559                        pw.print(",low-ram");
17560                    }
17561                    if (ActivityManager.isHighEndGfx()) {
17562                        pw.print(",high-end-gfx");
17563                    }
17564                    pw.println();
17565                }
17566            }
17567        }
17568    }
17569
17570    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17571            long memtrack, String name) {
17572        sb.append("  ");
17573        sb.append(ProcessList.makeOomAdjString(oomAdj));
17574        sb.append(' ');
17575        sb.append(ProcessList.makeProcStateString(procState));
17576        sb.append(' ');
17577        ProcessList.appendRamKb(sb, pss);
17578        sb.append(": ");
17579        sb.append(name);
17580        if (memtrack > 0) {
17581            sb.append(" (");
17582            sb.append(stringifyKBSize(memtrack));
17583            sb.append(" memtrack)");
17584        }
17585    }
17586
17587    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17588        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17589        sb.append(" (pid ");
17590        sb.append(mi.pid);
17591        sb.append(") ");
17592        sb.append(mi.adjType);
17593        sb.append('\n');
17594        if (mi.adjReason != null) {
17595            sb.append("                      ");
17596            sb.append(mi.adjReason);
17597            sb.append('\n');
17598        }
17599    }
17600
17601    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17602        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17603        for (int i=0, N=memInfos.size(); i<N; i++) {
17604            ProcessMemInfo mi = memInfos.get(i);
17605            infoMap.put(mi.pid, mi);
17606        }
17607        updateCpuStatsNow();
17608        long[] memtrackTmp = new long[1];
17609        final List<ProcessCpuTracker.Stats> stats;
17610        // Get a list of Stats that have vsize > 0
17611        synchronized (mProcessCpuTracker) {
17612            stats = mProcessCpuTracker.getStats((st) -> {
17613                return st.vsize > 0;
17614            });
17615        }
17616        final int statsCount = stats.size();
17617        for (int i = 0; i < statsCount; i++) {
17618            ProcessCpuTracker.Stats st = stats.get(i);
17619            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17620            if (pss > 0) {
17621                if (infoMap.indexOfKey(st.pid) < 0) {
17622                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17623                            ProcessList.NATIVE_ADJ, -1, "native", null);
17624                    mi.pss = pss;
17625                    mi.memtrack = memtrackTmp[0];
17626                    memInfos.add(mi);
17627                }
17628            }
17629        }
17630
17631        long totalPss = 0;
17632        long totalMemtrack = 0;
17633        for (int i=0, N=memInfos.size(); i<N; i++) {
17634            ProcessMemInfo mi = memInfos.get(i);
17635            if (mi.pss == 0) {
17636                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17637                mi.memtrack = memtrackTmp[0];
17638            }
17639            totalPss += mi.pss;
17640            totalMemtrack += mi.memtrack;
17641        }
17642        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17643            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17644                if (lhs.oomAdj != rhs.oomAdj) {
17645                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17646                }
17647                if (lhs.pss != rhs.pss) {
17648                    return lhs.pss < rhs.pss ? 1 : -1;
17649                }
17650                return 0;
17651            }
17652        });
17653
17654        StringBuilder tag = new StringBuilder(128);
17655        StringBuilder stack = new StringBuilder(128);
17656        tag.append("Low on memory -- ");
17657        appendMemBucket(tag, totalPss, "total", false);
17658        appendMemBucket(stack, totalPss, "total", true);
17659
17660        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17661        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17662        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17663
17664        boolean firstLine = true;
17665        int lastOomAdj = Integer.MIN_VALUE;
17666        long extraNativeRam = 0;
17667        long extraNativeMemtrack = 0;
17668        long cachedPss = 0;
17669        for (int i=0, N=memInfos.size(); i<N; i++) {
17670            ProcessMemInfo mi = memInfos.get(i);
17671
17672            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17673                cachedPss += mi.pss;
17674            }
17675
17676            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17677                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17678                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17679                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17680                if (lastOomAdj != mi.oomAdj) {
17681                    lastOomAdj = mi.oomAdj;
17682                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17683                        tag.append(" / ");
17684                    }
17685                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17686                        if (firstLine) {
17687                            stack.append(":");
17688                            firstLine = false;
17689                        }
17690                        stack.append("\n\t at ");
17691                    } else {
17692                        stack.append("$");
17693                    }
17694                } else {
17695                    tag.append(" ");
17696                    stack.append("$");
17697                }
17698                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17699                    appendMemBucket(tag, mi.pss, mi.name, false);
17700                }
17701                appendMemBucket(stack, mi.pss, mi.name, true);
17702                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17703                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17704                    stack.append("(");
17705                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17706                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17707                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17708                            stack.append(":");
17709                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17710                        }
17711                    }
17712                    stack.append(")");
17713                }
17714            }
17715
17716            appendMemInfo(fullNativeBuilder, mi);
17717            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17718                // The short form only has native processes that are >= 512K.
17719                if (mi.pss >= 512) {
17720                    appendMemInfo(shortNativeBuilder, mi);
17721                } else {
17722                    extraNativeRam += mi.pss;
17723                    extraNativeMemtrack += mi.memtrack;
17724                }
17725            } else {
17726                // Short form has all other details, but if we have collected RAM
17727                // from smaller native processes let's dump a summary of that.
17728                if (extraNativeRam > 0) {
17729                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17730                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17731                    shortNativeBuilder.append('\n');
17732                    extraNativeRam = 0;
17733                }
17734                appendMemInfo(fullJavaBuilder, mi);
17735            }
17736        }
17737
17738        fullJavaBuilder.append("           ");
17739        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17740        fullJavaBuilder.append(": TOTAL");
17741        if (totalMemtrack > 0) {
17742            fullJavaBuilder.append(" (");
17743            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17744            fullJavaBuilder.append(" memtrack)");
17745        } else {
17746        }
17747        fullJavaBuilder.append("\n");
17748
17749        MemInfoReader memInfo = new MemInfoReader();
17750        memInfo.readMemInfo();
17751        final long[] infos = memInfo.getRawInfo();
17752
17753        StringBuilder memInfoBuilder = new StringBuilder(1024);
17754        Debug.getMemInfo(infos);
17755        memInfoBuilder.append("  MemInfo: ");
17756        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17757        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17758        memInfoBuilder.append(stringifyKBSize(
17759                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17760        memInfoBuilder.append(stringifyKBSize(
17761                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17762        memInfoBuilder.append(stringifyKBSize(
17763                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17764        memInfoBuilder.append("           ");
17765        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17766        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17767        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17768        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17769        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17770            memInfoBuilder.append("  ZRAM: ");
17771            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17772            memInfoBuilder.append(" RAM, ");
17773            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17774            memInfoBuilder.append(" swap total, ");
17775            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17776            memInfoBuilder.append(" swap free\n");
17777        }
17778        final long[] ksm = getKsmInfo();
17779        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17780                || ksm[KSM_VOLATILE] != 0) {
17781            memInfoBuilder.append("  KSM: ");
17782            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17783            memInfoBuilder.append(" saved from shared ");
17784            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17785            memInfoBuilder.append("\n       ");
17786            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17787            memInfoBuilder.append(" unshared; ");
17788            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17789            memInfoBuilder.append(" volatile\n");
17790        }
17791        memInfoBuilder.append("  Free RAM: ");
17792        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17793                + memInfo.getFreeSizeKb()));
17794        memInfoBuilder.append("\n");
17795        memInfoBuilder.append("  Used RAM: ");
17796        memInfoBuilder.append(stringifyKBSize(
17797                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17798        memInfoBuilder.append("\n");
17799        memInfoBuilder.append("  Lost RAM: ");
17800        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17801                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17802                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17803        memInfoBuilder.append("\n");
17804        Slog.i(TAG, "Low on memory:");
17805        Slog.i(TAG, shortNativeBuilder.toString());
17806        Slog.i(TAG, fullJavaBuilder.toString());
17807        Slog.i(TAG, memInfoBuilder.toString());
17808
17809        StringBuilder dropBuilder = new StringBuilder(1024);
17810        /*
17811        StringWriter oomSw = new StringWriter();
17812        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17813        StringWriter catSw = new StringWriter();
17814        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17815        String[] emptyArgs = new String[] { };
17816        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17817        oomPw.flush();
17818        String oomString = oomSw.toString();
17819        */
17820        dropBuilder.append("Low on memory:");
17821        dropBuilder.append(stack);
17822        dropBuilder.append('\n');
17823        dropBuilder.append(fullNativeBuilder);
17824        dropBuilder.append(fullJavaBuilder);
17825        dropBuilder.append('\n');
17826        dropBuilder.append(memInfoBuilder);
17827        dropBuilder.append('\n');
17828        /*
17829        dropBuilder.append(oomString);
17830        dropBuilder.append('\n');
17831        */
17832        StringWriter catSw = new StringWriter();
17833        synchronized (ActivityManagerService.this) {
17834            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17835            String[] emptyArgs = new String[] { };
17836            catPw.println();
17837            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17838            catPw.println();
17839            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17840                    false, null).dumpLocked();
17841            catPw.println();
17842            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17843            catPw.flush();
17844        }
17845        dropBuilder.append(catSw.toString());
17846        addErrorToDropBox("lowmem", null, "system_server", null,
17847                null, tag.toString(), dropBuilder.toString(), null, null);
17848        //Slog.i(TAG, "Sent to dropbox:");
17849        //Slog.i(TAG, dropBuilder.toString());
17850        synchronized (ActivityManagerService.this) {
17851            long now = SystemClock.uptimeMillis();
17852            if (mLastMemUsageReportTime < now) {
17853                mLastMemUsageReportTime = now;
17854            }
17855        }
17856    }
17857
17858    /**
17859     * Searches array of arguments for the specified string
17860     * @param args array of argument strings
17861     * @param value value to search for
17862     * @return true if the value is contained in the array
17863     */
17864    private static boolean scanArgs(String[] args, String value) {
17865        if (args != null) {
17866            for (String arg : args) {
17867                if (value.equals(arg)) {
17868                    return true;
17869                }
17870            }
17871        }
17872        return false;
17873    }
17874
17875    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17876            ContentProviderRecord cpr, boolean always) {
17877        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17878
17879        if (!inLaunching || always) {
17880            synchronized (cpr) {
17881                cpr.launchingApp = null;
17882                cpr.notifyAll();
17883            }
17884            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17885            String names[] = cpr.info.authority.split(";");
17886            for (int j = 0; j < names.length; j++) {
17887                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17888            }
17889        }
17890
17891        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17892            ContentProviderConnection conn = cpr.connections.get(i);
17893            if (conn.waiting) {
17894                // If this connection is waiting for the provider, then we don't
17895                // need to mess with its process unless we are always removing
17896                // or for some reason the provider is not currently launching.
17897                if (inLaunching && !always) {
17898                    continue;
17899                }
17900            }
17901            ProcessRecord capp = conn.client;
17902            conn.dead = true;
17903            if (conn.stableCount > 0) {
17904                if (!capp.persistent && capp.thread != null
17905                        && capp.pid != 0
17906                        && capp.pid != MY_PID) {
17907                    capp.kill("depends on provider "
17908                            + cpr.name.flattenToShortString()
17909                            + " in dying proc " + (proc != null ? proc.processName : "??")
17910                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17911                }
17912            } else if (capp.thread != null && conn.provider.provider != null) {
17913                try {
17914                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17915                } catch (RemoteException e) {
17916                }
17917                // In the protocol here, we don't expect the client to correctly
17918                // clean up this connection, we'll just remove it.
17919                cpr.connections.remove(i);
17920                if (conn.client.conProviders.remove(conn)) {
17921                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17922                }
17923            }
17924        }
17925
17926        if (inLaunching && always) {
17927            mLaunchingProviders.remove(cpr);
17928        }
17929        return inLaunching;
17930    }
17931
17932    /**
17933     * Main code for cleaning up a process when it has gone away.  This is
17934     * called both as a result of the process dying, or directly when stopping
17935     * a process when running in single process mode.
17936     *
17937     * @return Returns true if the given process has been restarted, so the
17938     * app that was passed in must remain on the process lists.
17939     */
17940    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17941            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17942        if (index >= 0) {
17943            removeLruProcessLocked(app);
17944            ProcessList.remove(app.pid);
17945        }
17946
17947        mProcessesToGc.remove(app);
17948        mPendingPssProcesses.remove(app);
17949
17950        // Dismiss any open dialogs.
17951        if (app.crashDialog != null && !app.forceCrashReport) {
17952            app.crashDialog.dismiss();
17953            app.crashDialog = null;
17954        }
17955        if (app.anrDialog != null) {
17956            app.anrDialog.dismiss();
17957            app.anrDialog = null;
17958        }
17959        if (app.waitDialog != null) {
17960            app.waitDialog.dismiss();
17961            app.waitDialog = null;
17962        }
17963
17964        app.crashing = false;
17965        app.notResponding = false;
17966
17967        app.resetPackageList(mProcessStats);
17968        app.unlinkDeathRecipient();
17969        app.makeInactive(mProcessStats);
17970        app.waitingToKill = null;
17971        app.forcingToImportant = null;
17972        updateProcessForegroundLocked(app, false, false);
17973        app.foregroundActivities = false;
17974        app.hasShownUi = false;
17975        app.treatLikeActivity = false;
17976        app.hasAboveClient = false;
17977        app.hasClientActivities = false;
17978
17979        mServices.killServicesLocked(app, allowRestart);
17980
17981        boolean restart = false;
17982
17983        // Remove published content providers.
17984        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17985            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17986            final boolean always = app.bad || !allowRestart;
17987            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17988            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17989                // We left the provider in the launching list, need to
17990                // restart it.
17991                restart = true;
17992            }
17993
17994            cpr.provider = null;
17995            cpr.proc = null;
17996        }
17997        app.pubProviders.clear();
17998
17999        // Take care of any launching providers waiting for this process.
18000        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18001            restart = true;
18002        }
18003
18004        // Unregister from connected content providers.
18005        if (!app.conProviders.isEmpty()) {
18006            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18007                ContentProviderConnection conn = app.conProviders.get(i);
18008                conn.provider.connections.remove(conn);
18009                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18010                        conn.provider.name);
18011            }
18012            app.conProviders.clear();
18013        }
18014
18015        // At this point there may be remaining entries in mLaunchingProviders
18016        // where we were the only one waiting, so they are no longer of use.
18017        // Look for these and clean up if found.
18018        // XXX Commented out for now.  Trying to figure out a way to reproduce
18019        // the actual situation to identify what is actually going on.
18020        if (false) {
18021            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18022                ContentProviderRecord cpr = mLaunchingProviders.get(i);
18023                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18024                    synchronized (cpr) {
18025                        cpr.launchingApp = null;
18026                        cpr.notifyAll();
18027                    }
18028                }
18029            }
18030        }
18031
18032        skipCurrentReceiverLocked(app);
18033
18034        // Unregister any receivers.
18035        for (int i = app.receivers.size() - 1; i >= 0; i--) {
18036            removeReceiverLocked(app.receivers.valueAt(i));
18037        }
18038        app.receivers.clear();
18039
18040        // If the app is undergoing backup, tell the backup manager about it
18041        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18042            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18043                    + mBackupTarget.appInfo + " died during backup");
18044            mHandler.post(new Runnable() {
18045                @Override
18046                public void run(){
18047                    try {
18048                        IBackupManager bm = IBackupManager.Stub.asInterface(
18049                                ServiceManager.getService(Context.BACKUP_SERVICE));
18050                        bm.agentDisconnected(app.info.packageName);
18051                    } catch (RemoteException e) {
18052                        // can't happen; backup manager is local
18053                    }
18054                }
18055            });
18056        }
18057
18058        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18059            ProcessChangeItem item = mPendingProcessChanges.get(i);
18060            if (item.pid == app.pid) {
18061                mPendingProcessChanges.remove(i);
18062                mAvailProcessChanges.add(item);
18063            }
18064        }
18065        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18066                null).sendToTarget();
18067
18068        // If the caller is restarting this app, then leave it in its
18069        // current lists and let the caller take care of it.
18070        if (restarting) {
18071            return false;
18072        }
18073
18074        if (!app.persistent || app.isolated) {
18075            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18076                    "Removing non-persistent process during cleanup: " + app);
18077            if (!replacingPid) {
18078                removeProcessNameLocked(app.processName, app.uid, app);
18079            }
18080            if (mHeavyWeightProcess == app) {
18081                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18082                        mHeavyWeightProcess.userId, 0));
18083                mHeavyWeightProcess = null;
18084            }
18085        } else if (!app.removed) {
18086            // This app is persistent, so we need to keep its record around.
18087            // If it is not already on the pending app list, add it there
18088            // and start a new process for it.
18089            if (mPersistentStartingProcesses.indexOf(app) < 0) {
18090                mPersistentStartingProcesses.add(app);
18091                restart = true;
18092            }
18093        }
18094        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18095                TAG_CLEANUP, "Clean-up removing on hold: " + app);
18096        mProcessesOnHold.remove(app);
18097
18098        if (app == mHomeProcess) {
18099            mHomeProcess = null;
18100        }
18101        if (app == mPreviousProcess) {
18102            mPreviousProcess = null;
18103        }
18104
18105        if (restart && !app.isolated) {
18106            // We have components that still need to be running in the
18107            // process, so re-launch it.
18108            if (index < 0) {
18109                ProcessList.remove(app.pid);
18110            }
18111            addProcessNameLocked(app);
18112            startProcessLocked(app, "restart", app.processName);
18113            return true;
18114        } else if (app.pid > 0 && app.pid != MY_PID) {
18115            // Goodbye!
18116            boolean removed;
18117            synchronized (mPidsSelfLocked) {
18118                mPidsSelfLocked.remove(app.pid);
18119                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18120            }
18121            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18122            if (app.isolated) {
18123                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18124            }
18125            app.setPid(0);
18126        }
18127        return false;
18128    }
18129
18130    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18131        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18132            ContentProviderRecord cpr = mLaunchingProviders.get(i);
18133            if (cpr.launchingApp == app) {
18134                return true;
18135            }
18136        }
18137        return false;
18138    }
18139
18140    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18141        // Look through the content providers we are waiting to have launched,
18142        // and if any run in this process then either schedule a restart of
18143        // the process or kill the client waiting for it if this process has
18144        // gone bad.
18145        boolean restart = false;
18146        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18147            ContentProviderRecord cpr = mLaunchingProviders.get(i);
18148            if (cpr.launchingApp == app) {
18149                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18150                    restart = true;
18151                } else {
18152                    removeDyingProviderLocked(app, cpr, true);
18153                }
18154            }
18155        }
18156        return restart;
18157    }
18158
18159    // =========================================================
18160    // SERVICES
18161    // =========================================================
18162
18163    @Override
18164    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18165            int flags) {
18166        enforceNotIsolatedCaller("getServices");
18167
18168        final int callingUid = Binder.getCallingUid();
18169        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18170            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18171        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18172            callingUid);
18173        synchronized (this) {
18174            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18175                allowed, canInteractAcrossUsers);
18176        }
18177    }
18178
18179    @Override
18180    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18181        enforceNotIsolatedCaller("getRunningServiceControlPanel");
18182        synchronized (this) {
18183            return mServices.getRunningServiceControlPanelLocked(name);
18184        }
18185    }
18186
18187    @Override
18188    public ComponentName startService(IApplicationThread caller, Intent service,
18189            String resolvedType, boolean requireForeground, String callingPackage, int userId)
18190            throws TransactionTooLargeException {
18191        enforceNotIsolatedCaller("startService");
18192        // Refuse possible leaked file descriptors
18193        if (service != null && service.hasFileDescriptors() == true) {
18194            throw new IllegalArgumentException("File descriptors passed in Intent");
18195        }
18196
18197        if (callingPackage == null) {
18198            throw new IllegalArgumentException("callingPackage cannot be null");
18199        }
18200
18201        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18202                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18203        synchronized(this) {
18204            final int callingPid = Binder.getCallingPid();
18205            final int callingUid = Binder.getCallingUid();
18206            final long origId = Binder.clearCallingIdentity();
18207            ComponentName res;
18208            try {
18209                res = mServices.startServiceLocked(caller, service,
18210                        resolvedType, callingPid, callingUid,
18211                        requireForeground, callingPackage, userId);
18212            } finally {
18213                Binder.restoreCallingIdentity(origId);
18214            }
18215            return res;
18216        }
18217    }
18218
18219    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18220            boolean fgRequired, String callingPackage, int userId)
18221            throws TransactionTooLargeException {
18222        synchronized(this) {
18223            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18224                    "startServiceInPackage: " + service + " type=" + resolvedType);
18225            final long origId = Binder.clearCallingIdentity();
18226            ComponentName res;
18227            try {
18228                res = mServices.startServiceLocked(null, service,
18229                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
18230            } finally {
18231                Binder.restoreCallingIdentity(origId);
18232            }
18233            return res;
18234        }
18235    }
18236
18237    @Override
18238    public int stopService(IApplicationThread caller, Intent service,
18239            String resolvedType, int userId) {
18240        enforceNotIsolatedCaller("stopService");
18241        // Refuse possible leaked file descriptors
18242        if (service != null && service.hasFileDescriptors() == true) {
18243            throw new IllegalArgumentException("File descriptors passed in Intent");
18244        }
18245
18246        synchronized(this) {
18247            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18248        }
18249    }
18250
18251    @Override
18252    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18253        enforceNotIsolatedCaller("peekService");
18254        // Refuse possible leaked file descriptors
18255        if (service != null && service.hasFileDescriptors() == true) {
18256            throw new IllegalArgumentException("File descriptors passed in Intent");
18257        }
18258
18259        if (callingPackage == null) {
18260            throw new IllegalArgumentException("callingPackage cannot be null");
18261        }
18262
18263        synchronized(this) {
18264            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18265        }
18266    }
18267
18268    @Override
18269    public boolean stopServiceToken(ComponentName className, IBinder token,
18270            int startId) {
18271        synchronized(this) {
18272            return mServices.stopServiceTokenLocked(className, token, startId);
18273        }
18274    }
18275
18276    @Override
18277    public void setServiceForeground(ComponentName className, IBinder token,
18278            int id, Notification notification, int flags) {
18279        synchronized(this) {
18280            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18281        }
18282    }
18283
18284    @Override
18285    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18286            boolean requireFull, String name, String callerPackage) {
18287        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18288                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18289    }
18290
18291    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18292            String className, int flags) {
18293        boolean result = false;
18294        // For apps that don't have pre-defined UIDs, check for permission
18295        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18296            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18297                if (ActivityManager.checkUidPermission(
18298                        INTERACT_ACROSS_USERS,
18299                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18300                    ComponentName comp = new ComponentName(aInfo.packageName, className);
18301                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
18302                            + " requests FLAG_SINGLE_USER, but app does not hold "
18303                            + INTERACT_ACROSS_USERS;
18304                    Slog.w(TAG, msg);
18305                    throw new SecurityException(msg);
18306                }
18307                // Permission passed
18308                result = true;
18309            }
18310        } else if ("system".equals(componentProcessName)) {
18311            result = true;
18312        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18313            // Phone app and persistent apps are allowed to export singleuser providers.
18314            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18315                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18316        }
18317        if (DEBUG_MU) Slog.v(TAG_MU,
18318                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18319                + Integer.toHexString(flags) + ") = " + result);
18320        return result;
18321    }
18322
18323    /**
18324     * Checks to see if the caller is in the same app as the singleton
18325     * component, or the component is in a special app. It allows special apps
18326     * to export singleton components but prevents exporting singleton
18327     * components for regular apps.
18328     */
18329    boolean isValidSingletonCall(int callingUid, int componentUid) {
18330        int componentAppId = UserHandle.getAppId(componentUid);
18331        return UserHandle.isSameApp(callingUid, componentUid)
18332                || componentAppId == SYSTEM_UID
18333                || componentAppId == PHONE_UID
18334                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18335                        == PackageManager.PERMISSION_GRANTED;
18336    }
18337
18338    public int bindService(IApplicationThread caller, IBinder token, Intent service,
18339            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18340            int userId) throws TransactionTooLargeException {
18341        enforceNotIsolatedCaller("bindService");
18342
18343        // Refuse possible leaked file descriptors
18344        if (service != null && service.hasFileDescriptors() == true) {
18345            throw new IllegalArgumentException("File descriptors passed in Intent");
18346        }
18347
18348        if (callingPackage == null) {
18349            throw new IllegalArgumentException("callingPackage cannot be null");
18350        }
18351
18352        synchronized(this) {
18353            return mServices.bindServiceLocked(caller, token, service,
18354                    resolvedType, connection, flags, callingPackage, userId);
18355        }
18356    }
18357
18358    public boolean unbindService(IServiceConnection connection) {
18359        synchronized (this) {
18360            return mServices.unbindServiceLocked(connection);
18361        }
18362    }
18363
18364    public void publishService(IBinder token, Intent intent, IBinder service) {
18365        // Refuse possible leaked file descriptors
18366        if (intent != null && intent.hasFileDescriptors() == true) {
18367            throw new IllegalArgumentException("File descriptors passed in Intent");
18368        }
18369
18370        synchronized(this) {
18371            if (!(token instanceof ServiceRecord)) {
18372                throw new IllegalArgumentException("Invalid service token");
18373            }
18374            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18375        }
18376    }
18377
18378    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18379        // Refuse possible leaked file descriptors
18380        if (intent != null && intent.hasFileDescriptors() == true) {
18381            throw new IllegalArgumentException("File descriptors passed in Intent");
18382        }
18383
18384        synchronized(this) {
18385            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18386        }
18387    }
18388
18389    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18390        synchronized(this) {
18391            if (!(token instanceof ServiceRecord)) {
18392                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18393                throw new IllegalArgumentException("Invalid service token");
18394            }
18395            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18396        }
18397    }
18398
18399    // =========================================================
18400    // BACKUP AND RESTORE
18401    // =========================================================
18402
18403    // Cause the target app to be launched if necessary and its backup agent
18404    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18405    // activity manager to announce its creation.
18406    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18407        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18408        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18409
18410        IPackageManager pm = AppGlobals.getPackageManager();
18411        ApplicationInfo app = null;
18412        try {
18413            app = pm.getApplicationInfo(packageName, 0, userId);
18414        } catch (RemoteException e) {
18415            // can't happen; package manager is process-local
18416        }
18417        if (app == null) {
18418            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18419            return false;
18420        }
18421
18422        int oldBackupUid;
18423        int newBackupUid;
18424
18425        synchronized(this) {
18426            // !!! TODO: currently no check here that we're already bound
18427            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18428            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18429            synchronized (stats) {
18430                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18431            }
18432
18433            // Backup agent is now in use, its package can't be stopped.
18434            try {
18435                AppGlobals.getPackageManager().setPackageStoppedState(
18436                        app.packageName, false, UserHandle.getUserId(app.uid));
18437            } catch (RemoteException e) {
18438            } catch (IllegalArgumentException e) {
18439                Slog.w(TAG, "Failed trying to unstop package "
18440                        + app.packageName + ": " + e);
18441            }
18442
18443            BackupRecord r = new BackupRecord(ss, app, backupMode);
18444            ComponentName hostingName =
18445                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18446                            ? new ComponentName(app.packageName, app.backupAgentName)
18447                            : new ComponentName("android", "FullBackupAgent");
18448            // startProcessLocked() returns existing proc's record if it's already running
18449            ProcessRecord proc = startProcessLocked(app.processName, app,
18450                    false, 0, "backup", hostingName, false, false, false);
18451            if (proc == null) {
18452                Slog.e(TAG, "Unable to start backup agent process " + r);
18453                return false;
18454            }
18455
18456            // If the app is a regular app (uid >= 10000) and not the system server or phone
18457            // process, etc, then mark it as being in full backup so that certain calls to the
18458            // process can be blocked. This is not reset to false anywhere because we kill the
18459            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18460            if (UserHandle.isApp(app.uid) &&
18461                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18462                proc.inFullBackup = true;
18463            }
18464            r.app = proc;
18465            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18466            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18467            mBackupTarget = r;
18468            mBackupAppName = app.packageName;
18469
18470            // Try not to kill the process during backup
18471            updateOomAdjLocked(proc, true);
18472
18473            // If the process is already attached, schedule the creation of the backup agent now.
18474            // If it is not yet live, this will be done when it attaches to the framework.
18475            if (proc.thread != null) {
18476                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18477                try {
18478                    proc.thread.scheduleCreateBackupAgent(app,
18479                            compatibilityInfoForPackageLocked(app), backupMode);
18480                } catch (RemoteException e) {
18481                    // Will time out on the backup manager side
18482                }
18483            } else {
18484                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18485            }
18486            // Invariants: at this point, the target app process exists and the application
18487            // is either already running or in the process of coming up.  mBackupTarget and
18488            // mBackupAppName describe the app, so that when it binds back to the AM we
18489            // know that it's scheduled for a backup-agent operation.
18490        }
18491
18492        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18493        if (oldBackupUid != -1) {
18494            js.removeBackingUpUid(oldBackupUid);
18495        }
18496        if (newBackupUid != -1) {
18497            js.addBackingUpUid(newBackupUid);
18498        }
18499
18500        return true;
18501    }
18502
18503    @Override
18504    public void clearPendingBackup() {
18505        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18506        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18507
18508        synchronized (this) {
18509            mBackupTarget = null;
18510            mBackupAppName = null;
18511        }
18512
18513        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18514        js.clearAllBackingUpUids();
18515    }
18516
18517    // A backup agent has just come up
18518    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18519        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18520                + " = " + agent);
18521
18522        synchronized(this) {
18523            if (!agentPackageName.equals(mBackupAppName)) {
18524                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18525                return;
18526            }
18527        }
18528
18529        long oldIdent = Binder.clearCallingIdentity();
18530        try {
18531            IBackupManager bm = IBackupManager.Stub.asInterface(
18532                    ServiceManager.getService(Context.BACKUP_SERVICE));
18533            bm.agentConnected(agentPackageName, agent);
18534        } catch (RemoteException e) {
18535            // can't happen; the backup manager service is local
18536        } catch (Exception e) {
18537            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18538            e.printStackTrace();
18539        } finally {
18540            Binder.restoreCallingIdentity(oldIdent);
18541        }
18542    }
18543
18544    // done with this agent
18545    public void unbindBackupAgent(ApplicationInfo appInfo) {
18546        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18547        if (appInfo == null) {
18548            Slog.w(TAG, "unbind backup agent for null app");
18549            return;
18550        }
18551
18552        int oldBackupUid;
18553
18554        synchronized(this) {
18555            try {
18556                if (mBackupAppName == null) {
18557                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18558                    return;
18559                }
18560
18561                if (!mBackupAppName.equals(appInfo.packageName)) {
18562                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18563                    return;
18564                }
18565
18566                // Not backing this app up any more; reset its OOM adjustment
18567                final ProcessRecord proc = mBackupTarget.app;
18568                updateOomAdjLocked(proc, true);
18569                proc.inFullBackup = false;
18570
18571                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18572
18573                // If the app crashed during backup, 'thread' will be null here
18574                if (proc.thread != null) {
18575                    try {
18576                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18577                                compatibilityInfoForPackageLocked(appInfo));
18578                    } catch (Exception e) {
18579                        Slog.e(TAG, "Exception when unbinding backup agent:");
18580                        e.printStackTrace();
18581                    }
18582                }
18583            } finally {
18584                mBackupTarget = null;
18585                mBackupAppName = null;
18586            }
18587        }
18588
18589        if (oldBackupUid != -1) {
18590            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18591            js.removeBackingUpUid(oldBackupUid);
18592        }
18593    }
18594
18595    // =========================================================
18596    // BROADCASTS
18597    // =========================================================
18598
18599    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18600        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18601            return false;
18602        }
18603        // Easy case -- we have the app's ProcessRecord.
18604        if (record != null) {
18605            return record.info.isInstantApp();
18606        }
18607        // Otherwise check with PackageManager.
18608        if (callerPackage == null) {
18609            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18610            throw new IllegalArgumentException("Calling application did not provide package name");
18611        }
18612        mAppOpsService.checkPackage(uid, callerPackage);
18613        try {
18614            IPackageManager pm = AppGlobals.getPackageManager();
18615            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18616        } catch (RemoteException e) {
18617            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18618            return true;
18619        }
18620    }
18621
18622    boolean isPendingBroadcastProcessLocked(int pid) {
18623        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18624                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18625    }
18626
18627    void skipPendingBroadcastLocked(int pid) {
18628            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18629            for (BroadcastQueue queue : mBroadcastQueues) {
18630                queue.skipPendingBroadcastLocked(pid);
18631            }
18632    }
18633
18634    // The app just attached; send any pending broadcasts that it should receive
18635    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18636        boolean didSomething = false;
18637        for (BroadcastQueue queue : mBroadcastQueues) {
18638            didSomething |= queue.sendPendingBroadcastsLocked(app);
18639        }
18640        return didSomething;
18641    }
18642
18643    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18644            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18645            int flags) {
18646        enforceNotIsolatedCaller("registerReceiver");
18647        ArrayList<Intent> stickyIntents = null;
18648        ProcessRecord callerApp = null;
18649        final boolean visibleToInstantApps
18650                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18651        int callingUid;
18652        int callingPid;
18653        boolean instantApp;
18654        synchronized(this) {
18655            if (caller != null) {
18656                callerApp = getRecordForAppLocked(caller);
18657                if (callerApp == null) {
18658                    throw new SecurityException(
18659                            "Unable to find app for caller " + caller
18660                            + " (pid=" + Binder.getCallingPid()
18661                            + ") when registering receiver " + receiver);
18662                }
18663                if (callerApp.info.uid != SYSTEM_UID &&
18664                        !callerApp.pkgList.containsKey(callerPackage) &&
18665                        !"android".equals(callerPackage)) {
18666                    throw new SecurityException("Given caller package " + callerPackage
18667                            + " is not running in process " + callerApp);
18668                }
18669                callingUid = callerApp.info.uid;
18670                callingPid = callerApp.pid;
18671            } else {
18672                callerPackage = null;
18673                callingUid = Binder.getCallingUid();
18674                callingPid = Binder.getCallingPid();
18675            }
18676
18677            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18678            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18679                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18680
18681            Iterator<String> actions = filter.actionsIterator();
18682            if (actions == null) {
18683                ArrayList<String> noAction = new ArrayList<String>(1);
18684                noAction.add(null);
18685                actions = noAction.iterator();
18686            }
18687
18688            // Collect stickies of users
18689            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18690            while (actions.hasNext()) {
18691                String action = actions.next();
18692                for (int id : userIds) {
18693                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18694                    if (stickies != null) {
18695                        ArrayList<Intent> intents = stickies.get(action);
18696                        if (intents != null) {
18697                            if (stickyIntents == null) {
18698                                stickyIntents = new ArrayList<Intent>();
18699                            }
18700                            stickyIntents.addAll(intents);
18701                        }
18702                    }
18703                }
18704            }
18705        }
18706
18707        ArrayList<Intent> allSticky = null;
18708        if (stickyIntents != null) {
18709            final ContentResolver resolver = mContext.getContentResolver();
18710            // Look for any matching sticky broadcasts...
18711            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18712                Intent intent = stickyIntents.get(i);
18713                // Don't provided intents that aren't available to instant apps.
18714                if (instantApp &&
18715                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18716                    continue;
18717                }
18718                // If intent has scheme "content", it will need to acccess
18719                // provider that needs to lock mProviderMap in ActivityThread
18720                // and also it may need to wait application response, so we
18721                // cannot lock ActivityManagerService here.
18722                if (filter.match(resolver, intent, true, TAG) >= 0) {
18723                    if (allSticky == null) {
18724                        allSticky = new ArrayList<Intent>();
18725                    }
18726                    allSticky.add(intent);
18727                }
18728            }
18729        }
18730
18731        // The first sticky in the list is returned directly back to the client.
18732        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18733        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18734        if (receiver == null) {
18735            return sticky;
18736        }
18737
18738        synchronized (this) {
18739            if (callerApp != null && (callerApp.thread == null
18740                    || callerApp.thread.asBinder() != caller.asBinder())) {
18741                // Original caller already died
18742                return null;
18743            }
18744            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18745            if (rl == null) {
18746                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18747                        userId, receiver);
18748                if (rl.app != null) {
18749                    rl.app.receivers.add(rl);
18750                } else {
18751                    try {
18752                        receiver.asBinder().linkToDeath(rl, 0);
18753                    } catch (RemoteException e) {
18754                        return sticky;
18755                    }
18756                    rl.linkedToDeath = true;
18757                }
18758                mRegisteredReceivers.put(receiver.asBinder(), rl);
18759            } else if (rl.uid != callingUid) {
18760                throw new IllegalArgumentException(
18761                        "Receiver requested to register for uid " + callingUid
18762                        + " was previously registered for uid " + rl.uid
18763                        + " callerPackage is " + callerPackage);
18764            } else if (rl.pid != callingPid) {
18765                throw new IllegalArgumentException(
18766                        "Receiver requested to register for pid " + callingPid
18767                        + " was previously registered for pid " + rl.pid
18768                        + " callerPackage is " + callerPackage);
18769            } else if (rl.userId != userId) {
18770                throw new IllegalArgumentException(
18771                        "Receiver requested to register for user " + userId
18772                        + " was previously registered for user " + rl.userId
18773                        + " callerPackage is " + callerPackage);
18774            }
18775            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18776                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18777            rl.add(bf);
18778            if (!bf.debugCheck()) {
18779                Slog.w(TAG, "==> For Dynamic broadcast");
18780            }
18781            mReceiverResolver.addFilter(bf);
18782
18783            // Enqueue broadcasts for all existing stickies that match
18784            // this filter.
18785            if (allSticky != null) {
18786                ArrayList receivers = new ArrayList();
18787                receivers.add(bf);
18788
18789                final int stickyCount = allSticky.size();
18790                for (int i = 0; i < stickyCount; i++) {
18791                    Intent intent = allSticky.get(i);
18792                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18793                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18794                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18795                            null, 0, null, null, false, true, true, -1);
18796                    queue.enqueueParallelBroadcastLocked(r);
18797                    queue.scheduleBroadcastsLocked();
18798                }
18799            }
18800
18801            return sticky;
18802        }
18803    }
18804
18805    public void unregisterReceiver(IIntentReceiver receiver) {
18806        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18807
18808        final long origId = Binder.clearCallingIdentity();
18809        try {
18810            boolean doTrim = false;
18811
18812            synchronized(this) {
18813                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18814                if (rl != null) {
18815                    final BroadcastRecord r = rl.curBroadcast;
18816                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18817                        final boolean doNext = r.queue.finishReceiverLocked(
18818                                r, r.resultCode, r.resultData, r.resultExtras,
18819                                r.resultAbort, false);
18820                        if (doNext) {
18821                            doTrim = true;
18822                            r.queue.processNextBroadcast(false);
18823                        }
18824                    }
18825
18826                    if (rl.app != null) {
18827                        rl.app.receivers.remove(rl);
18828                    }
18829                    removeReceiverLocked(rl);
18830                    if (rl.linkedToDeath) {
18831                        rl.linkedToDeath = false;
18832                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18833                    }
18834                }
18835            }
18836
18837            // If we actually concluded any broadcasts, we might now be able
18838            // to trim the recipients' apps from our working set
18839            if (doTrim) {
18840                trimApplications();
18841                return;
18842            }
18843
18844        } finally {
18845            Binder.restoreCallingIdentity(origId);
18846        }
18847    }
18848
18849    void removeReceiverLocked(ReceiverList rl) {
18850        mRegisteredReceivers.remove(rl.receiver.asBinder());
18851        for (int i = rl.size() - 1; i >= 0; i--) {
18852            mReceiverResolver.removeFilter(rl.get(i));
18853        }
18854    }
18855
18856    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18857        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18858            ProcessRecord r = mLruProcesses.get(i);
18859            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18860                try {
18861                    r.thread.dispatchPackageBroadcast(cmd, packages);
18862                } catch (RemoteException ex) {
18863                }
18864            }
18865        }
18866    }
18867
18868    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18869            int callingUid, int[] users) {
18870        // TODO: come back and remove this assumption to triage all broadcasts
18871        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18872
18873        List<ResolveInfo> receivers = null;
18874        try {
18875            HashSet<ComponentName> singleUserReceivers = null;
18876            boolean scannedFirstReceivers = false;
18877            for (int user : users) {
18878                // Skip users that have Shell restrictions, with exception of always permitted
18879                // Shell broadcasts
18880                if (callingUid == SHELL_UID
18881                        && mUserController.hasUserRestriction(
18882                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18883                        && !isPermittedShellBroadcast(intent)) {
18884                    continue;
18885                }
18886                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18887                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18888                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18889                    // If this is not the system user, we need to check for
18890                    // any receivers that should be filtered out.
18891                    for (int i=0; i<newReceivers.size(); i++) {
18892                        ResolveInfo ri = newReceivers.get(i);
18893                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18894                            newReceivers.remove(i);
18895                            i--;
18896                        }
18897                    }
18898                }
18899                if (newReceivers != null && newReceivers.size() == 0) {
18900                    newReceivers = null;
18901                }
18902                if (receivers == null) {
18903                    receivers = newReceivers;
18904                } else if (newReceivers != null) {
18905                    // We need to concatenate the additional receivers
18906                    // found with what we have do far.  This would be easy,
18907                    // but we also need to de-dup any receivers that are
18908                    // singleUser.
18909                    if (!scannedFirstReceivers) {
18910                        // Collect any single user receivers we had already retrieved.
18911                        scannedFirstReceivers = true;
18912                        for (int i=0; i<receivers.size(); i++) {
18913                            ResolveInfo ri = receivers.get(i);
18914                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18915                                ComponentName cn = new ComponentName(
18916                                        ri.activityInfo.packageName, ri.activityInfo.name);
18917                                if (singleUserReceivers == null) {
18918                                    singleUserReceivers = new HashSet<ComponentName>();
18919                                }
18920                                singleUserReceivers.add(cn);
18921                            }
18922                        }
18923                    }
18924                    // Add the new results to the existing results, tracking
18925                    // and de-dupping single user receivers.
18926                    for (int i=0; i<newReceivers.size(); i++) {
18927                        ResolveInfo ri = newReceivers.get(i);
18928                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18929                            ComponentName cn = new ComponentName(
18930                                    ri.activityInfo.packageName, ri.activityInfo.name);
18931                            if (singleUserReceivers == null) {
18932                                singleUserReceivers = new HashSet<ComponentName>();
18933                            }
18934                            if (!singleUserReceivers.contains(cn)) {
18935                                singleUserReceivers.add(cn);
18936                                receivers.add(ri);
18937                            }
18938                        } else {
18939                            receivers.add(ri);
18940                        }
18941                    }
18942                }
18943            }
18944        } catch (RemoteException ex) {
18945            // pm is in same process, this will never happen.
18946        }
18947        return receivers;
18948    }
18949
18950    private boolean isPermittedShellBroadcast(Intent intent) {
18951        // remote bugreport should always be allowed to be taken
18952        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18953    }
18954
18955    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18956            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18957        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18958            // Don't yell about broadcasts sent via shell
18959            return;
18960        }
18961
18962        final String action = intent.getAction();
18963        if (isProtectedBroadcast
18964                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18965                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18966                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18967                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18968                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18969                || Intent.ACTION_MASTER_CLEAR.equals(action)
18970                || Intent.ACTION_FACTORY_RESET.equals(action)
18971                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18972                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18973                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18974                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18975                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18976                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18977                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18978            // Broadcast is either protected, or it's a public action that
18979            // we've relaxed, so it's fine for system internals to send.
18980            return;
18981        }
18982
18983        // This broadcast may be a problem...  but there are often system components that
18984        // want to send an internal broadcast to themselves, which is annoying to have to
18985        // explicitly list each action as a protected broadcast, so we will check for that
18986        // one safe case and allow it: an explicit broadcast, only being received by something
18987        // that has protected itself.
18988        if (receivers != null && receivers.size() > 0
18989                && (intent.getPackage() != null || intent.getComponent() != null)) {
18990            boolean allProtected = true;
18991            for (int i = receivers.size()-1; i >= 0; i--) {
18992                Object target = receivers.get(i);
18993                if (target instanceof ResolveInfo) {
18994                    ResolveInfo ri = (ResolveInfo)target;
18995                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18996                        allProtected = false;
18997                        break;
18998                    }
18999                } else {
19000                    BroadcastFilter bf = (BroadcastFilter)target;
19001                    if (bf.requiredPermission == null) {
19002                        allProtected = false;
19003                        break;
19004                    }
19005                }
19006            }
19007            if (allProtected) {
19008                // All safe!
19009                return;
19010            }
19011        }
19012
19013        // The vast majority of broadcasts sent from system internals
19014        // should be protected to avoid security holes, so yell loudly
19015        // to ensure we examine these cases.
19016        if (callerApp != null) {
19017            Log.wtf(TAG, "Sending non-protected broadcast " + action
19018                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19019                    new Throwable());
19020        } else {
19021            Log.wtf(TAG, "Sending non-protected broadcast " + action
19022                            + " from system uid " + UserHandle.formatUid(callingUid)
19023                            + " pkg " + callerPackage,
19024                    new Throwable());
19025        }
19026    }
19027
19028    final int broadcastIntentLocked(ProcessRecord callerApp,
19029            String callerPackage, Intent intent, String resolvedType,
19030            IIntentReceiver resultTo, int resultCode, String resultData,
19031            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19032            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19033        intent = new Intent(intent);
19034
19035        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19036        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19037        if (callerInstantApp) {
19038            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19039        }
19040
19041        // By default broadcasts do not go to stopped apps.
19042        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19043
19044        // If we have not finished booting, don't allow this to launch new processes.
19045        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19046            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19047        }
19048
19049        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19050                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19051                + " ordered=" + ordered + " userid=" + userId);
19052        if ((resultTo != null) && !ordered) {
19053            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19054        }
19055
19056        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19057                ALLOW_NON_FULL, "broadcast", callerPackage);
19058
19059        // Make sure that the user who is receiving this broadcast is running.
19060        // If not, we will just skip it. Make an exception for shutdown broadcasts
19061        // and upgrade steps.
19062
19063        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19064            if ((callingUid != SYSTEM_UID
19065                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19066                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19067                Slog.w(TAG, "Skipping broadcast of " + intent
19068                        + ": user " + userId + " is stopped");
19069                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19070            }
19071        }
19072
19073        BroadcastOptions brOptions = null;
19074        if (bOptions != null) {
19075            brOptions = new BroadcastOptions(bOptions);
19076            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19077                // See if the caller is allowed to do this.  Note we are checking against
19078                // the actual real caller (not whoever provided the operation as say a
19079                // PendingIntent), because that who is actually supplied the arguments.
19080                if (checkComponentPermission(
19081                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19082                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19083                        != PackageManager.PERMISSION_GRANTED) {
19084                    String msg = "Permission Denial: " + intent.getAction()
19085                            + " broadcast from " + callerPackage + " (pid=" + callingPid
19086                            + ", uid=" + callingUid + ")"
19087                            + " requires "
19088                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19089                    Slog.w(TAG, msg);
19090                    throw new SecurityException(msg);
19091                }
19092            }
19093        }
19094
19095        // Verify that protected broadcasts are only being sent by system code,
19096        // and that system code is only sending protected broadcasts.
19097        final String action = intent.getAction();
19098        final boolean isProtectedBroadcast;
19099        try {
19100            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19101        } catch (RemoteException e) {
19102            Slog.w(TAG, "Remote exception", e);
19103            return ActivityManager.BROADCAST_SUCCESS;
19104        }
19105
19106        final boolean isCallerSystem;
19107        switch (UserHandle.getAppId(callingUid)) {
19108            case ROOT_UID:
19109            case SYSTEM_UID:
19110            case PHONE_UID:
19111            case BLUETOOTH_UID:
19112            case NFC_UID:
19113                isCallerSystem = true;
19114                break;
19115            default:
19116                isCallerSystem = (callerApp != null) && callerApp.persistent;
19117                break;
19118        }
19119
19120        // First line security check before anything else: stop non-system apps from
19121        // sending protected broadcasts.
19122        if (!isCallerSystem) {
19123            if (isProtectedBroadcast) {
19124                String msg = "Permission Denial: not allowed to send broadcast "
19125                        + action + " from pid="
19126                        + callingPid + ", uid=" + callingUid;
19127                Slog.w(TAG, msg);
19128                throw new SecurityException(msg);
19129
19130            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19131                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19132                // Special case for compatibility: we don't want apps to send this,
19133                // but historically it has not been protected and apps may be using it
19134                // to poke their own app widget.  So, instead of making it protected,
19135                // just limit it to the caller.
19136                if (callerPackage == null) {
19137                    String msg = "Permission Denial: not allowed to send broadcast "
19138                            + action + " from unknown caller.";
19139                    Slog.w(TAG, msg);
19140                    throw new SecurityException(msg);
19141                } else if (intent.getComponent() != null) {
19142                    // They are good enough to send to an explicit component...  verify
19143                    // it is being sent to the calling app.
19144                    if (!intent.getComponent().getPackageName().equals(
19145                            callerPackage)) {
19146                        String msg = "Permission Denial: not allowed to send broadcast "
19147                                + action + " to "
19148                                + intent.getComponent().getPackageName() + " from "
19149                                + callerPackage;
19150                        Slog.w(TAG, msg);
19151                        throw new SecurityException(msg);
19152                    }
19153                } else {
19154                    // Limit broadcast to their own package.
19155                    intent.setPackage(callerPackage);
19156                }
19157            }
19158        }
19159
19160        if (action != null) {
19161            if (getBackgroundLaunchBroadcasts().contains(action)) {
19162                if (DEBUG_BACKGROUND_CHECK) {
19163                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19164                }
19165                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19166            }
19167
19168            switch (action) {
19169                case Intent.ACTION_UID_REMOVED:
19170                case Intent.ACTION_PACKAGE_REMOVED:
19171                case Intent.ACTION_PACKAGE_CHANGED:
19172                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19173                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19174                case Intent.ACTION_PACKAGES_SUSPENDED:
19175                case Intent.ACTION_PACKAGES_UNSUSPENDED:
19176                    // Handle special intents: if this broadcast is from the package
19177                    // manager about a package being removed, we need to remove all of
19178                    // its activities from the history stack.
19179                    if (checkComponentPermission(
19180                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19181                            callingPid, callingUid, -1, true)
19182                            != PackageManager.PERMISSION_GRANTED) {
19183                        String msg = "Permission Denial: " + intent.getAction()
19184                                + " broadcast from " + callerPackage + " (pid=" + callingPid
19185                                + ", uid=" + callingUid + ")"
19186                                + " requires "
19187                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19188                        Slog.w(TAG, msg);
19189                        throw new SecurityException(msg);
19190                    }
19191                    switch (action) {
19192                        case Intent.ACTION_UID_REMOVED:
19193                            final int uid = getUidFromIntent(intent);
19194                            if (uid >= 0) {
19195                                mBatteryStatsService.removeUid(uid);
19196                                mAppOpsService.uidRemoved(uid);
19197                            }
19198                            break;
19199                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19200                            // If resources are unavailable just force stop all those packages
19201                            // and flush the attribute cache as well.
19202                            String list[] =
19203                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19204                            if (list != null && list.length > 0) {
19205                                for (int i = 0; i < list.length; i++) {
19206                                    forceStopPackageLocked(list[i], -1, false, true, true,
19207                                            false, false, userId, "storage unmount");
19208                                }
19209                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19210                                sendPackageBroadcastLocked(
19211                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19212                                        list, userId);
19213                            }
19214                            break;
19215                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19216                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19217                            break;
19218                        case Intent.ACTION_PACKAGE_REMOVED:
19219                        case Intent.ACTION_PACKAGE_CHANGED:
19220                            Uri data = intent.getData();
19221                            String ssp;
19222                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19223                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19224                                final boolean replacing =
19225                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19226                                final boolean killProcess =
19227                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19228                                final boolean fullUninstall = removed && !replacing;
19229                                if (removed) {
19230                                    if (killProcess) {
19231                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
19232                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19233                                                false, true, true, false, fullUninstall, userId,
19234                                                removed ? "pkg removed" : "pkg changed");
19235                                    }
19236                                    final int cmd = killProcess
19237                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
19238                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19239                                    sendPackageBroadcastLocked(cmd,
19240                                            new String[] {ssp}, userId);
19241                                    if (fullUninstall) {
19242                                        mAppOpsService.packageRemoved(
19243                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19244
19245                                        // Remove all permissions granted from/to this package
19246                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
19247
19248                                        removeTasksByPackageNameLocked(ssp, userId);
19249
19250                                        mServices.forceStopPackageLocked(ssp, userId);
19251
19252                                        // Hide the "unsupported display" dialog if necessary.
19253                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19254                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19255                                            mUnsupportedDisplaySizeDialog.dismiss();
19256                                            mUnsupportedDisplaySizeDialog = null;
19257                                        }
19258                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
19259                                        mBatteryStatsService.notePackageUninstalled(ssp);
19260                                    }
19261                                } else {
19262                                    if (killProcess) {
19263                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
19264                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19265                                                userId, ProcessList.INVALID_ADJ,
19266                                                false, true, true, false, "change " + ssp);
19267                                    }
19268                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19269                                            intent.getStringArrayExtra(
19270                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19271                                }
19272                            }
19273                            break;
19274                        case Intent.ACTION_PACKAGES_SUSPENDED:
19275                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
19276                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19277                                    intent.getAction());
19278                            final String[] packageNames = intent.getStringArrayExtra(
19279                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
19280                            final int userHandle = intent.getIntExtra(
19281                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19282
19283                            synchronized(ActivityManagerService.this) {
19284                                mRecentTasks.onPackagesSuspendedChanged(
19285                                        packageNames, suspended, userHandle);
19286                            }
19287                            break;
19288                    }
19289                    break;
19290                case Intent.ACTION_PACKAGE_REPLACED:
19291                {
19292                    final Uri data = intent.getData();
19293                    final String ssp;
19294                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19295                        ApplicationInfo aInfo = null;
19296                        try {
19297                            aInfo = AppGlobals.getPackageManager()
19298                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
19299                        } catch (RemoteException ignore) {}
19300                        if (aInfo == null) {
19301                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19302                                    + " ssp=" + ssp + " data=" + data);
19303                            return ActivityManager.BROADCAST_SUCCESS;
19304                        }
19305                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19306                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19307                                new String[] {ssp}, userId);
19308                    }
19309                    break;
19310                }
19311                case Intent.ACTION_PACKAGE_ADDED:
19312                {
19313                    // Special case for adding a package: by default turn on compatibility mode.
19314                    Uri data = intent.getData();
19315                    String ssp;
19316                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19317                        final boolean replacing =
19318                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19319                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19320
19321                        try {
19322                            ApplicationInfo ai = AppGlobals.getPackageManager().
19323                                    getApplicationInfo(ssp, 0, 0);
19324                            mBatteryStatsService.notePackageInstalled(ssp,
19325                                    ai != null ? ai.versionCode : 0);
19326                        } catch (RemoteException e) {
19327                        }
19328                    }
19329                    break;
19330                }
19331                case Intent.ACTION_PACKAGE_DATA_CLEARED:
19332                {
19333                    Uri data = intent.getData();
19334                    String ssp;
19335                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19336                        // Hide the "unsupported display" dialog if necessary.
19337                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19338                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19339                            mUnsupportedDisplaySizeDialog.dismiss();
19340                            mUnsupportedDisplaySizeDialog = null;
19341                        }
19342                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
19343                    }
19344                    break;
19345                }
19346                case Intent.ACTION_TIMEZONE_CHANGED:
19347                    // If this is the time zone changed action, queue up a message that will reset
19348                    // the timezone of all currently running processes. This message will get
19349                    // queued up before the broadcast happens.
19350                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19351                    break;
19352                case Intent.ACTION_TIME_CHANGED:
19353                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19354                    // the tri-state value it may contain and "unknown".
19355                    // For convenience we re-use the Intent extra values.
19356                    final int NO_EXTRA_VALUE_FOUND = -1;
19357                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19358                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19359                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
19360                    // Only send a message if the time preference is available.
19361                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19362                        Message updateTimePreferenceMsg =
19363                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19364                                        timeFormatPreferenceMsgValue, 0);
19365                        mHandler.sendMessage(updateTimePreferenceMsg);
19366                    }
19367                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19368                    synchronized (stats) {
19369                        stats.noteCurrentTimeChangedLocked();
19370                    }
19371                    break;
19372                case Intent.ACTION_CLEAR_DNS_CACHE:
19373                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19374                    break;
19375                case Proxy.PROXY_CHANGE_ACTION:
19376                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19377                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19378                    break;
19379                case android.hardware.Camera.ACTION_NEW_PICTURE:
19380                case android.hardware.Camera.ACTION_NEW_VIDEO:
19381                    // In N we just turned these off; in O we are turing them back on partly,
19382                    // only for registered receivers.  This will still address the main problem
19383                    // (a spam of apps waking up when a picture is taken putting significant
19384                    // memory pressure on the system at a bad point), while still allowing apps
19385                    // that are already actively running to know about this happening.
19386                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19387                    break;
19388                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19389                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19390                    break;
19391                case "com.android.launcher.action.INSTALL_SHORTCUT":
19392                    // As of O, we no longer support this broadcasts, even for pre-O apps.
19393                    // Apps should now be using ShortcutManager.pinRequestShortcut().
19394                    Log.w(TAG, "Broadcast " + action
19395                            + " no longer supported. It will not be delivered.");
19396                    return ActivityManager.BROADCAST_SUCCESS;
19397            }
19398
19399            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19400                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19401                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19402                final int uid = getUidFromIntent(intent);
19403                if (uid != -1) {
19404                    final UidRecord uidRec = mActiveUids.get(uid);
19405                    if (uidRec != null) {
19406                        uidRec.updateHasInternetPermission();
19407                    }
19408                }
19409            }
19410        }
19411
19412        // Add to the sticky list if requested.
19413        if (sticky) {
19414            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19415                    callingPid, callingUid)
19416                    != PackageManager.PERMISSION_GRANTED) {
19417                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19418                        + callingPid + ", uid=" + callingUid
19419                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19420                Slog.w(TAG, msg);
19421                throw new SecurityException(msg);
19422            }
19423            if (requiredPermissions != null && requiredPermissions.length > 0) {
19424                Slog.w(TAG, "Can't broadcast sticky intent " + intent
19425                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19426                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19427            }
19428            if (intent.getComponent() != null) {
19429                throw new SecurityException(
19430                        "Sticky broadcasts can't target a specific component");
19431            }
19432            // We use userId directly here, since the "all" target is maintained
19433            // as a separate set of sticky broadcasts.
19434            if (userId != UserHandle.USER_ALL) {
19435                // But first, if this is not a broadcast to all users, then
19436                // make sure it doesn't conflict with an existing broadcast to
19437                // all users.
19438                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19439                        UserHandle.USER_ALL);
19440                if (stickies != null) {
19441                    ArrayList<Intent> list = stickies.get(intent.getAction());
19442                    if (list != null) {
19443                        int N = list.size();
19444                        int i;
19445                        for (i=0; i<N; i++) {
19446                            if (intent.filterEquals(list.get(i))) {
19447                                throw new IllegalArgumentException(
19448                                        "Sticky broadcast " + intent + " for user "
19449                                        + userId + " conflicts with existing global broadcast");
19450                            }
19451                        }
19452                    }
19453                }
19454            }
19455            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19456            if (stickies == null) {
19457                stickies = new ArrayMap<>();
19458                mStickyBroadcasts.put(userId, stickies);
19459            }
19460            ArrayList<Intent> list = stickies.get(intent.getAction());
19461            if (list == null) {
19462                list = new ArrayList<>();
19463                stickies.put(intent.getAction(), list);
19464            }
19465            final int stickiesCount = list.size();
19466            int i;
19467            for (i = 0; i < stickiesCount; i++) {
19468                if (intent.filterEquals(list.get(i))) {
19469                    // This sticky already exists, replace it.
19470                    list.set(i, new Intent(intent));
19471                    break;
19472                }
19473            }
19474            if (i >= stickiesCount) {
19475                list.add(new Intent(intent));
19476            }
19477        }
19478
19479        int[] users;
19480        if (userId == UserHandle.USER_ALL) {
19481            // Caller wants broadcast to go to all started users.
19482            users = mUserController.getStartedUserArrayLocked();
19483        } else {
19484            // Caller wants broadcast to go to one specific user.
19485            users = new int[] {userId};
19486        }
19487
19488        // Figure out who all will receive this broadcast.
19489        List receivers = null;
19490        List<BroadcastFilter> registeredReceivers = null;
19491        // Need to resolve the intent to interested receivers...
19492        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19493                 == 0) {
19494            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19495        }
19496        if (intent.getComponent() == null) {
19497            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19498                // Query one target user at a time, excluding shell-restricted users
19499                for (int i = 0; i < users.length; i++) {
19500                    if (mUserController.hasUserRestriction(
19501                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19502                        continue;
19503                    }
19504                    List<BroadcastFilter> registeredReceiversForUser =
19505                            mReceiverResolver.queryIntent(intent,
19506                                    resolvedType, false /*defaultOnly*/, users[i]);
19507                    if (registeredReceivers == null) {
19508                        registeredReceivers = registeredReceiversForUser;
19509                    } else if (registeredReceiversForUser != null) {
19510                        registeredReceivers.addAll(registeredReceiversForUser);
19511                    }
19512                }
19513            } else {
19514                registeredReceivers = mReceiverResolver.queryIntent(intent,
19515                        resolvedType, false /*defaultOnly*/, userId);
19516            }
19517        }
19518
19519        final boolean replacePending =
19520                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19521
19522        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19523                + " replacePending=" + replacePending);
19524
19525        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19526        if (!ordered && NR > 0) {
19527            // If we are not serializing this broadcast, then send the
19528            // registered receivers separately so they don't wait for the
19529            // components to be launched.
19530            if (isCallerSystem) {
19531                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19532                        isProtectedBroadcast, registeredReceivers);
19533            }
19534            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19535            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19536                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19537                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19538                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19539            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19540            final boolean replaced = replacePending
19541                    && (queue.replaceParallelBroadcastLocked(r) != null);
19542            // Note: We assume resultTo is null for non-ordered broadcasts.
19543            if (!replaced) {
19544                queue.enqueueParallelBroadcastLocked(r);
19545                queue.scheduleBroadcastsLocked();
19546            }
19547            registeredReceivers = null;
19548            NR = 0;
19549        }
19550
19551        // Merge into one list.
19552        int ir = 0;
19553        if (receivers != null) {
19554            // A special case for PACKAGE_ADDED: do not allow the package
19555            // being added to see this broadcast.  This prevents them from
19556            // using this as a back door to get run as soon as they are
19557            // installed.  Maybe in the future we want to have a special install
19558            // broadcast or such for apps, but we'd like to deliberately make
19559            // this decision.
19560            String skipPackages[] = null;
19561            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19562                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19563                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19564                Uri data = intent.getData();
19565                if (data != null) {
19566                    String pkgName = data.getSchemeSpecificPart();
19567                    if (pkgName != null) {
19568                        skipPackages = new String[] { pkgName };
19569                    }
19570                }
19571            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19572                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19573            }
19574            if (skipPackages != null && (skipPackages.length > 0)) {
19575                for (String skipPackage : skipPackages) {
19576                    if (skipPackage != null) {
19577                        int NT = receivers.size();
19578                        for (int it=0; it<NT; it++) {
19579                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19580                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19581                                receivers.remove(it);
19582                                it--;
19583                                NT--;
19584                            }
19585                        }
19586                    }
19587                }
19588            }
19589
19590            int NT = receivers != null ? receivers.size() : 0;
19591            int it = 0;
19592            ResolveInfo curt = null;
19593            BroadcastFilter curr = null;
19594            while (it < NT && ir < NR) {
19595                if (curt == null) {
19596                    curt = (ResolveInfo)receivers.get(it);
19597                }
19598                if (curr == null) {
19599                    curr = registeredReceivers.get(ir);
19600                }
19601                if (curr.getPriority() >= curt.priority) {
19602                    // Insert this broadcast record into the final list.
19603                    receivers.add(it, curr);
19604                    ir++;
19605                    curr = null;
19606                    it++;
19607                    NT++;
19608                } else {
19609                    // Skip to the next ResolveInfo in the final list.
19610                    it++;
19611                    curt = null;
19612                }
19613            }
19614        }
19615        while (ir < NR) {
19616            if (receivers == null) {
19617                receivers = new ArrayList();
19618            }
19619            receivers.add(registeredReceivers.get(ir));
19620            ir++;
19621        }
19622
19623        if (isCallerSystem) {
19624            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19625                    isProtectedBroadcast, receivers);
19626        }
19627
19628        if ((receivers != null && receivers.size() > 0)
19629                || resultTo != null) {
19630            BroadcastQueue queue = broadcastQueueForIntent(intent);
19631            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19632                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19633                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19634                    resultData, resultExtras, ordered, sticky, false, userId);
19635
19636            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19637                    + ": prev had " + queue.mOrderedBroadcasts.size());
19638            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19639                    "Enqueueing broadcast " + r.intent.getAction());
19640
19641            final BroadcastRecord oldRecord =
19642                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19643            if (oldRecord != null) {
19644                // Replaced, fire the result-to receiver.
19645                if (oldRecord.resultTo != null) {
19646                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19647                    try {
19648                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19649                                oldRecord.intent,
19650                                Activity.RESULT_CANCELED, null, null,
19651                                false, false, oldRecord.userId);
19652                    } catch (RemoteException e) {
19653                        Slog.w(TAG, "Failure ["
19654                                + queue.mQueueName + "] sending broadcast result of "
19655                                + intent, e);
19656
19657                    }
19658                }
19659            } else {
19660                queue.enqueueOrderedBroadcastLocked(r);
19661                queue.scheduleBroadcastsLocked();
19662            }
19663        } else {
19664            // There was nobody interested in the broadcast, but we still want to record
19665            // that it happened.
19666            if (intent.getComponent() == null && intent.getPackage() == null
19667                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19668                // This was an implicit broadcast... let's record it for posterity.
19669                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19670            }
19671        }
19672
19673        return ActivityManager.BROADCAST_SUCCESS;
19674    }
19675
19676    /**
19677     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19678     */
19679    private int getUidFromIntent(Intent intent) {
19680        if (intent == null) {
19681            return -1;
19682        }
19683        final Bundle intentExtras = intent.getExtras();
19684        return intent.hasExtra(Intent.EXTRA_UID)
19685                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19686    }
19687
19688    final void rotateBroadcastStatsIfNeededLocked() {
19689        final long now = SystemClock.elapsedRealtime();
19690        if (mCurBroadcastStats == null ||
19691                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19692            mLastBroadcastStats = mCurBroadcastStats;
19693            if (mLastBroadcastStats != null) {
19694                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19695                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19696            }
19697            mCurBroadcastStats = new BroadcastStats();
19698        }
19699    }
19700
19701    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19702            int skipCount, long dispatchTime) {
19703        rotateBroadcastStatsIfNeededLocked();
19704        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19705    }
19706
19707    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19708        rotateBroadcastStatsIfNeededLocked();
19709        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19710    }
19711
19712    final Intent verifyBroadcastLocked(Intent intent) {
19713        // Refuse possible leaked file descriptors
19714        if (intent != null && intent.hasFileDescriptors() == true) {
19715            throw new IllegalArgumentException("File descriptors passed in Intent");
19716        }
19717
19718        int flags = intent.getFlags();
19719
19720        if (!mProcessesReady) {
19721            // if the caller really truly claims to know what they're doing, go
19722            // ahead and allow the broadcast without launching any receivers
19723            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19724                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19725            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19726                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19727                        + " before boot completion");
19728                throw new IllegalStateException("Cannot broadcast before boot completed");
19729            }
19730        }
19731
19732        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19733            throw new IllegalArgumentException(
19734                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19735        }
19736
19737        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19738            switch (Binder.getCallingUid()) {
19739                case ROOT_UID:
19740                case SHELL_UID:
19741                    break;
19742                default:
19743                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19744                            + Binder.getCallingUid());
19745                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19746                    break;
19747            }
19748        }
19749
19750        return intent;
19751    }
19752
19753    public final int broadcastIntent(IApplicationThread caller,
19754            Intent intent, String resolvedType, IIntentReceiver resultTo,
19755            int resultCode, String resultData, Bundle resultExtras,
19756            String[] requiredPermissions, int appOp, Bundle bOptions,
19757            boolean serialized, boolean sticky, int userId) {
19758        enforceNotIsolatedCaller("broadcastIntent");
19759        synchronized(this) {
19760            intent = verifyBroadcastLocked(intent);
19761
19762            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19763            final int callingPid = Binder.getCallingPid();
19764            final int callingUid = Binder.getCallingUid();
19765            final long origId = Binder.clearCallingIdentity();
19766            int res = broadcastIntentLocked(callerApp,
19767                    callerApp != null ? callerApp.info.packageName : null,
19768                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19769                    requiredPermissions, appOp, bOptions, serialized, sticky,
19770                    callingPid, callingUid, userId);
19771            Binder.restoreCallingIdentity(origId);
19772            return res;
19773        }
19774    }
19775
19776
19777    int broadcastIntentInPackage(String packageName, int uid,
19778            Intent intent, String resolvedType, IIntentReceiver resultTo,
19779            int resultCode, String resultData, Bundle resultExtras,
19780            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19781            int userId) {
19782        synchronized(this) {
19783            intent = verifyBroadcastLocked(intent);
19784
19785            final long origId = Binder.clearCallingIdentity();
19786            String[] requiredPermissions = requiredPermission == null ? null
19787                    : new String[] {requiredPermission};
19788            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19789                    resultTo, resultCode, resultData, resultExtras,
19790                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19791                    sticky, -1, uid, userId);
19792            Binder.restoreCallingIdentity(origId);
19793            return res;
19794        }
19795    }
19796
19797    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19798        // Refuse possible leaked file descriptors
19799        if (intent != null && intent.hasFileDescriptors() == true) {
19800            throw new IllegalArgumentException("File descriptors passed in Intent");
19801        }
19802
19803        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19804                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19805
19806        synchronized(this) {
19807            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19808                    != PackageManager.PERMISSION_GRANTED) {
19809                String msg = "Permission Denial: unbroadcastIntent() from pid="
19810                        + Binder.getCallingPid()
19811                        + ", uid=" + Binder.getCallingUid()
19812                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19813                Slog.w(TAG, msg);
19814                throw new SecurityException(msg);
19815            }
19816            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19817            if (stickies != null) {
19818                ArrayList<Intent> list = stickies.get(intent.getAction());
19819                if (list != null) {
19820                    int N = list.size();
19821                    int i;
19822                    for (i=0; i<N; i++) {
19823                        if (intent.filterEquals(list.get(i))) {
19824                            list.remove(i);
19825                            break;
19826                        }
19827                    }
19828                    if (list.size() <= 0) {
19829                        stickies.remove(intent.getAction());
19830                    }
19831                }
19832                if (stickies.size() <= 0) {
19833                    mStickyBroadcasts.remove(userId);
19834                }
19835            }
19836        }
19837    }
19838
19839    void backgroundServicesFinishedLocked(int userId) {
19840        for (BroadcastQueue queue : mBroadcastQueues) {
19841            queue.backgroundServicesFinishedLocked(userId);
19842        }
19843    }
19844
19845    public void finishReceiver(IBinder who, int resultCode, String resultData,
19846            Bundle resultExtras, boolean resultAbort, int flags) {
19847        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19848
19849        // Refuse possible leaked file descriptors
19850        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19851            throw new IllegalArgumentException("File descriptors passed in Bundle");
19852        }
19853
19854        final long origId = Binder.clearCallingIdentity();
19855        try {
19856            boolean doNext = false;
19857            BroadcastRecord r;
19858
19859            synchronized(this) {
19860                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19861                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19862                r = queue.getMatchingOrderedReceiver(who);
19863                if (r != null) {
19864                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19865                        resultData, resultExtras, resultAbort, true);
19866                }
19867            }
19868
19869            if (doNext) {
19870                r.queue.processNextBroadcast(false);
19871            }
19872            trimApplications();
19873        } finally {
19874            Binder.restoreCallingIdentity(origId);
19875        }
19876    }
19877
19878    // =========================================================
19879    // INSTRUMENTATION
19880    // =========================================================
19881
19882    public boolean startInstrumentation(ComponentName className,
19883            String profileFile, int flags, Bundle arguments,
19884            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19885            int userId, String abiOverride) {
19886        enforceNotIsolatedCaller("startInstrumentation");
19887        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19888                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19889        // Refuse possible leaked file descriptors
19890        if (arguments != null && arguments.hasFileDescriptors()) {
19891            throw new IllegalArgumentException("File descriptors passed in Bundle");
19892        }
19893
19894        synchronized(this) {
19895            InstrumentationInfo ii = null;
19896            ApplicationInfo ai = null;
19897            try {
19898                ii = mContext.getPackageManager().getInstrumentationInfo(
19899                    className, STOCK_PM_FLAGS);
19900                ai = AppGlobals.getPackageManager().getApplicationInfo(
19901                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19902            } catch (PackageManager.NameNotFoundException e) {
19903            } catch (RemoteException e) {
19904            }
19905            if (ii == null) {
19906                reportStartInstrumentationFailureLocked(watcher, className,
19907                        "Unable to find instrumentation info for: " + className);
19908                return false;
19909            }
19910            if (ai == null) {
19911                reportStartInstrumentationFailureLocked(watcher, className,
19912                        "Unable to find instrumentation target package: " + ii.targetPackage);
19913                return false;
19914            }
19915            if (!ai.hasCode()) {
19916                reportStartInstrumentationFailureLocked(watcher, className,
19917                        "Instrumentation target has no code: " + ii.targetPackage);
19918                return false;
19919            }
19920
19921            int match = mContext.getPackageManager().checkSignatures(
19922                    ii.targetPackage, ii.packageName);
19923            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19924                String msg = "Permission Denial: starting instrumentation "
19925                        + className + " from pid="
19926                        + Binder.getCallingPid()
19927                        + ", uid=" + Binder.getCallingPid()
19928                        + " not allowed because package " + ii.packageName
19929                        + " does not have a signature matching the target "
19930                        + ii.targetPackage;
19931                reportStartInstrumentationFailureLocked(watcher, className, msg);
19932                throw new SecurityException(msg);
19933            }
19934
19935            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19936            activeInstr.mClass = className;
19937            String defProcess = ai.processName;;
19938            if (ii.targetProcesses == null) {
19939                activeInstr.mTargetProcesses = new String[]{ai.processName};
19940            } else if (ii.targetProcesses.equals("*")) {
19941                activeInstr.mTargetProcesses = new String[0];
19942            } else {
19943                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19944                defProcess = activeInstr.mTargetProcesses[0];
19945            }
19946            activeInstr.mTargetInfo = ai;
19947            activeInstr.mProfileFile = profileFile;
19948            activeInstr.mArguments = arguments;
19949            activeInstr.mWatcher = watcher;
19950            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19951            activeInstr.mResultClass = className;
19952
19953            final long origId = Binder.clearCallingIdentity();
19954            // Instrumentation can kill and relaunch even persistent processes
19955            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19956                    "start instr");
19957            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19958            app.instr = activeInstr;
19959            activeInstr.mFinished = false;
19960            activeInstr.mRunningProcesses.add(app);
19961            if (!mActiveInstrumentation.contains(activeInstr)) {
19962                mActiveInstrumentation.add(activeInstr);
19963            }
19964            Binder.restoreCallingIdentity(origId);
19965        }
19966
19967        return true;
19968    }
19969
19970    /**
19971     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19972     * error to the logs, but if somebody is watching, send the report there too.  This enables
19973     * the "am" command to report errors with more information.
19974     *
19975     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19976     * @param cn The component name of the instrumentation.
19977     * @param report The error report.
19978     */
19979    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19980            ComponentName cn, String report) {
19981        Slog.w(TAG, report);
19982        if (watcher != null) {
19983            Bundle results = new Bundle();
19984            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19985            results.putString("Error", report);
19986            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19987        }
19988    }
19989
19990    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19991        if (app.instr == null) {
19992            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19993            return;
19994        }
19995
19996        if (!app.instr.mFinished && results != null) {
19997            if (app.instr.mCurResults == null) {
19998                app.instr.mCurResults = new Bundle(results);
19999            } else {
20000                app.instr.mCurResults.putAll(results);
20001            }
20002        }
20003    }
20004
20005    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20006        int userId = UserHandle.getCallingUserId();
20007        // Refuse possible leaked file descriptors
20008        if (results != null && results.hasFileDescriptors()) {
20009            throw new IllegalArgumentException("File descriptors passed in Intent");
20010        }
20011
20012        synchronized(this) {
20013            ProcessRecord app = getRecordForAppLocked(target);
20014            if (app == null) {
20015                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20016                return;
20017            }
20018            final long origId = Binder.clearCallingIdentity();
20019            addInstrumentationResultsLocked(app, results);
20020            Binder.restoreCallingIdentity(origId);
20021        }
20022    }
20023
20024    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20025        if (app.instr == null) {
20026            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20027            return;
20028        }
20029
20030        if (!app.instr.mFinished) {
20031            if (app.instr.mWatcher != null) {
20032                Bundle finalResults = app.instr.mCurResults;
20033                if (finalResults != null) {
20034                    if (app.instr.mCurResults != null && results != null) {
20035                        finalResults.putAll(results);
20036                    }
20037                } else {
20038                    finalResults = results;
20039                }
20040                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20041                        app.instr.mClass, resultCode, finalResults);
20042            }
20043
20044            // Can't call out of the system process with a lock held, so post a message.
20045            if (app.instr.mUiAutomationConnection != null) {
20046                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20047                        app.instr.mUiAutomationConnection).sendToTarget();
20048            }
20049            app.instr.mFinished = true;
20050        }
20051
20052        app.instr.removeProcess(app);
20053        app.instr = null;
20054
20055        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20056                "finished inst");
20057    }
20058
20059    public void finishInstrumentation(IApplicationThread target,
20060            int resultCode, Bundle results) {
20061        int userId = UserHandle.getCallingUserId();
20062        // Refuse possible leaked file descriptors
20063        if (results != null && results.hasFileDescriptors()) {
20064            throw new IllegalArgumentException("File descriptors passed in Intent");
20065        }
20066
20067        synchronized(this) {
20068            ProcessRecord app = getRecordForAppLocked(target);
20069            if (app == null) {
20070                Slog.w(TAG, "finishInstrumentation: no app for " + target);
20071                return;
20072            }
20073            final long origId = Binder.clearCallingIdentity();
20074            finishInstrumentationLocked(app, resultCode, results);
20075            Binder.restoreCallingIdentity(origId);
20076        }
20077    }
20078
20079    // =========================================================
20080    // CONFIGURATION
20081    // =========================================================
20082
20083    public ConfigurationInfo getDeviceConfigurationInfo() {
20084        ConfigurationInfo config = new ConfigurationInfo();
20085        synchronized (this) {
20086            final Configuration globalConfig = getGlobalConfiguration();
20087            config.reqTouchScreen = globalConfig.touchscreen;
20088            config.reqKeyboardType = globalConfig.keyboard;
20089            config.reqNavigation = globalConfig.navigation;
20090            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20091                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20092                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20093            }
20094            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20095                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20096                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20097            }
20098            config.reqGlEsVersion = GL_ES_VERSION;
20099        }
20100        return config;
20101    }
20102
20103    ActivityStack getFocusedStack() {
20104        return mStackSupervisor.getFocusedStack();
20105    }
20106
20107    @Override
20108    public int getFocusedStackId() throws RemoteException {
20109        ActivityStack focusedStack = getFocusedStack();
20110        if (focusedStack != null) {
20111            return focusedStack.getStackId();
20112        }
20113        return -1;
20114    }
20115
20116    public Configuration getConfiguration() {
20117        Configuration ci;
20118        synchronized(this) {
20119            ci = new Configuration(getGlobalConfiguration());
20120            ci.userSetLocale = false;
20121        }
20122        return ci;
20123    }
20124
20125    @Override
20126    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20127        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20128        synchronized (this) {
20129            mSuppressResizeConfigChanges = suppress;
20130        }
20131    }
20132
20133    /**
20134     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20135     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20136     *       activity and clearing the task at the same time.
20137     */
20138    @Override
20139    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20140        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20141        if (StackId.isHomeOrRecentsStack(fromStackId)) {
20142            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20143        }
20144        synchronized (this) {
20145            final long origId = Binder.clearCallingIdentity();
20146            try {
20147                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20148            } finally {
20149                Binder.restoreCallingIdentity(origId);
20150            }
20151        }
20152    }
20153
20154    @Override
20155    public void updatePersistentConfiguration(Configuration values) {
20156        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20157        enforceWriteSettingsPermission("updatePersistentConfiguration()");
20158        if (values == null) {
20159            throw new NullPointerException("Configuration must not be null");
20160        }
20161
20162        int userId = UserHandle.getCallingUserId();
20163
20164        synchronized(this) {
20165            updatePersistentConfigurationLocked(values, userId);
20166        }
20167    }
20168
20169    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20170        final long origId = Binder.clearCallingIdentity();
20171        try {
20172            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20173        } finally {
20174            Binder.restoreCallingIdentity(origId);
20175        }
20176    }
20177
20178    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20179        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20180                FONT_SCALE, 1.0f, userId);
20181
20182        synchronized (this) {
20183            if (getGlobalConfiguration().fontScale == scaleFactor) {
20184                return;
20185            }
20186
20187            final Configuration configuration
20188                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20189            configuration.fontScale = scaleFactor;
20190            updatePersistentConfigurationLocked(configuration, userId);
20191        }
20192    }
20193
20194    private void enforceWriteSettingsPermission(String func) {
20195        int uid = Binder.getCallingUid();
20196        if (uid == ROOT_UID) {
20197            return;
20198        }
20199
20200        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20201                Settings.getPackageNameForUid(mContext, uid), false)) {
20202            return;
20203        }
20204
20205        String msg = "Permission Denial: " + func + " from pid="
20206                + Binder.getCallingPid()
20207                + ", uid=" + uid
20208                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20209        Slog.w(TAG, msg);
20210        throw new SecurityException(msg);
20211    }
20212
20213    @Override
20214    public boolean updateConfiguration(Configuration values) {
20215        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20216
20217        synchronized(this) {
20218            if (values == null && mWindowManager != null) {
20219                // sentinel: fetch the current configuration from the window manager
20220                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20221            }
20222
20223            if (mWindowManager != null) {
20224                // Update OOM levels based on display size.
20225                mProcessList.applyDisplaySize(mWindowManager);
20226            }
20227
20228            final long origId = Binder.clearCallingIdentity();
20229            try {
20230                if (values != null) {
20231                    Settings.System.clearConfiguration(values);
20232                }
20233                updateConfigurationLocked(values, null, false, false /* persistent */,
20234                        UserHandle.USER_NULL, false /* deferResume */,
20235                        mTmpUpdateConfigurationResult);
20236                return mTmpUpdateConfigurationResult.changes != 0;
20237            } finally {
20238                Binder.restoreCallingIdentity(origId);
20239            }
20240        }
20241    }
20242
20243    void updateUserConfigurationLocked() {
20244        final Configuration configuration = new Configuration(getGlobalConfiguration());
20245        final int currentUserId = mUserController.getCurrentUserIdLocked();
20246        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20247                currentUserId, Settings.System.canWrite(mContext));
20248        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20249                false /* persistent */, currentUserId, false /* deferResume */);
20250    }
20251
20252    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20253            boolean initLocale) {
20254        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20255    }
20256
20257    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20258            boolean initLocale, boolean deferResume) {
20259        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20260        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20261                UserHandle.USER_NULL, deferResume);
20262    }
20263
20264    // To cache the list of supported system locales
20265    private String[] mSupportedSystemLocales = null;
20266
20267    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20268            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20269        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20270                deferResume, null /* result */);
20271    }
20272
20273    /**
20274     * Do either or both things: (1) change the current configuration, and (2)
20275     * make sure the given activity is running with the (now) current
20276     * configuration.  Returns true if the activity has been left running, or
20277     * false if <var>starting</var> is being destroyed to match the new
20278     * configuration.
20279     *
20280     * @param userId is only used when persistent parameter is set to true to persist configuration
20281     *               for that particular user
20282     */
20283    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20284            boolean initLocale, boolean persistent, int userId, boolean deferResume,
20285            UpdateConfigurationResult result) {
20286        int changes = 0;
20287        boolean kept = true;
20288
20289        if (mWindowManager != null) {
20290            mWindowManager.deferSurfaceLayout();
20291        }
20292        try {
20293            if (values != null) {
20294                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20295                        deferResume);
20296            }
20297
20298            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20299        } finally {
20300            if (mWindowManager != null) {
20301                mWindowManager.continueSurfaceLayout();
20302            }
20303        }
20304
20305        if (result != null) {
20306            result.changes = changes;
20307            result.activityRelaunched = !kept;
20308        }
20309        return kept;
20310    }
20311
20312    /** Update default (global) configuration and notify listeners about changes. */
20313    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20314            boolean persistent, int userId, boolean deferResume) {
20315        mTempConfig.setTo(getGlobalConfiguration());
20316        final int changes = mTempConfig.updateFrom(values);
20317        if (changes == 0) {
20318            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20319            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20320            // performDisplayOverrideConfigUpdate in order to send the new display configuration
20321            // (even if there are no actual changes) to unfreeze the window.
20322            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20323            return 0;
20324        }
20325
20326        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20327                "Updating global configuration to: " + values);
20328
20329        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20330
20331        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20332            final LocaleList locales = values.getLocales();
20333            int bestLocaleIndex = 0;
20334            if (locales.size() > 1) {
20335                if (mSupportedSystemLocales == null) {
20336                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20337                }
20338                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20339            }
20340            SystemProperties.set("persist.sys.locale",
20341                    locales.get(bestLocaleIndex).toLanguageTag());
20342            LocaleList.setDefault(locales, bestLocaleIndex);
20343            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20344                    locales.get(bestLocaleIndex)));
20345        }
20346
20347        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20348        mTempConfig.seq = mConfigurationSeq;
20349
20350        // Update stored global config and notify everyone about the change.
20351        mStackSupervisor.onConfigurationChanged(mTempConfig);
20352
20353        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20354        // TODO(multi-display): Update UsageEvents#Event to include displayId.
20355        mUsageStatsService.reportConfigurationChange(mTempConfig,
20356                mUserController.getCurrentUserIdLocked());
20357
20358        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20359        mShowDialogs = shouldShowDialogs(mTempConfig);
20360
20361        AttributeCache ac = AttributeCache.instance();
20362        if (ac != null) {
20363            ac.updateConfiguration(mTempConfig);
20364        }
20365
20366        // Make sure all resources in our process are updated right now, so that anyone who is going
20367        // to retrieve resource values after we return will be sure to get the new ones. This is
20368        // especially important during boot, where the first config change needs to guarantee all
20369        // resources have that config before following boot code is executed.
20370        mSystemThread.applyConfigurationToResources(mTempConfig);
20371
20372        // We need another copy of global config because we're scheduling some calls instead of
20373        // running them in place. We need to be sure that object we send will be handled unchanged.
20374        final Configuration configCopy = new Configuration(mTempConfig);
20375        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20376            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20377            msg.obj = configCopy;
20378            msg.arg1 = userId;
20379            mHandler.sendMessage(msg);
20380        }
20381
20382        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20383            ProcessRecord app = mLruProcesses.get(i);
20384            try {
20385                if (app.thread != null) {
20386                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20387                            + app.processName + " new config " + configCopy);
20388                    app.thread.scheduleConfigurationChanged(configCopy);
20389                }
20390            } catch (Exception e) {
20391            }
20392        }
20393
20394        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20395        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20396                | Intent.FLAG_RECEIVER_FOREGROUND
20397                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20398        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20399                AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20400                UserHandle.USER_ALL);
20401        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20402            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20403            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20404                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20405                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20406            if (initLocale || !mProcessesReady) {
20407                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20408            }
20409            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20410                    AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20411                    UserHandle.USER_ALL);
20412        }
20413
20414        // Override configuration of the default display duplicates global config, so we need to
20415        // update it also. This will also notify WindowManager about changes.
20416        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20417                DEFAULT_DISPLAY);
20418
20419        return changes;
20420    }
20421
20422    @Override
20423    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20424        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20425
20426        synchronized (this) {
20427            // Check if display is initialized in AM.
20428            if (!mStackSupervisor.isDisplayAdded(displayId)) {
20429                // Call might come when display is not yet added or has already been removed.
20430                if (DEBUG_CONFIGURATION) {
20431                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20432                            + displayId);
20433                }
20434                return false;
20435            }
20436
20437            if (values == null && mWindowManager != null) {
20438                // sentinel: fetch the current configuration from the window manager
20439                values = mWindowManager.computeNewConfiguration(displayId);
20440            }
20441
20442            if (mWindowManager != null) {
20443                // Update OOM levels based on display size.
20444                mProcessList.applyDisplaySize(mWindowManager);
20445            }
20446
20447            final long origId = Binder.clearCallingIdentity();
20448            try {
20449                if (values != null) {
20450                    Settings.System.clearConfiguration(values);
20451                }
20452                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20453                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20454                return mTmpUpdateConfigurationResult.changes != 0;
20455            } finally {
20456                Binder.restoreCallingIdentity(origId);
20457            }
20458        }
20459    }
20460
20461    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20462            boolean deferResume, int displayId) {
20463        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20464                displayId, null /* result */);
20465    }
20466
20467    /**
20468     * Updates override configuration specific for the selected display. If no config is provided,
20469     * new one will be computed in WM based on current display info.
20470     */
20471    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20472            ActivityRecord starting, boolean deferResume, int displayId,
20473            UpdateConfigurationResult result) {
20474        int changes = 0;
20475        boolean kept = true;
20476
20477        if (mWindowManager != null) {
20478            mWindowManager.deferSurfaceLayout();
20479        }
20480        try {
20481            if (values != null) {
20482                if (displayId == DEFAULT_DISPLAY) {
20483                    // Override configuration of the default display duplicates global config, so
20484                    // we're calling global config update instead for default display. It will also
20485                    // apply the correct override config.
20486                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20487                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20488                } else {
20489                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20490                }
20491            }
20492
20493            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20494        } finally {
20495            if (mWindowManager != null) {
20496                mWindowManager.continueSurfaceLayout();
20497            }
20498        }
20499
20500        if (result != null) {
20501            result.changes = changes;
20502            result.activityRelaunched = !kept;
20503        }
20504        return kept;
20505    }
20506
20507    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20508            int displayId) {
20509        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20510        final int changes = mTempConfig.updateFrom(values);
20511        if (changes != 0) {
20512            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20513                    + mTempConfig + " for displayId=" + displayId);
20514            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20515
20516            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20517            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20518                // Reset the unsupported display size dialog.
20519                mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20520
20521                killAllBackgroundProcessesExcept(N,
20522                        ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20523            }
20524        }
20525
20526        // Update the configuration with WM first and check if any of the stacks need to be resized
20527        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20528        // necessary. This way we don't need to relaunch again afterwards in
20529        // ensureActivityConfigurationLocked().
20530        if (mWindowManager != null) {
20531            final int[] resizedStacks =
20532                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20533            if (resizedStacks != null) {
20534                for (int stackId : resizedStacks) {
20535                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20536                }
20537            }
20538        }
20539
20540        return changes;
20541    }
20542
20543    /** Applies latest configuration and/or visibility updates if needed. */
20544    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20545        boolean kept = true;
20546        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20547        // mainStack is null during startup.
20548        if (mainStack != null) {
20549            if (changes != 0 && starting == null) {
20550                // If the configuration changed, and the caller is not already
20551                // in the process of starting an activity, then find the top
20552                // activity to check if its configuration needs to change.
20553                starting = mainStack.topRunningActivityLocked();
20554            }
20555
20556            if (starting != null) {
20557                kept = starting.ensureActivityConfigurationLocked(changes,
20558                        false /* preserveWindow */);
20559                // And we need to make sure at this point that all other activities
20560                // are made visible with the correct configuration.
20561                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20562                        !PRESERVE_WINDOWS);
20563            }
20564        }
20565
20566        return kept;
20567    }
20568
20569    /** Helper method that requests bounds from WM and applies them to stack. */
20570    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20571        final Rect newStackBounds = new Rect();
20572        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20573        mStackSupervisor.resizeStackLocked(
20574                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20575                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20576                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20577    }
20578
20579    /**
20580     * Decide based on the configuration whether we should show the ANR,
20581     * crash, etc dialogs.  The idea is that if there is no affordance to
20582     * press the on-screen buttons, or the user experience would be more
20583     * greatly impacted than the crash itself, we shouldn't show the dialog.
20584     *
20585     * A thought: SystemUI might also want to get told about this, the Power
20586     * dialog / global actions also might want different behaviors.
20587     */
20588    private static boolean shouldShowDialogs(Configuration config) {
20589        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20590                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20591                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20592        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20593        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20594                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20595                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20596                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20597        return inputMethodExists && uiModeSupportsDialogs;
20598    }
20599
20600    @Override
20601    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20602        synchronized (this) {
20603            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20604            if (srec != null) {
20605                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20606            }
20607        }
20608        return false;
20609    }
20610
20611    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20612            Intent resultData) {
20613
20614        synchronized (this) {
20615            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20616            if (r != null) {
20617                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20618            }
20619            return false;
20620        }
20621    }
20622
20623    public int getLaunchedFromUid(IBinder activityToken) {
20624        ActivityRecord srec;
20625        synchronized (this) {
20626            srec = ActivityRecord.forTokenLocked(activityToken);
20627        }
20628        if (srec == null) {
20629            return -1;
20630        }
20631        return srec.launchedFromUid;
20632    }
20633
20634    public String getLaunchedFromPackage(IBinder activityToken) {
20635        ActivityRecord srec;
20636        synchronized (this) {
20637            srec = ActivityRecord.forTokenLocked(activityToken);
20638        }
20639        if (srec == null) {
20640            return null;
20641        }
20642        return srec.launchedFromPackage;
20643    }
20644
20645    // =========================================================
20646    // LIFETIME MANAGEMENT
20647    // =========================================================
20648
20649    // Returns whether the app is receiving broadcast.
20650    // If receiving, fetch all broadcast queues which the app is
20651    // the current [or imminent] receiver on.
20652    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20653            ArraySet<BroadcastQueue> receivingQueues) {
20654        if (!app.curReceivers.isEmpty()) {
20655            for (BroadcastRecord r : app.curReceivers) {
20656                receivingQueues.add(r.queue);
20657            }
20658            return true;
20659        }
20660
20661        // It's not the current receiver, but it might be starting up to become one
20662        for (BroadcastQueue queue : mBroadcastQueues) {
20663            final BroadcastRecord r = queue.mPendingBroadcast;
20664            if (r != null && r.curApp == app) {
20665                // found it; report which queue it's in
20666                receivingQueues.add(queue);
20667            }
20668        }
20669
20670        return !receivingQueues.isEmpty();
20671    }
20672
20673    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20674            int targetUid, ComponentName targetComponent, String targetProcess) {
20675        if (!mTrackingAssociations) {
20676            return null;
20677        }
20678        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20679                = mAssociations.get(targetUid);
20680        if (components == null) {
20681            components = new ArrayMap<>();
20682            mAssociations.put(targetUid, components);
20683        }
20684        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20685        if (sourceUids == null) {
20686            sourceUids = new SparseArray<>();
20687            components.put(targetComponent, sourceUids);
20688        }
20689        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20690        if (sourceProcesses == null) {
20691            sourceProcesses = new ArrayMap<>();
20692            sourceUids.put(sourceUid, sourceProcesses);
20693        }
20694        Association ass = sourceProcesses.get(sourceProcess);
20695        if (ass == null) {
20696            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20697                    targetProcess);
20698            sourceProcesses.put(sourceProcess, ass);
20699        }
20700        ass.mCount++;
20701        ass.mNesting++;
20702        if (ass.mNesting == 1) {
20703            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20704            ass.mLastState = sourceState;
20705        }
20706        return ass;
20707    }
20708
20709    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20710            ComponentName targetComponent) {
20711        if (!mTrackingAssociations) {
20712            return;
20713        }
20714        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20715                = mAssociations.get(targetUid);
20716        if (components == null) {
20717            return;
20718        }
20719        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20720        if (sourceUids == null) {
20721            return;
20722        }
20723        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20724        if (sourceProcesses == null) {
20725            return;
20726        }
20727        Association ass = sourceProcesses.get(sourceProcess);
20728        if (ass == null || ass.mNesting <= 0) {
20729            return;
20730        }
20731        ass.mNesting--;
20732        if (ass.mNesting == 0) {
20733            long uptime = SystemClock.uptimeMillis();
20734            ass.mTime += uptime - ass.mStartTime;
20735            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20736                    += uptime - ass.mLastStateUptime;
20737            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20738        }
20739    }
20740
20741    private void noteUidProcessState(final int uid, final int state) {
20742        mBatteryStatsService.noteUidProcessState(uid, state);
20743        if (mTrackingAssociations) {
20744            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20745                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20746                        = mAssociations.valueAt(i1);
20747                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20748                    SparseArray<ArrayMap<String, Association>> sourceUids
20749                            = targetComponents.valueAt(i2);
20750                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20751                    if (sourceProcesses != null) {
20752                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20753                            Association ass = sourceProcesses.valueAt(i4);
20754                            if (ass.mNesting >= 1) {
20755                                // currently associated
20756                                long uptime = SystemClock.uptimeMillis();
20757                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20758                                        += uptime - ass.mLastStateUptime;
20759                                ass.mLastState = state;
20760                                ass.mLastStateUptime = uptime;
20761                            }
20762                        }
20763                    }
20764                }
20765            }
20766        }
20767    }
20768
20769    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20770            boolean doingAll, long now) {
20771        if (mAdjSeq == app.adjSeq) {
20772            // This adjustment has already been computed.
20773            return app.curRawAdj;
20774        }
20775
20776        if (app.thread == null) {
20777            app.adjSeq = mAdjSeq;
20778            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20779            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20780            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20781        }
20782
20783        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20784        app.adjSource = null;
20785        app.adjTarget = null;
20786        app.empty = false;
20787        app.cached = false;
20788
20789        final int activitiesSize = app.activities.size();
20790
20791        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20792            // The max adjustment doesn't allow this app to be anything
20793            // below foreground, so it is not worth doing work for it.
20794            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20795            app.adjType = "fixed";
20796            app.adjSeq = mAdjSeq;
20797            app.curRawAdj = app.maxAdj;
20798            app.foregroundActivities = false;
20799            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20800            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20801            // System processes can do UI, and when they do we want to have
20802            // them trim their memory after the user leaves the UI.  To
20803            // facilitate this, here we need to determine whether or not it
20804            // is currently showing UI.
20805            app.systemNoUi = true;
20806            if (app == TOP_APP) {
20807                app.systemNoUi = false;
20808                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20809                app.adjType = "pers-top-activity";
20810            } else if (app.hasTopUi) {
20811                app.systemNoUi = false;
20812                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20813                app.adjType = "pers-top-ui";
20814            } else if (activitiesSize > 0) {
20815                for (int j = 0; j < activitiesSize; j++) {
20816                    final ActivityRecord r = app.activities.get(j);
20817                    if (r.visible) {
20818                        app.systemNoUi = false;
20819                    }
20820                }
20821            }
20822            if (!app.systemNoUi) {
20823                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20824            }
20825            return (app.curAdj=app.maxAdj);
20826        }
20827
20828        app.systemNoUi = false;
20829
20830        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20831
20832        // Determine the importance of the process, starting with most
20833        // important to least, and assign an appropriate OOM adjustment.
20834        int adj;
20835        int schedGroup;
20836        int procState;
20837        boolean foregroundActivities = false;
20838        mTmpBroadcastQueue.clear();
20839        if (app == TOP_APP) {
20840            // The last app on the list is the foreground app.
20841            adj = ProcessList.FOREGROUND_APP_ADJ;
20842            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20843            app.adjType = "top-activity";
20844            foregroundActivities = true;
20845            procState = PROCESS_STATE_CUR_TOP;
20846            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20847        } else if (app.instr != null) {
20848            // Don't want to kill running instrumentation.
20849            adj = ProcessList.FOREGROUND_APP_ADJ;
20850            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20851            app.adjType = "instrumentation";
20852            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20853            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20854        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20855            // An app that is currently receiving a broadcast also
20856            // counts as being in the foreground for OOM killer purposes.
20857            // It's placed in a sched group based on the nature of the
20858            // broadcast as reflected by which queue it's active in.
20859            adj = ProcessList.FOREGROUND_APP_ADJ;
20860            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20861                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20862            app.adjType = "broadcast";
20863            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20864            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20865        } else if (app.executingServices.size() > 0) {
20866            // An app that is currently executing a service callback also
20867            // counts as being in the foreground.
20868            adj = ProcessList.FOREGROUND_APP_ADJ;
20869            schedGroup = app.execServicesFg ?
20870                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20871            app.adjType = "exec-service";
20872            procState = ActivityManager.PROCESS_STATE_SERVICE;
20873            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20874            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20875        } else {
20876            // As far as we know the process is empty.  We may change our mind later.
20877            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20878            // At this point we don't actually know the adjustment.  Use the cached adj
20879            // value that the caller wants us to.
20880            adj = cachedAdj;
20881            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20882            app.cached = true;
20883            app.empty = true;
20884            app.adjType = "cch-empty";
20885            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20886        }
20887
20888        // Examine all activities if not already foreground.
20889        if (!foregroundActivities && activitiesSize > 0) {
20890            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20891            for (int j = 0; j < activitiesSize; j++) {
20892                final ActivityRecord r = app.activities.get(j);
20893                if (r.app != app) {
20894                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20895                            + " instead of expected " + app);
20896                    if (r.app == null || (r.app.uid == app.uid)) {
20897                        // Only fix things up when they look sane
20898                        r.app = app;
20899                    } else {
20900                        continue;
20901                    }
20902                }
20903                if (r.visible) {
20904                    // App has a visible activity; only upgrade adjustment.
20905                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20906                        adj = ProcessList.VISIBLE_APP_ADJ;
20907                        app.adjType = "vis-activity";
20908                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20909                    }
20910                    if (procState > PROCESS_STATE_CUR_TOP) {
20911                        procState = PROCESS_STATE_CUR_TOP;
20912                        app.adjType = "vis-activity";
20913                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20914                    }
20915                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20916                    app.cached = false;
20917                    app.empty = false;
20918                    foregroundActivities = true;
20919                    final TaskRecord task = r.getTask();
20920                    if (task != null && minLayer > 0) {
20921                        final int layer = task.mLayerRank;
20922                        if (layer >= 0 && minLayer > layer) {
20923                            minLayer = layer;
20924                        }
20925                    }
20926                    break;
20927                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20928                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20929                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20930                        app.adjType = "pause-activity";
20931                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20932                    }
20933                    if (procState > PROCESS_STATE_CUR_TOP) {
20934                        procState = PROCESS_STATE_CUR_TOP;
20935                        app.adjType = "pause-activity";
20936                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20937                    }
20938                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20939                    app.cached = false;
20940                    app.empty = false;
20941                    foregroundActivities = true;
20942                } else if (r.state == ActivityState.STOPPING) {
20943                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20944                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20945                        app.adjType = "stop-activity";
20946                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20947                    }
20948                    // For the process state, we will at this point consider the
20949                    // process to be cached.  It will be cached either as an activity
20950                    // or empty depending on whether the activity is finishing.  We do
20951                    // this so that we can treat the process as cached for purposes of
20952                    // memory trimming (determing current memory level, trim command to
20953                    // send to process) since there can be an arbitrary number of stopping
20954                    // processes and they should soon all go into the cached state.
20955                    if (!r.finishing) {
20956                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20957                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20958                            app.adjType = "stop-activity";
20959                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20960                        }
20961                    }
20962                    app.cached = false;
20963                    app.empty = false;
20964                    foregroundActivities = true;
20965                } else {
20966                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20967                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20968                        app.adjType = "cch-act";
20969                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
20970                    }
20971                }
20972            }
20973            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20974                adj += minLayer;
20975            }
20976        }
20977
20978        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20979                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20980            if (app.foregroundServices) {
20981                // The user is aware of this app, so make it visible.
20982                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20983                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20984                app.cached = false;
20985                app.adjType = "fg-service";
20986                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20987                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
20988            } else if (app.hasOverlayUi) {
20989                // The process is display an overlay UI.
20990                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20991                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20992                app.cached = false;
20993                app.adjType = "has-overlay-ui";
20994                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20995                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
20996            }
20997        }
20998
20999        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21000                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21001            if (app.forcingToImportant != null) {
21002                // This is currently used for toasts...  they are not interactive, and
21003                // we don't want them to cause the app to become fully foreground (and
21004                // thus out of background check), so we yes the best background level we can.
21005                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21006                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21007                app.cached = false;
21008                app.adjType = "force-imp";
21009                app.adjSource = app.forcingToImportant;
21010                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21011                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21012            }
21013        }
21014
21015        if (app == mHeavyWeightProcess) {
21016            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21017                // We don't want to kill the current heavy-weight process.
21018                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21019                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21020                app.cached = false;
21021                app.adjType = "heavy";
21022                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21023            }
21024            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21025                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21026                app.adjType = "heavy";
21027                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21028            }
21029        }
21030
21031        if (app == mHomeProcess) {
21032            if (adj > ProcessList.HOME_APP_ADJ) {
21033                // This process is hosting what we currently consider to be the
21034                // home app, so we don't want to let it go into the background.
21035                adj = ProcessList.HOME_APP_ADJ;
21036                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21037                app.cached = false;
21038                app.adjType = "home";
21039                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21040            }
21041            if (procState > ActivityManager.PROCESS_STATE_HOME) {
21042                procState = ActivityManager.PROCESS_STATE_HOME;
21043                app.adjType = "home";
21044                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21045            }
21046        }
21047
21048        if (app == mPreviousProcess && app.activities.size() > 0) {
21049            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21050                // This was the previous process that showed UI to the user.
21051                // We want to try to keep it around more aggressively, to give
21052                // a good experience around switching between two apps.
21053                adj = ProcessList.PREVIOUS_APP_ADJ;
21054                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21055                app.cached = false;
21056                app.adjType = "previous";
21057                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21058            }
21059            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21060                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21061                app.adjType = "previous";
21062                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21063            }
21064        }
21065
21066        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21067                + " reason=" + app.adjType);
21068
21069        // By default, we use the computed adjustment.  It may be changed if
21070        // there are applications dependent on our services or providers, but
21071        // this gives us a baseline and makes sure we don't get into an
21072        // infinite recursion.
21073        app.adjSeq = mAdjSeq;
21074        app.curRawAdj = adj;
21075        app.hasStartedServices = false;
21076
21077        if (mBackupTarget != null && app == mBackupTarget.app) {
21078            // If possible we want to avoid killing apps while they're being backed up
21079            if (adj > ProcessList.BACKUP_APP_ADJ) {
21080                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21081                adj = ProcessList.BACKUP_APP_ADJ;
21082                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21083                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21084                }
21085                app.adjType = "backup";
21086                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21087                app.cached = false;
21088            }
21089            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21090                procState = ActivityManager.PROCESS_STATE_BACKUP;
21091                app.adjType = "backup";
21092                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21093            }
21094        }
21095
21096        boolean mayBeTop = false;
21097        String mayBeTopType = null;
21098        Object mayBeTopSource = null;
21099        Object mayBeTopTarget = null;
21100
21101        for (int is = app.services.size()-1;
21102                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21103                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21104                        || procState > ActivityManager.PROCESS_STATE_TOP);
21105                is--) {
21106            ServiceRecord s = app.services.valueAt(is);
21107            if (s.startRequested) {
21108                app.hasStartedServices = true;
21109                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21110                    procState = ActivityManager.PROCESS_STATE_SERVICE;
21111                    app.adjType = "started-services";
21112                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21113                }
21114                if (app.hasShownUi && app != mHomeProcess) {
21115                    // If this process has shown some UI, let it immediately
21116                    // go to the LRU list because it may be pretty heavy with
21117                    // UI stuff.  We'll tag it with a label just to help
21118                    // debug and understand what is going on.
21119                    if (adj > ProcessList.SERVICE_ADJ) {
21120                        app.adjType = "cch-started-ui-services";
21121                    }
21122                } else {
21123                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21124                        // This service has seen some activity within
21125                        // recent memory, so we will keep its process ahead
21126                        // of the background processes.
21127                        if (adj > ProcessList.SERVICE_ADJ) {
21128                            adj = ProcessList.SERVICE_ADJ;
21129                            app.adjType = "started-services";
21130                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21131                            app.cached = false;
21132                        }
21133                    }
21134                    // If we have let the service slide into the background
21135                    // state, still have some text describing what it is doing
21136                    // even though the service no longer has an impact.
21137                    if (adj > ProcessList.SERVICE_ADJ) {
21138                        app.adjType = "cch-started-services";
21139                    }
21140                }
21141            }
21142
21143            for (int conni = s.connections.size()-1;
21144                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21145                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21146                            || procState > ActivityManager.PROCESS_STATE_TOP);
21147                    conni--) {
21148                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21149                for (int i = 0;
21150                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21151                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21152                                || procState > ActivityManager.PROCESS_STATE_TOP);
21153                        i++) {
21154                    // XXX should compute this based on the max of
21155                    // all connected clients.
21156                    ConnectionRecord cr = clist.get(i);
21157                    if (cr.binding.client == app) {
21158                        // Binding to ourself is not interesting.
21159                        continue;
21160                    }
21161
21162                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21163                        ProcessRecord client = cr.binding.client;
21164                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
21165                                TOP_APP, doingAll, now);
21166                        int clientProcState = client.curProcState;
21167                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21168                            // If the other app is cached for any reason, for purposes here
21169                            // we are going to consider it empty.  The specific cached state
21170                            // doesn't propagate except under certain conditions.
21171                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21172                        }
21173                        String adjType = null;
21174                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21175                            // Not doing bind OOM management, so treat
21176                            // this guy more like a started service.
21177                            if (app.hasShownUi && app != mHomeProcess) {
21178                                // If this process has shown some UI, let it immediately
21179                                // go to the LRU list because it may be pretty heavy with
21180                                // UI stuff.  We'll tag it with a label just to help
21181                                // debug and understand what is going on.
21182                                if (adj > clientAdj) {
21183                                    adjType = "cch-bound-ui-services";
21184                                }
21185                                app.cached = false;
21186                                clientAdj = adj;
21187                                clientProcState = procState;
21188                            } else {
21189                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21190                                    // This service has not seen activity within
21191                                    // recent memory, so allow it to drop to the
21192                                    // LRU list if there is no other reason to keep
21193                                    // it around.  We'll also tag it with a label just
21194                                    // to help debug and undertand what is going on.
21195                                    if (adj > clientAdj) {
21196                                        adjType = "cch-bound-services";
21197                                    }
21198                                    clientAdj = adj;
21199                                }
21200                            }
21201                        }
21202                        if (adj > clientAdj) {
21203                            // If this process has recently shown UI, and
21204                            // the process that is binding to it is less
21205                            // important than being visible, then we don't
21206                            // care about the binding as much as we care
21207                            // about letting this process get into the LRU
21208                            // list to be killed and restarted if needed for
21209                            // memory.
21210                            if (app.hasShownUi && app != mHomeProcess
21211                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21212                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21213                                    adjType = "cch-bound-ui-services";
21214                                }
21215                            } else {
21216                                int newAdj;
21217                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21218                                        |Context.BIND_IMPORTANT)) != 0) {
21219                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21220                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21221                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21222                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21223                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21224                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21225                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21226                                    newAdj = clientAdj;
21227                                } else {
21228                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
21229                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21230                                    } else {
21231                                        newAdj = adj;
21232                                    }
21233                                }
21234                                if (!client.cached) {
21235                                    app.cached = false;
21236                                }
21237                                if (adj >  newAdj) {
21238                                    adj = newAdj;
21239                                    adjType = "service";
21240                                }
21241                            }
21242                        }
21243                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21244                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21245                            // This will treat important bound services identically to
21246                            // the top app, which may behave differently than generic
21247                            // foreground work.
21248                            if (client.curSchedGroup > schedGroup) {
21249                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21250                                    schedGroup = client.curSchedGroup;
21251                                } else {
21252                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21253                                }
21254                            }
21255                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21256                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21257                                    // Special handling of clients who are in the top state.
21258                                    // We *may* want to consider this process to be in the
21259                                    // top state as well, but only if there is not another
21260                                    // reason for it to be running.  Being on the top is a
21261                                    // special state, meaning you are specifically running
21262                                    // for the current top app.  If the process is already
21263                                    // running in the background for some other reason, it
21264                                    // is more important to continue considering it to be
21265                                    // in the background state.
21266                                    mayBeTop = true;
21267                                    mayBeTopType = "service";
21268                                    mayBeTopSource = cr.binding.client;
21269                                    mayBeTopTarget = s.name;
21270                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21271                                } else {
21272                                    // Special handling for above-top states (persistent
21273                                    // processes).  These should not bring the current process
21274                                    // into the top state, since they are not on top.  Instead
21275                                    // give them the best state after that.
21276                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21277                                        clientProcState =
21278                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21279                                    } else if (mWakefulness
21280                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21281                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21282                                                    != 0) {
21283                                        clientProcState =
21284                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21285                                    } else {
21286                                        clientProcState =
21287                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21288                                    }
21289                                }
21290                            }
21291                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21292                            if (clientProcState <
21293                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21294                                clientProcState =
21295                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21296                            }
21297                        } else {
21298                            if (clientProcState <
21299                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21300                                clientProcState =
21301                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21302                            }
21303                        }
21304                        if (procState > clientProcState) {
21305                            procState = clientProcState;
21306                            if (adjType == null) {
21307                                adjType = "service";
21308                            }
21309                        }
21310                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21311                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21312                            app.pendingUiClean = true;
21313                        }
21314                        if (adjType != null) {
21315                            app.adjType = adjType;
21316                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21317                                    .REASON_SERVICE_IN_USE;
21318                            app.adjSource = cr.binding.client;
21319                            app.adjSourceProcState = clientProcState;
21320                            app.adjTarget = s.name;
21321                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21322                                    + ": " + app + ", due to " + cr.binding.client
21323                                    + " adj=" + adj + " procState=" + procState);
21324                        }
21325                    }
21326                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21327                        app.treatLikeActivity = true;
21328                    }
21329                    final ActivityRecord a = cr.activity;
21330                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21331                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21332                            (a.visible || a.state == ActivityState.RESUMED ||
21333                             a.state == ActivityState.PAUSING)) {
21334                            adj = ProcessList.FOREGROUND_APP_ADJ;
21335                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21336                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21337                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21338                                } else {
21339                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21340                                }
21341                            }
21342                            app.cached = false;
21343                            app.adjType = "service";
21344                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21345                                    .REASON_SERVICE_IN_USE;
21346                            app.adjSource = a;
21347                            app.adjSourceProcState = procState;
21348                            app.adjTarget = s.name;
21349                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21350                                    + app);
21351                        }
21352                    }
21353                }
21354            }
21355        }
21356
21357        for (int provi = app.pubProviders.size()-1;
21358                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21359                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21360                        || procState > ActivityManager.PROCESS_STATE_TOP);
21361                provi--) {
21362            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21363            for (int i = cpr.connections.size()-1;
21364                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21365                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21366                            || procState > ActivityManager.PROCESS_STATE_TOP);
21367                    i--) {
21368                ContentProviderConnection conn = cpr.connections.get(i);
21369                ProcessRecord client = conn.client;
21370                if (client == app) {
21371                    // Being our own client is not interesting.
21372                    continue;
21373                }
21374                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21375                int clientProcState = client.curProcState;
21376                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21377                    // If the other app is cached for any reason, for purposes here
21378                    // we are going to consider it empty.
21379                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21380                }
21381                String adjType = null;
21382                if (adj > clientAdj) {
21383                    if (app.hasShownUi && app != mHomeProcess
21384                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21385                        adjType = "cch-ui-provider";
21386                    } else {
21387                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21388                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21389                        adjType = "provider";
21390                    }
21391                    app.cached &= client.cached;
21392                }
21393                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21394                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21395                        // Special handling of clients who are in the top state.
21396                        // We *may* want to consider this process to be in the
21397                        // top state as well, but only if there is not another
21398                        // reason for it to be running.  Being on the top is a
21399                        // special state, meaning you are specifically running
21400                        // for the current top app.  If the process is already
21401                        // running in the background for some other reason, it
21402                        // is more important to continue considering it to be
21403                        // in the background state.
21404                        mayBeTop = true;
21405                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21406                        mayBeTopType = adjType = "provider-top";
21407                        mayBeTopSource = client;
21408                        mayBeTopTarget = cpr.name;
21409                    } else {
21410                        // Special handling for above-top states (persistent
21411                        // processes).  These should not bring the current process
21412                        // into the top state, since they are not on top.  Instead
21413                        // give them the best state after that.
21414                        clientProcState =
21415                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21416                        if (adjType == null) {
21417                            adjType = "provider";
21418                        }
21419                    }
21420                }
21421                if (procState > clientProcState) {
21422                    procState = clientProcState;
21423                }
21424                if (client.curSchedGroup > schedGroup) {
21425                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21426                }
21427                if (adjType != null) {
21428                    app.adjType = adjType;
21429                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21430                            .REASON_PROVIDER_IN_USE;
21431                    app.adjSource = client;
21432                    app.adjSourceProcState = clientProcState;
21433                    app.adjTarget = cpr.name;
21434                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21435                            + ": " + app + ", due to " + client
21436                            + " adj=" + adj + " procState=" + procState);
21437                }
21438            }
21439            // If the provider has external (non-framework) process
21440            // dependencies, ensure that its adjustment is at least
21441            // FOREGROUND_APP_ADJ.
21442            if (cpr.hasExternalProcessHandles()) {
21443                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21444                    adj = ProcessList.FOREGROUND_APP_ADJ;
21445                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21446                    app.cached = false;
21447                    app.adjType = "ext-provider";
21448                    app.adjTarget = cpr.name;
21449                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21450                }
21451                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21452                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21453                }
21454            }
21455        }
21456
21457        if (app.lastProviderTime > 0 &&
21458                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21459            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21460                adj = ProcessList.PREVIOUS_APP_ADJ;
21461                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21462                app.cached = false;
21463                app.adjType = "recent-provider";
21464                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21465            }
21466            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21467                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21468                app.adjType = "recent-provider";
21469                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21470            }
21471        }
21472
21473        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21474            // A client of one of our services or providers is in the top state.  We
21475            // *may* want to be in the top state, but not if we are already running in
21476            // the background for some other reason.  For the decision here, we are going
21477            // to pick out a few specific states that we want to remain in when a client
21478            // is top (states that tend to be longer-term) and otherwise allow it to go
21479            // to the top state.
21480            switch (procState) {
21481                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21482                    // Something else is keeping it at this level, just leave it.
21483                    break;
21484                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21485                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21486                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21487                case ActivityManager.PROCESS_STATE_SERVICE:
21488                    // These all are longer-term states, so pull them up to the top
21489                    // of the background states, but not all the way to the top state.
21490                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21491                    app.adjType = mayBeTopType;
21492                    app.adjSource = mayBeTopSource;
21493                    app.adjTarget = mayBeTopTarget;
21494                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21495                            + ": " + app + ", due to " + mayBeTopSource
21496                            + " adj=" + adj + " procState=" + procState);
21497                    break;
21498                default:
21499                    // Otherwise, top is a better choice, so take it.
21500                    procState = ActivityManager.PROCESS_STATE_TOP;
21501                    app.adjType = mayBeTopType;
21502                    app.adjSource = mayBeTopSource;
21503                    app.adjTarget = mayBeTopTarget;
21504                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21505                            + ": " + app + ", due to " + mayBeTopSource
21506                            + " adj=" + adj + " procState=" + procState);
21507                    break;
21508            }
21509        }
21510
21511        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21512            if (app.hasClientActivities) {
21513                // This is a cached process, but with client activities.  Mark it so.
21514                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21515                app.adjType = "cch-client-act";
21516            } else if (app.treatLikeActivity) {
21517                // This is a cached process, but somebody wants us to treat it like it has
21518                // an activity, okay!
21519                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21520                app.adjType = "cch-as-act";
21521            }
21522        }
21523
21524        if (adj == ProcessList.SERVICE_ADJ) {
21525            if (doingAll) {
21526                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21527                mNewNumServiceProcs++;
21528                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21529                if (!app.serviceb) {
21530                    // This service isn't far enough down on the LRU list to
21531                    // normally be a B service, but if we are low on RAM and it
21532                    // is large we want to force it down since we would prefer to
21533                    // keep launcher over it.
21534                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21535                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21536                        app.serviceHighRam = true;
21537                        app.serviceb = true;
21538                        //Slog.i(TAG, "ADJ " + app + " high ram!");
21539                    } else {
21540                        mNewNumAServiceProcs++;
21541                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
21542                    }
21543                } else {
21544                    app.serviceHighRam = false;
21545                }
21546            }
21547            if (app.serviceb) {
21548                adj = ProcessList.SERVICE_B_ADJ;
21549            }
21550        }
21551
21552        app.curRawAdj = adj;
21553
21554        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21555        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21556        if (adj > app.maxAdj) {
21557            adj = app.maxAdj;
21558            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21559                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21560            }
21561        }
21562
21563        // Do final modification to adj.  Everything we do between here and applying
21564        // the final setAdj must be done in this function, because we will also use
21565        // it when computing the final cached adj later.  Note that we don't need to
21566        // worry about this for max adj above, since max adj will always be used to
21567        // keep it out of the cached vaues.
21568        app.curAdj = app.modifyRawOomAdj(adj);
21569        app.curSchedGroup = schedGroup;
21570        app.curProcState = procState;
21571        app.foregroundActivities = foregroundActivities;
21572
21573        return app.curRawAdj;
21574    }
21575
21576    /**
21577     * Record new PSS sample for a process.
21578     */
21579    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21580            long now) {
21581        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21582                swapPss * 1024);
21583        proc.lastPssTime = now;
21584        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21585        if (DEBUG_PSS) Slog.d(TAG_PSS,
21586                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21587                + " state=" + ProcessList.makeProcStateString(procState));
21588        if (proc.initialIdlePss == 0) {
21589            proc.initialIdlePss = pss;
21590        }
21591        proc.lastPss = pss;
21592        proc.lastSwapPss = swapPss;
21593        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21594            proc.lastCachedPss = pss;
21595            proc.lastCachedSwapPss = swapPss;
21596        }
21597
21598        final SparseArray<Pair<Long, String>> watchUids
21599                = mMemWatchProcesses.getMap().get(proc.processName);
21600        Long check = null;
21601        if (watchUids != null) {
21602            Pair<Long, String> val = watchUids.get(proc.uid);
21603            if (val == null) {
21604                val = watchUids.get(0);
21605            }
21606            if (val != null) {
21607                check = val.first;
21608            }
21609        }
21610        if (check != null) {
21611            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21612                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21613                if (!isDebuggable) {
21614                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21615                        isDebuggable = true;
21616                    }
21617                }
21618                if (isDebuggable) {
21619                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21620                    final ProcessRecord myProc = proc;
21621                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21622                    mMemWatchDumpProcName = proc.processName;
21623                    mMemWatchDumpFile = heapdumpFile.toString();
21624                    mMemWatchDumpPid = proc.pid;
21625                    mMemWatchDumpUid = proc.uid;
21626                    BackgroundThread.getHandler().post(new Runnable() {
21627                        @Override
21628                        public void run() {
21629                            revokeUriPermission(ActivityThread.currentActivityThread()
21630                                            .getApplicationThread(),
21631                                    null, DumpHeapActivity.JAVA_URI,
21632                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21633                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21634                                    UserHandle.myUserId());
21635                            ParcelFileDescriptor fd = null;
21636                            try {
21637                                heapdumpFile.delete();
21638                                fd = ParcelFileDescriptor.open(heapdumpFile,
21639                                        ParcelFileDescriptor.MODE_CREATE |
21640                                                ParcelFileDescriptor.MODE_TRUNCATE |
21641                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21642                                                ParcelFileDescriptor.MODE_APPEND);
21643                                IApplicationThread thread = myProc.thread;
21644                                if (thread != null) {
21645                                    try {
21646                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21647                                                "Requesting dump heap from "
21648                                                + myProc + " to " + heapdumpFile);
21649                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
21650                                    } catch (RemoteException e) {
21651                                    }
21652                                }
21653                            } catch (FileNotFoundException e) {
21654                                e.printStackTrace();
21655                            } finally {
21656                                if (fd != null) {
21657                                    try {
21658                                        fd.close();
21659                                    } catch (IOException e) {
21660                                    }
21661                                }
21662                            }
21663                        }
21664                    });
21665                } else {
21666                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21667                            + ", but debugging not enabled");
21668                }
21669            }
21670        }
21671    }
21672
21673    /**
21674     * Schedule PSS collection of a process.
21675     */
21676    void requestPssLocked(ProcessRecord proc, int procState) {
21677        if (mPendingPssProcesses.contains(proc)) {
21678            return;
21679        }
21680        if (mPendingPssProcesses.size() == 0) {
21681            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21682        }
21683        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21684        proc.pssProcState = procState;
21685        mPendingPssProcesses.add(proc);
21686    }
21687
21688    /**
21689     * Schedule PSS collection of all processes.
21690     */
21691    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21692        if (!always) {
21693            if (now < (mLastFullPssTime +
21694                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21695                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
21696                return;
21697            }
21698        }
21699        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21700        mLastFullPssTime = now;
21701        mFullPssPending = true;
21702        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21703        mPendingPssProcesses.clear();
21704        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21705            ProcessRecord app = mLruProcesses.get(i);
21706            if (app.thread == null
21707                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21708                continue;
21709            }
21710            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21711                app.pssProcState = app.setProcState;
21712                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21713                        mTestPssMode, isSleepingLocked(), now);
21714                mPendingPssProcesses.add(app);
21715            }
21716        }
21717        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21718    }
21719
21720    public void setTestPssMode(boolean enabled) {
21721        synchronized (this) {
21722            mTestPssMode = enabled;
21723            if (enabled) {
21724                // Whenever we enable the mode, we want to take a snapshot all of current
21725                // process mem use.
21726                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21727            }
21728        }
21729    }
21730
21731    /**
21732     * Ask a given process to GC right now.
21733     */
21734    final void performAppGcLocked(ProcessRecord app) {
21735        try {
21736            app.lastRequestedGc = SystemClock.uptimeMillis();
21737            if (app.thread != null) {
21738                if (app.reportLowMemory) {
21739                    app.reportLowMemory = false;
21740                    app.thread.scheduleLowMemory();
21741                } else {
21742                    app.thread.processInBackground();
21743                }
21744            }
21745        } catch (Exception e) {
21746            // whatever.
21747        }
21748    }
21749
21750    /**
21751     * Returns true if things are idle enough to perform GCs.
21752     */
21753    private final boolean canGcNowLocked() {
21754        boolean processingBroadcasts = false;
21755        for (BroadcastQueue q : mBroadcastQueues) {
21756            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21757                processingBroadcasts = true;
21758            }
21759        }
21760        return !processingBroadcasts
21761                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21762    }
21763
21764    /**
21765     * Perform GCs on all processes that are waiting for it, but only
21766     * if things are idle.
21767     */
21768    final void performAppGcsLocked() {
21769        final int N = mProcessesToGc.size();
21770        if (N <= 0) {
21771            return;
21772        }
21773        if (canGcNowLocked()) {
21774            while (mProcessesToGc.size() > 0) {
21775                ProcessRecord proc = mProcessesToGc.remove(0);
21776                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21777                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21778                            <= SystemClock.uptimeMillis()) {
21779                        // To avoid spamming the system, we will GC processes one
21780                        // at a time, waiting a few seconds between each.
21781                        performAppGcLocked(proc);
21782                        scheduleAppGcsLocked();
21783                        return;
21784                    } else {
21785                        // It hasn't been long enough since we last GCed this
21786                        // process...  put it in the list to wait for its time.
21787                        addProcessToGcListLocked(proc);
21788                        break;
21789                    }
21790                }
21791            }
21792
21793            scheduleAppGcsLocked();
21794        }
21795    }
21796
21797    /**
21798     * If all looks good, perform GCs on all processes waiting for them.
21799     */
21800    final void performAppGcsIfAppropriateLocked() {
21801        if (canGcNowLocked()) {
21802            performAppGcsLocked();
21803            return;
21804        }
21805        // Still not idle, wait some more.
21806        scheduleAppGcsLocked();
21807    }
21808
21809    /**
21810     * Schedule the execution of all pending app GCs.
21811     */
21812    final void scheduleAppGcsLocked() {
21813        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21814
21815        if (mProcessesToGc.size() > 0) {
21816            // Schedule a GC for the time to the next process.
21817            ProcessRecord proc = mProcessesToGc.get(0);
21818            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21819
21820            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21821            long now = SystemClock.uptimeMillis();
21822            if (when < (now+mConstants.GC_TIMEOUT)) {
21823                when = now + mConstants.GC_TIMEOUT;
21824            }
21825            mHandler.sendMessageAtTime(msg, when);
21826        }
21827    }
21828
21829    /**
21830     * Add a process to the array of processes waiting to be GCed.  Keeps the
21831     * list in sorted order by the last GC time.  The process can't already be
21832     * on the list.
21833     */
21834    final void addProcessToGcListLocked(ProcessRecord proc) {
21835        boolean added = false;
21836        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21837            if (mProcessesToGc.get(i).lastRequestedGc <
21838                    proc.lastRequestedGc) {
21839                added = true;
21840                mProcessesToGc.add(i+1, proc);
21841                break;
21842            }
21843        }
21844        if (!added) {
21845            mProcessesToGc.add(0, proc);
21846        }
21847    }
21848
21849    /**
21850     * Set up to ask a process to GC itself.  This will either do it
21851     * immediately, or put it on the list of processes to gc the next
21852     * time things are idle.
21853     */
21854    final void scheduleAppGcLocked(ProcessRecord app) {
21855        long now = SystemClock.uptimeMillis();
21856        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21857            return;
21858        }
21859        if (!mProcessesToGc.contains(app)) {
21860            addProcessToGcListLocked(app);
21861            scheduleAppGcsLocked();
21862        }
21863    }
21864
21865    final void checkExcessivePowerUsageLocked(boolean doKills) {
21866        updateCpuStatsNow();
21867
21868        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21869        boolean doWakeKills = doKills;
21870        boolean doCpuKills = doKills;
21871        if (mLastPowerCheckRealtime == 0) {
21872            doWakeKills = false;
21873        }
21874        if (mLastPowerCheckUptime == 0) {
21875            doCpuKills = false;
21876        }
21877        if (stats.isScreenOn()) {
21878            doWakeKills = false;
21879        }
21880        final long curRealtime = SystemClock.elapsedRealtime();
21881        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21882        final long curUptime = SystemClock.uptimeMillis();
21883        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21884        mLastPowerCheckRealtime = curRealtime;
21885        mLastPowerCheckUptime = curUptime;
21886        if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
21887            doWakeKills = false;
21888        }
21889        if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
21890            doCpuKills = false;
21891        }
21892        int i = mLruProcesses.size();
21893        while (i > 0) {
21894            i--;
21895            ProcessRecord app = mLruProcesses.get(i);
21896            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21897                long wtime;
21898                synchronized (stats) {
21899                    wtime = stats.getProcessWakeTime(app.info.uid,
21900                            app.pid, curRealtime);
21901                }
21902                long wtimeUsed = wtime - app.lastWakeTime;
21903                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21904                if (DEBUG_POWER) {
21905                    StringBuilder sb = new StringBuilder(128);
21906                    sb.append("Wake for ");
21907                    app.toShortString(sb);
21908                    sb.append(": over ");
21909                    TimeUtils.formatDuration(realtimeSince, sb);
21910                    sb.append(" used ");
21911                    TimeUtils.formatDuration(wtimeUsed, sb);
21912                    sb.append(" (");
21913                    sb.append((wtimeUsed*100)/realtimeSince);
21914                    sb.append("%)");
21915                    Slog.i(TAG_POWER, sb.toString());
21916                    sb.setLength(0);
21917                    sb.append("CPU for ");
21918                    app.toShortString(sb);
21919                    sb.append(": over ");
21920                    TimeUtils.formatDuration(uptimeSince, sb);
21921                    sb.append(" used ");
21922                    TimeUtils.formatDuration(cputimeUsed, sb);
21923                    sb.append(" (");
21924                    sb.append((cputimeUsed*100)/uptimeSince);
21925                    sb.append("%)");
21926                    Slog.i(TAG_POWER, sb.toString());
21927                }
21928                // If a process has held a wake lock for more
21929                // than 50% of the time during this period,
21930                // that sounds bad.  Kill!
21931                if (doWakeKills && realtimeSince > 0
21932                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
21933                    synchronized (stats) {
21934                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21935                                realtimeSince, wtimeUsed);
21936                    }
21937                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21938                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21939                } else if (doCpuKills && uptimeSince > 0
21940                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
21941                    synchronized (stats) {
21942                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21943                                uptimeSince, cputimeUsed);
21944                    }
21945                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21946                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21947                } else {
21948                    app.lastWakeTime = wtime;
21949                    app.lastCpuTime = app.curCpuTime;
21950                }
21951            }
21952        }
21953    }
21954
21955    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21956            long nowElapsed) {
21957        boolean success = true;
21958
21959        if (app.curRawAdj != app.setRawAdj) {
21960            app.setRawAdj = app.curRawAdj;
21961        }
21962
21963        int changes = 0;
21964
21965        if (app.curAdj != app.setAdj) {
21966            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21967            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21968                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21969                    + app.adjType);
21970            app.setAdj = app.curAdj;
21971            app.verifiedAdj = ProcessList.INVALID_ADJ;
21972        }
21973
21974        if (app.setSchedGroup != app.curSchedGroup) {
21975            int oldSchedGroup = app.setSchedGroup;
21976            app.setSchedGroup = app.curSchedGroup;
21977            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21978                    "Setting sched group of " + app.processName
21979                    + " to " + app.curSchedGroup);
21980            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21981                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21982                app.kill(app.waitingToKill, true);
21983                success = false;
21984            } else {
21985                int processGroup;
21986                switch (app.curSchedGroup) {
21987                    case ProcessList.SCHED_GROUP_BACKGROUND:
21988                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21989                        break;
21990                    case ProcessList.SCHED_GROUP_TOP_APP:
21991                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21992                        processGroup = THREAD_GROUP_TOP_APP;
21993                        break;
21994                    default:
21995                        processGroup = THREAD_GROUP_DEFAULT;
21996                        break;
21997                }
21998                long oldId = Binder.clearCallingIdentity();
21999                try {
22000                    setProcessGroup(app.pid, processGroup);
22001                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22002                        // do nothing if we already switched to RT
22003                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22004                            mVrController.onTopProcChangedLocked(app);
22005                            if (mUseFifoUiScheduling) {
22006                                // Switch UI pipeline for app to SCHED_FIFO
22007                                app.savedPriority = Process.getThreadPriority(app.pid);
22008                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22009                                if (app.renderThreadTid != 0) {
22010                                    scheduleAsFifoPriority(app.renderThreadTid,
22011                                        /* suppressLogs */true);
22012                                    if (DEBUG_OOM_ADJ) {
22013                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
22014                                            app.renderThreadTid + ") to FIFO");
22015                                    }
22016                                } else {
22017                                    if (DEBUG_OOM_ADJ) {
22018                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
22019                                    }
22020                                }
22021                            } else {
22022                                // Boost priority for top app UI and render threads
22023                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22024                                if (app.renderThreadTid != 0) {
22025                                    try {
22026                                        setThreadPriority(app.renderThreadTid,
22027                                                TOP_APP_PRIORITY_BOOST);
22028                                    } catch (IllegalArgumentException e) {
22029                                        // thread died, ignore
22030                                    }
22031                                }
22032                            }
22033                        }
22034                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22035                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22036                        mVrController.onTopProcChangedLocked(app);
22037                        if (mUseFifoUiScheduling) {
22038                            // Reset UI pipeline to SCHED_OTHER
22039                            setThreadScheduler(app.pid, SCHED_OTHER, 0);
22040                            setThreadPriority(app.pid, app.savedPriority);
22041                            if (app.renderThreadTid != 0) {
22042                                setThreadScheduler(app.renderThreadTid,
22043                                    SCHED_OTHER, 0);
22044                                setThreadPriority(app.renderThreadTid, -4);
22045                            }
22046                        } else {
22047                            // Reset priority for top app UI and render threads
22048                            setThreadPriority(app.pid, 0);
22049                            if (app.renderThreadTid != 0) {
22050                                setThreadPriority(app.renderThreadTid, 0);
22051                            }
22052                        }
22053                    }
22054                } catch (Exception e) {
22055                    if (false) {
22056                        Slog.w(TAG, "Failed setting process group of " + app.pid
22057                                + " to " + app.curSchedGroup);
22058                        Slog.w(TAG, "at location", e);
22059                    }
22060                } finally {
22061                    Binder.restoreCallingIdentity(oldId);
22062                }
22063            }
22064        }
22065        if (app.repForegroundActivities != app.foregroundActivities) {
22066            app.repForegroundActivities = app.foregroundActivities;
22067            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22068        }
22069        if (app.repProcState != app.curProcState) {
22070            app.repProcState = app.curProcState;
22071            if (app.thread != null) {
22072                try {
22073                    if (false) {
22074                        //RuntimeException h = new RuntimeException("here");
22075                        Slog.i(TAG, "Sending new process state " + app.repProcState
22076                                + " to " + app /*, h*/);
22077                    }
22078                    app.thread.setProcessState(app.repProcState);
22079                } catch (RemoteException e) {
22080                }
22081            }
22082        }
22083        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22084                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22085            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22086                // Experimental code to more aggressively collect pss while
22087                // running test...  the problem is that this tends to collect
22088                // the data right when a process is transitioning between process
22089                // states, which well tend to give noisy data.
22090                long start = SystemClock.uptimeMillis();
22091                long pss = Debug.getPss(app.pid, mTmpLong, null);
22092                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22093                mPendingPssProcesses.remove(app);
22094                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22095                        + " to " + app.curProcState + ": "
22096                        + (SystemClock.uptimeMillis()-start) + "ms");
22097            }
22098            app.lastStateTime = now;
22099            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22100                    mTestPssMode, isSleepingLocked(), now);
22101            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22102                    + ProcessList.makeProcStateString(app.setProcState) + " to "
22103                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22104                    + (app.nextPssTime-now) + ": " + app);
22105        } else {
22106            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22107                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22108                    mTestPssMode)))) {
22109                requestPssLocked(app, app.setProcState);
22110                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22111                        mTestPssMode, isSleepingLocked(), now);
22112            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22113                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22114        }
22115        if (app.setProcState != app.curProcState) {
22116            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22117                    "Proc state change of " + app.processName
22118                            + " to " + app.curProcState);
22119            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22120            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22121            if (setImportant && !curImportant) {
22122                // This app is no longer something we consider important enough to allow to
22123                // use arbitrary amounts of battery power.  Note
22124                // its current wake lock time to later know to kill it if
22125                // it is not behaving well.
22126                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22127                synchronized (stats) {
22128                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
22129                            app.pid, nowElapsed);
22130                }
22131                app.lastCpuTime = app.curCpuTime;
22132
22133            }
22134            // Inform UsageStats of important process state change
22135            // Must be called before updating setProcState
22136            maybeUpdateUsageStatsLocked(app, nowElapsed);
22137
22138            app.setProcState = app.curProcState;
22139            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22140                app.notCachedSinceIdle = false;
22141            }
22142            if (!doingAll) {
22143                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22144            } else {
22145                app.procStateChanged = true;
22146            }
22147        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22148                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22149            // For apps that sit around for a long time in the interactive state, we need
22150            // to report this at least once a day so they don't go idle.
22151            maybeUpdateUsageStatsLocked(app, nowElapsed);
22152        }
22153
22154        if (changes != 0) {
22155            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22156                    "Changes in " + app + ": " + changes);
22157            int i = mPendingProcessChanges.size()-1;
22158            ProcessChangeItem item = null;
22159            while (i >= 0) {
22160                item = mPendingProcessChanges.get(i);
22161                if (item.pid == app.pid) {
22162                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22163                            "Re-using existing item: " + item);
22164                    break;
22165                }
22166                i--;
22167            }
22168            if (i < 0) {
22169                // No existing item in pending changes; need a new one.
22170                final int NA = mAvailProcessChanges.size();
22171                if (NA > 0) {
22172                    item = mAvailProcessChanges.remove(NA-1);
22173                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22174                            "Retrieving available item: " + item);
22175                } else {
22176                    item = new ProcessChangeItem();
22177                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22178                            "Allocating new item: " + item);
22179                }
22180                item.changes = 0;
22181                item.pid = app.pid;
22182                item.uid = app.info.uid;
22183                if (mPendingProcessChanges.size() == 0) {
22184                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22185                            "*** Enqueueing dispatch processes changed!");
22186                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22187                }
22188                mPendingProcessChanges.add(item);
22189            }
22190            item.changes |= changes;
22191            item.foregroundActivities = app.repForegroundActivities;
22192            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22193                    "Item " + Integer.toHexString(System.identityHashCode(item))
22194                    + " " + app.toShortString() + ": changes=" + item.changes
22195                    + " foreground=" + item.foregroundActivities
22196                    + " type=" + app.adjType + " source=" + app.adjSource
22197                    + " target=" + app.adjTarget);
22198        }
22199
22200        return success;
22201    }
22202
22203    private boolean isEphemeralLocked(int uid) {
22204        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22205        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22206            return false;
22207        }
22208        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22209                packages[0]);
22210    }
22211
22212    @VisibleForTesting
22213    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22214        final UidRecord.ChangeItem pendingChange;
22215        if (uidRec == null || uidRec.pendingChange == null) {
22216            if (mPendingUidChanges.size() == 0) {
22217                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22218                        "*** Enqueueing dispatch uid changed!");
22219                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22220            }
22221            final int NA = mAvailUidChanges.size();
22222            if (NA > 0) {
22223                pendingChange = mAvailUidChanges.remove(NA-1);
22224                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22225                        "Retrieving available item: " + pendingChange);
22226            } else {
22227                pendingChange = new UidRecord.ChangeItem();
22228                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22229                        "Allocating new item: " + pendingChange);
22230            }
22231            if (uidRec != null) {
22232                uidRec.pendingChange = pendingChange;
22233                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
22234                    // If this uid is going away, and we haven't yet reported it is gone,
22235                    // then do so now.
22236                    change = UidRecord.CHANGE_GONE_IDLE;
22237                }
22238            } else if (uid < 0) {
22239                throw new IllegalArgumentException("No UidRecord or uid");
22240            }
22241            pendingChange.uidRecord = uidRec;
22242            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22243            mPendingUidChanges.add(pendingChange);
22244        } else {
22245            pendingChange = uidRec.pendingChange;
22246            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
22247                change = UidRecord.CHANGE_GONE_IDLE;
22248            }
22249        }
22250        pendingChange.change = change;
22251        pendingChange.processState = uidRec != null
22252                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22253        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22254        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22255        if (uidRec != null) {
22256            uidRec.updateLastDispatchedProcStateSeq(change);
22257        }
22258
22259        // Directly update the power manager, since we sit on top of it and it is critical
22260        // it be kept in sync (so wake locks will be held as soon as appropriate).
22261        if (mLocalPowerManager != null) {
22262            switch (change) {
22263                case UidRecord.CHANGE_GONE:
22264                case UidRecord.CHANGE_GONE_IDLE:
22265                    mLocalPowerManager.uidGone(pendingChange.uid);
22266                    break;
22267                case UidRecord.CHANGE_IDLE:
22268                    mLocalPowerManager.uidIdle(pendingChange.uid);
22269                    break;
22270                case UidRecord.CHANGE_ACTIVE:
22271                    mLocalPowerManager.uidActive(pendingChange.uid);
22272                    break;
22273                default:
22274                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
22275                            pendingChange.processState);
22276                    break;
22277            }
22278        }
22279    }
22280
22281    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22282            String authority) {
22283        if (app == null) return;
22284        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22285            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22286            if (userState == null) return;
22287            final long now = SystemClock.elapsedRealtime();
22288            Long lastReported = userState.mProviderLastReportedFg.get(authority);
22289            if (lastReported == null || lastReported < now - 60 * 1000L) {
22290                if (mSystemReady) {
22291                    // Cannot touch the user stats if not system ready
22292                    mUsageStatsService.reportContentProviderUsage(
22293                            authority, providerPkgName, app.userId);
22294                }
22295                userState.mProviderLastReportedFg.put(authority, now);
22296            }
22297        }
22298    }
22299
22300    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22301        if (DEBUG_USAGE_STATS) {
22302            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22303                    + "] state changes: old = " + app.setProcState + ", new = "
22304                    + app.curProcState);
22305        }
22306        if (mUsageStatsService == null) {
22307            return;
22308        }
22309        boolean isInteraction;
22310        // To avoid some abuse patterns, we are going to be careful about what we consider
22311        // to be an app interaction.  Being the top activity doesn't count while the display
22312        // is sleeping, nor do short foreground services.
22313        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22314            isInteraction = true;
22315            app.fgInteractionTime = 0;
22316        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22317            if (app.fgInteractionTime == 0) {
22318                app.fgInteractionTime = nowElapsed;
22319                isInteraction = false;
22320            } else {
22321                isInteraction = nowElapsed > app.fgInteractionTime
22322                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22323            }
22324        } else {
22325            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22326            app.fgInteractionTime = 0;
22327        }
22328        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22329                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22330            app.interactionEventTime = nowElapsed;
22331            String[] packages = app.getPackageList();
22332            if (packages != null) {
22333                for (int i = 0; i < packages.length; i++) {
22334                    mUsageStatsService.reportEvent(packages[i], app.userId,
22335                            UsageEvents.Event.SYSTEM_INTERACTION);
22336                }
22337            }
22338        }
22339        app.reportedInteraction = isInteraction;
22340        if (!isInteraction) {
22341            app.interactionEventTime = 0;
22342        }
22343    }
22344
22345    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22346        if (proc.thread != null) {
22347            if (proc.baseProcessTracker != null) {
22348                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22349            }
22350        }
22351    }
22352
22353    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22354            ProcessRecord TOP_APP, boolean doingAll, long now) {
22355        if (app.thread == null) {
22356            return false;
22357        }
22358
22359        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22360
22361        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22362    }
22363
22364    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22365            boolean oomAdj) {
22366        if (isForeground != proc.foregroundServices) {
22367            proc.foregroundServices = isForeground;
22368            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22369                    proc.info.uid);
22370            if (isForeground) {
22371                if (curProcs == null) {
22372                    curProcs = new ArrayList<ProcessRecord>();
22373                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22374                }
22375                if (!curProcs.contains(proc)) {
22376                    curProcs.add(proc);
22377                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22378                            proc.info.packageName, proc.info.uid);
22379                }
22380            } else {
22381                if (curProcs != null) {
22382                    if (curProcs.remove(proc)) {
22383                        mBatteryStatsService.noteEvent(
22384                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22385                                proc.info.packageName, proc.info.uid);
22386                        if (curProcs.size() <= 0) {
22387                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22388                        }
22389                    }
22390                }
22391            }
22392            if (oomAdj) {
22393                updateOomAdjLocked();
22394            }
22395        }
22396    }
22397
22398    private final ActivityRecord resumedAppLocked() {
22399        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22400        String pkg;
22401        int uid;
22402        if (act != null) {
22403            pkg = act.packageName;
22404            uid = act.info.applicationInfo.uid;
22405        } else {
22406            pkg = null;
22407            uid = -1;
22408        }
22409        // Has the UID or resumed package name changed?
22410        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22411                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22412            if (mCurResumedPackage != null) {
22413                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22414                        mCurResumedPackage, mCurResumedUid);
22415            }
22416            mCurResumedPackage = pkg;
22417            mCurResumedUid = uid;
22418            if (mCurResumedPackage != null) {
22419                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22420                        mCurResumedPackage, mCurResumedUid);
22421            }
22422        }
22423        return act;
22424    }
22425
22426    /**
22427     * Update OomAdj for a specific process.
22428     * @param app The process to update
22429     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22430     *                  if necessary, or skip.
22431     * @return whether updateOomAdjLocked(app) was successful.
22432     */
22433    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22434        final ActivityRecord TOP_ACT = resumedAppLocked();
22435        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22436        final boolean wasCached = app.cached;
22437
22438        mAdjSeq++;
22439
22440        // This is the desired cached adjusment we want to tell it to use.
22441        // If our app is currently cached, we know it, and that is it.  Otherwise,
22442        // we don't know it yet, and it needs to now be cached we will then
22443        // need to do a complete oom adj.
22444        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22445                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22446        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22447                SystemClock.uptimeMillis());
22448        if (oomAdjAll
22449                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22450            // Changed to/from cached state, so apps after it in the LRU
22451            // list may also be changed.
22452            updateOomAdjLocked();
22453        }
22454        return success;
22455    }
22456
22457    final void updateOomAdjLocked() {
22458        final ActivityRecord TOP_ACT = resumedAppLocked();
22459        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22460        final long now = SystemClock.uptimeMillis();
22461        final long nowElapsed = SystemClock.elapsedRealtime();
22462        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22463        final int N = mLruProcesses.size();
22464
22465        if (false) {
22466            RuntimeException e = new RuntimeException();
22467            e.fillInStackTrace();
22468            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22469        }
22470
22471        // Reset state in all uid records.
22472        for (int i=mActiveUids.size()-1; i>=0; i--) {
22473            final UidRecord uidRec = mActiveUids.valueAt(i);
22474            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22475                    "Starting update of " + uidRec);
22476            uidRec.reset();
22477        }
22478
22479        mStackSupervisor.rankTaskLayersIfNeeded();
22480
22481        mAdjSeq++;
22482        mNewNumServiceProcs = 0;
22483        mNewNumAServiceProcs = 0;
22484
22485        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22486        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22487
22488        // Let's determine how many processes we have running vs.
22489        // how many slots we have for background processes; we may want
22490        // to put multiple processes in a slot of there are enough of
22491        // them.
22492        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22493                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22494        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22495        if (numEmptyProcs > cachedProcessLimit) {
22496            // If there are more empty processes than our limit on cached
22497            // processes, then use the cached process limit for the factor.
22498            // This ensures that the really old empty processes get pushed
22499            // down to the bottom, so if we are running low on memory we will
22500            // have a better chance at keeping around more cached processes
22501            // instead of a gazillion empty processes.
22502            numEmptyProcs = cachedProcessLimit;
22503        }
22504        int emptyFactor = numEmptyProcs/numSlots;
22505        if (emptyFactor < 1) emptyFactor = 1;
22506        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22507        if (cachedFactor < 1) cachedFactor = 1;
22508        int stepCached = 0;
22509        int stepEmpty = 0;
22510        int numCached = 0;
22511        int numEmpty = 0;
22512        int numTrimming = 0;
22513
22514        mNumNonCachedProcs = 0;
22515        mNumCachedHiddenProcs = 0;
22516
22517        // First update the OOM adjustment for each of the
22518        // application processes based on their current state.
22519        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22520        int nextCachedAdj = curCachedAdj+1;
22521        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22522        int nextEmptyAdj = curEmptyAdj+2;
22523        for (int i=N-1; i>=0; i--) {
22524            ProcessRecord app = mLruProcesses.get(i);
22525            if (!app.killedByAm && app.thread != null) {
22526                app.procStateChanged = false;
22527                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22528
22529                // If we haven't yet assigned the final cached adj
22530                // to the process, do that now.
22531                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22532                    switch (app.curProcState) {
22533                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22534                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22535                            // This process is a cached process holding activities...
22536                            // assign it the next cached value for that type, and then
22537                            // step that cached level.
22538                            app.curRawAdj = curCachedAdj;
22539                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22540                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22541                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22542                                    + ")");
22543                            if (curCachedAdj != nextCachedAdj) {
22544                                stepCached++;
22545                                if (stepCached >= cachedFactor) {
22546                                    stepCached = 0;
22547                                    curCachedAdj = nextCachedAdj;
22548                                    nextCachedAdj += 2;
22549                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22550                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22551                                    }
22552                                }
22553                            }
22554                            break;
22555                        default:
22556                            // For everything else, assign next empty cached process
22557                            // level and bump that up.  Note that this means that
22558                            // long-running services that have dropped down to the
22559                            // cached level will be treated as empty (since their process
22560                            // state is still as a service), which is what we want.
22561                            app.curRawAdj = curEmptyAdj;
22562                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22563                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22564                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22565                                    + ")");
22566                            if (curEmptyAdj != nextEmptyAdj) {
22567                                stepEmpty++;
22568                                if (stepEmpty >= emptyFactor) {
22569                                    stepEmpty = 0;
22570                                    curEmptyAdj = nextEmptyAdj;
22571                                    nextEmptyAdj += 2;
22572                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22573                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22574                                    }
22575                                }
22576                            }
22577                            break;
22578                    }
22579                }
22580
22581                applyOomAdjLocked(app, true, now, nowElapsed);
22582
22583                // Count the number of process types.
22584                switch (app.curProcState) {
22585                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22586                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22587                        mNumCachedHiddenProcs++;
22588                        numCached++;
22589                        if (numCached > cachedProcessLimit) {
22590                            app.kill("cached #" + numCached, true);
22591                        }
22592                        break;
22593                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22594                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22595                                && app.lastActivityTime < oldTime) {
22596                            app.kill("empty for "
22597                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22598                                    / 1000) + "s", true);
22599                        } else {
22600                            numEmpty++;
22601                            if (numEmpty > emptyProcessLimit) {
22602                                app.kill("empty #" + numEmpty, true);
22603                            }
22604                        }
22605                        break;
22606                    default:
22607                        mNumNonCachedProcs++;
22608                        break;
22609                }
22610
22611                if (app.isolated && app.services.size() <= 0) {
22612                    // If this is an isolated process, and there are no
22613                    // services running in it, then the process is no longer
22614                    // needed.  We agressively kill these because we can by
22615                    // definition not re-use the same process again, and it is
22616                    // good to avoid having whatever code was running in them
22617                    // left sitting around after no longer needed.
22618                    app.kill("isolated not needed", true);
22619                } else {
22620                    // Keeping this process, update its uid.
22621                    final UidRecord uidRec = app.uidRecord;
22622                    if (uidRec != null) {
22623                        uidRec.ephemeral = app.info.isInstantApp();
22624                        if (uidRec.curProcState > app.curProcState) {
22625                            uidRec.curProcState = app.curProcState;
22626                        }
22627                        if (app.foregroundServices) {
22628                            uidRec.foregroundServices = true;
22629                        }
22630                    }
22631                }
22632
22633                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22634                        && !app.killedByAm) {
22635                    numTrimming++;
22636                }
22637            }
22638        }
22639
22640        incrementProcStateSeqAndNotifyAppsLocked();
22641
22642        mNumServiceProcs = mNewNumServiceProcs;
22643
22644        // Now determine the memory trimming level of background processes.
22645        // Unfortunately we need to start at the back of the list to do this
22646        // properly.  We only do this if the number of background apps we
22647        // are managing to keep around is less than half the maximum we desire;
22648        // if we are keeping a good number around, we'll let them use whatever
22649        // memory they want.
22650        final int numCachedAndEmpty = numCached + numEmpty;
22651        int memFactor;
22652        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22653                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22654            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22655                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22656            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22657                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22658            } else {
22659                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22660            }
22661        } else {
22662            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22663        }
22664        // We always allow the memory level to go up (better).  We only allow it to go
22665        // down if we are in a state where that is allowed, *and* the total number of processes
22666        // has gone down since last time.
22667        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22668                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22669                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22670        if (memFactor > mLastMemoryLevel) {
22671            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22672                memFactor = mLastMemoryLevel;
22673                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22674            }
22675        }
22676        if (memFactor != mLastMemoryLevel) {
22677            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22678        }
22679        mLastMemoryLevel = memFactor;
22680        mLastNumProcesses = mLruProcesses.size();
22681        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22682        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22683        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22684            if (mLowRamStartTime == 0) {
22685                mLowRamStartTime = now;
22686            }
22687            int step = 0;
22688            int fgTrimLevel;
22689            switch (memFactor) {
22690                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22691                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22692                    break;
22693                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22694                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22695                    break;
22696                default:
22697                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22698                    break;
22699            }
22700            int factor = numTrimming/3;
22701            int minFactor = 2;
22702            if (mHomeProcess != null) minFactor++;
22703            if (mPreviousProcess != null) minFactor++;
22704            if (factor < minFactor) factor = minFactor;
22705            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22706            for (int i=N-1; i>=0; i--) {
22707                ProcessRecord app = mLruProcesses.get(i);
22708                if (allChanged || app.procStateChanged) {
22709                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22710                    app.procStateChanged = false;
22711                }
22712                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22713                        && !app.killedByAm) {
22714                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22715                        try {
22716                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22717                                    "Trimming memory of " + app.processName + " to " + curLevel);
22718                            app.thread.scheduleTrimMemory(curLevel);
22719                        } catch (RemoteException e) {
22720                        }
22721                        if (false) {
22722                            // For now we won't do this; our memory trimming seems
22723                            // to be good enough at this point that destroying
22724                            // activities causes more harm than good.
22725                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22726                                    && app != mHomeProcess && app != mPreviousProcess) {
22727                                // Need to do this on its own message because the stack may not
22728                                // be in a consistent state at this point.
22729                                // For these apps we will also finish their activities
22730                                // to help them free memory.
22731                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22732                            }
22733                        }
22734                    }
22735                    app.trimMemoryLevel = curLevel;
22736                    step++;
22737                    if (step >= factor) {
22738                        step = 0;
22739                        switch (curLevel) {
22740                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22741                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22742                                break;
22743                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22744                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22745                                break;
22746                        }
22747                    }
22748                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22749                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22750                            && app.thread != null) {
22751                        try {
22752                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22753                                    "Trimming memory of heavy-weight " + app.processName
22754                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22755                            app.thread.scheduleTrimMemory(
22756                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22757                        } catch (RemoteException e) {
22758                        }
22759                    }
22760                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22761                } else {
22762                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22763                            || app.systemNoUi) && app.pendingUiClean) {
22764                        // If this application is now in the background and it
22765                        // had done UI, then give it the special trim level to
22766                        // have it free UI resources.
22767                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22768                        if (app.trimMemoryLevel < level && app.thread != null) {
22769                            try {
22770                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22771                                        "Trimming memory of bg-ui " + app.processName
22772                                        + " to " + level);
22773                                app.thread.scheduleTrimMemory(level);
22774                            } catch (RemoteException e) {
22775                            }
22776                        }
22777                        app.pendingUiClean = false;
22778                    }
22779                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22780                        try {
22781                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22782                                    "Trimming memory of fg " + app.processName
22783                                    + " to " + fgTrimLevel);
22784                            app.thread.scheduleTrimMemory(fgTrimLevel);
22785                        } catch (RemoteException e) {
22786                        }
22787                    }
22788                    app.trimMemoryLevel = fgTrimLevel;
22789                }
22790            }
22791        } else {
22792            if (mLowRamStartTime != 0) {
22793                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22794                mLowRamStartTime = 0;
22795            }
22796            for (int i=N-1; i>=0; i--) {
22797                ProcessRecord app = mLruProcesses.get(i);
22798                if (allChanged || app.procStateChanged) {
22799                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22800                    app.procStateChanged = false;
22801                }
22802                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22803                        || app.systemNoUi) && app.pendingUiClean) {
22804                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22805                            && app.thread != null) {
22806                        try {
22807                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22808                                    "Trimming memory of ui hidden " + app.processName
22809                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22810                            app.thread.scheduleTrimMemory(
22811                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22812                        } catch (RemoteException e) {
22813                        }
22814                    }
22815                    app.pendingUiClean = false;
22816                }
22817                app.trimMemoryLevel = 0;
22818            }
22819        }
22820
22821        if (mAlwaysFinishActivities) {
22822            // Need to do this on its own message because the stack may not
22823            // be in a consistent state at this point.
22824            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22825        }
22826
22827        if (allChanged) {
22828            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22829        }
22830
22831        // Update from any uid changes.
22832        if (mLocalPowerManager != null) {
22833            mLocalPowerManager.startUidChanges();
22834        }
22835        for (int i=mActiveUids.size()-1; i>=0; i--) {
22836            final UidRecord uidRec = mActiveUids.valueAt(i);
22837            int uidChange = UidRecord.CHANGE_PROCSTATE;
22838            if (uidRec.setProcState != uidRec.curProcState
22839                    || uidRec.setWhitelist != uidRec.curWhitelist) {
22840                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22841                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22842                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22843                        + " to " + uidRec.curWhitelist);
22844                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22845                        && !uidRec.curWhitelist) {
22846                    // UID is now in the background (and not on the temp whitelist).  Was it
22847                    // previously in the foreground (or on the temp whitelist)?
22848                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22849                            || uidRec.setWhitelist) {
22850                        uidRec.lastBackgroundTime = nowElapsed;
22851                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22852                            // Note: the background settle time is in elapsed realtime, while
22853                            // the handler time base is uptime.  All this means is that we may
22854                            // stop background uids later than we had intended, but that only
22855                            // happens because the device was sleeping so we are okay anyway.
22856                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22857                                    mConstants.BACKGROUND_SETTLE_TIME);
22858                        }
22859                    }
22860                } else {
22861                    if (uidRec.idle) {
22862                        uidChange = UidRecord.CHANGE_ACTIVE;
22863                        EventLogTags.writeAmUidActive(uidRec.uid);
22864                        uidRec.idle = false;
22865                    }
22866                    uidRec.lastBackgroundTime = 0;
22867                }
22868                uidRec.setProcState = uidRec.curProcState;
22869                uidRec.setWhitelist = uidRec.curWhitelist;
22870                enqueueUidChangeLocked(uidRec, -1, uidChange);
22871                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22872                if (uidRec.foregroundServices) {
22873                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
22874                }
22875            }
22876        }
22877        if (mLocalPowerManager != null) {
22878            mLocalPowerManager.finishUidChanges();
22879        }
22880
22881        if (mProcessStats.shouldWriteNowLocked(now)) {
22882            mHandler.post(new Runnable() {
22883                @Override public void run() {
22884                    synchronized (ActivityManagerService.this) {
22885                        mProcessStats.writeStateAsyncLocked();
22886                    }
22887                }
22888            });
22889        }
22890
22891        if (DEBUG_OOM_ADJ) {
22892            final long duration = SystemClock.uptimeMillis() - now;
22893            if (false) {
22894                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22895                        new RuntimeException("here").fillInStackTrace());
22896            } else {
22897                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22898            }
22899        }
22900    }
22901
22902    @Override
22903    public void makePackageIdle(String packageName, int userId) {
22904        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22905                != PackageManager.PERMISSION_GRANTED) {
22906            String msg = "Permission Denial: makePackageIdle() from pid="
22907                    + Binder.getCallingPid()
22908                    + ", uid=" + Binder.getCallingUid()
22909                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22910            Slog.w(TAG, msg);
22911            throw new SecurityException(msg);
22912        }
22913        final int callingPid = Binder.getCallingPid();
22914        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22915                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22916        long callingId = Binder.clearCallingIdentity();
22917        synchronized(this) {
22918            try {
22919                IPackageManager pm = AppGlobals.getPackageManager();
22920                int pkgUid = -1;
22921                try {
22922                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22923                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22924                } catch (RemoteException e) {
22925                }
22926                if (pkgUid == -1) {
22927                    throw new IllegalArgumentException("Unknown package name " + packageName);
22928                }
22929
22930                if (mLocalPowerManager != null) {
22931                    mLocalPowerManager.startUidChanges();
22932                }
22933                final int appId = UserHandle.getAppId(pkgUid);
22934                final int N = mActiveUids.size();
22935                for (int i=N-1; i>=0; i--) {
22936                    final UidRecord uidRec = mActiveUids.valueAt(i);
22937                    final long bgTime = uidRec.lastBackgroundTime;
22938                    if (bgTime > 0 && !uidRec.idle) {
22939                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22940                            if (userId == UserHandle.USER_ALL ||
22941                                    userId == UserHandle.getUserId(uidRec.uid)) {
22942                                EventLogTags.writeAmUidIdle(uidRec.uid);
22943                                uidRec.idle = true;
22944                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22945                                        + " from package " + packageName + " user " + userId);
22946                                doStopUidLocked(uidRec.uid, uidRec);
22947                            }
22948                        }
22949                    }
22950                }
22951            } finally {
22952                if (mLocalPowerManager != null) {
22953                    mLocalPowerManager.finishUidChanges();
22954                }
22955                Binder.restoreCallingIdentity(callingId);
22956            }
22957        }
22958    }
22959
22960    final void idleUids() {
22961        synchronized (this) {
22962            final int N = mActiveUids.size();
22963            if (N <= 0) {
22964                return;
22965            }
22966            final long nowElapsed = SystemClock.elapsedRealtime();
22967            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22968            long nextTime = 0;
22969            if (mLocalPowerManager != null) {
22970                mLocalPowerManager.startUidChanges();
22971            }
22972            for (int i=N-1; i>=0; i--) {
22973                final UidRecord uidRec = mActiveUids.valueAt(i);
22974                final long bgTime = uidRec.lastBackgroundTime;
22975                if (bgTime > 0 && !uidRec.idle) {
22976                    if (bgTime <= maxBgTime) {
22977                        EventLogTags.writeAmUidIdle(uidRec.uid);
22978                        uidRec.idle = true;
22979                        doStopUidLocked(uidRec.uid, uidRec);
22980                    } else {
22981                        if (nextTime == 0 || nextTime > bgTime) {
22982                            nextTime = bgTime;
22983                        }
22984                    }
22985                }
22986            }
22987            if (mLocalPowerManager != null) {
22988                mLocalPowerManager.finishUidChanges();
22989            }
22990            if (nextTime > 0) {
22991                mHandler.removeMessages(IDLE_UIDS_MSG);
22992                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22993                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
22994            }
22995        }
22996    }
22997
22998    /**
22999     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23000     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23001     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23002     */
23003    @VisibleForTesting
23004    @GuardedBy("this")
23005    void incrementProcStateSeqAndNotifyAppsLocked() {
23006        if (mWaitForNetworkTimeoutMs <= 0) {
23007            return;
23008        }
23009        // Used for identifying which uids need to block for network.
23010        ArrayList<Integer> blockingUids = null;
23011        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23012            final UidRecord uidRec = mActiveUids.valueAt(i);
23013            // If the network is not restricted for uid, then nothing to do here.
23014            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23015                continue;
23016            }
23017            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23018                continue;
23019            }
23020            // If process state is not changed, then there's nothing to do.
23021            if (uidRec.setProcState == uidRec.curProcState) {
23022                continue;
23023            }
23024            final int blockState = getBlockStateForUid(uidRec);
23025            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23026            // there's nothing the app needs to do in this scenario.
23027            if (blockState == NETWORK_STATE_NO_CHANGE) {
23028                continue;
23029            }
23030            synchronized (uidRec.networkStateLock) {
23031                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23032                if (blockState == NETWORK_STATE_BLOCK) {
23033                    if (blockingUids == null) {
23034                        blockingUids = new ArrayList<>();
23035                    }
23036                    blockingUids.add(uidRec.uid);
23037                } else {
23038                    if (DEBUG_NETWORK) {
23039                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23040                                + " threads for uid: " + uidRec);
23041                    }
23042                    if (uidRec.waitingForNetwork) {
23043                        uidRec.networkStateLock.notifyAll();
23044                    }
23045                }
23046            }
23047        }
23048
23049        // There are no uids that need to block, so nothing more to do.
23050        if (blockingUids == null) {
23051            return;
23052        }
23053
23054        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23055            final ProcessRecord app = mLruProcesses.get(i);
23056            if (!blockingUids.contains(app.uid)) {
23057                continue;
23058            }
23059            if (!app.killedByAm && app.thread != null) {
23060                final UidRecord uidRec = mActiveUids.get(app.uid);
23061                try {
23062                    if (DEBUG_NETWORK) {
23063                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23064                                + uidRec);
23065                    }
23066                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23067                } catch (RemoteException ignored) {
23068                }
23069            }
23070        }
23071    }
23072
23073    /**
23074     * Checks if the uid is coming from background to foreground or vice versa and returns
23075     * appropriate block state based on this.
23076     *
23077     * @return blockState based on whether the uid is coming from background to foreground or
23078     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23079     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23080     *         {@link #NETWORK_STATE_NO_CHANGE}.
23081     */
23082    @VisibleForTesting
23083    int getBlockStateForUid(UidRecord uidRec) {
23084        // Denotes whether uid's process state is currently allowed network access.
23085        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23086                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23087        // Denotes whether uid's process state was previously allowed network access.
23088        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23089                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23090
23091        // When the uid is coming to foreground, AMS should inform the app thread that it should
23092        // block for the network rules to get updated before launching an activity.
23093        if (!wasAllowed && isAllowed) {
23094            return NETWORK_STATE_BLOCK;
23095        }
23096        // When the uid is going to background, AMS should inform the app thread that if an
23097        // activity launch is blocked for the network rules to get updated, it should be unblocked.
23098        if (wasAllowed && !isAllowed) {
23099            return NETWORK_STATE_UNBLOCK;
23100        }
23101        return NETWORK_STATE_NO_CHANGE;
23102    }
23103
23104    final void runInBackgroundDisabled(int uid) {
23105        synchronized (this) {
23106            UidRecord uidRec = mActiveUids.get(uid);
23107            if (uidRec != null) {
23108                // This uid is actually running...  should it be considered background now?
23109                if (uidRec.idle) {
23110                    doStopUidLocked(uidRec.uid, uidRec);
23111                }
23112            } else {
23113                // This uid isn't actually running...  still send a report about it being "stopped".
23114                doStopUidLocked(uid, null);
23115            }
23116        }
23117    }
23118
23119    final void doStopUidLocked(int uid, final UidRecord uidRec) {
23120        mServices.stopInBackgroundLocked(uid);
23121        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23122    }
23123
23124    /**
23125     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23126     */
23127    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23128            long duration, String tag) {
23129        if (DEBUG_WHITELISTS) {
23130            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23131                    + targetUid + ", " + duration + ")");
23132        }
23133
23134        synchronized (mPidsSelfLocked) {
23135            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23136            if (pr == null) {
23137                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23138                        + callerPid);
23139                return;
23140            }
23141            if (!pr.whitelistManager) {
23142                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23143                        != PackageManager.PERMISSION_GRANTED) {
23144                    if (DEBUG_WHITELISTS) {
23145                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23146                                + ": pid " + callerPid + " is not allowed");
23147                    }
23148                    return;
23149                }
23150            }
23151        }
23152
23153        tempWhitelistUidLocked(targetUid, duration, tag);
23154    }
23155
23156    /**
23157     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23158     */
23159    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23160        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23161        setUidTempWhitelistStateLocked(targetUid, true);
23162        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23163    }
23164
23165    void pushTempWhitelist() {
23166        final int N;
23167        final PendingTempWhitelist[] list;
23168
23169        // First copy out the pending changes...  we need to leave them in the map for now,
23170        // in case someone needs to check what is coming up while we don't have the lock held.
23171        synchronized(this) {
23172            N = mPendingTempWhitelist.size();
23173            list = new PendingTempWhitelist[N];
23174            for (int i = 0; i < N; i++) {
23175                list[i] = mPendingTempWhitelist.valueAt(i);
23176            }
23177        }
23178
23179        // Now safely dispatch changes to device idle controller.
23180        for (int i = 0; i < N; i++) {
23181            PendingTempWhitelist ptw = list[i];
23182            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23183                    ptw.duration, true, ptw.tag);
23184        }
23185
23186        // And now we can safely remove them from the map.
23187        synchronized(this) {
23188            for (int i = 0; i < N; i++) {
23189                PendingTempWhitelist ptw = list[i];
23190                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23191                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23192                    mPendingTempWhitelist.removeAt(index);
23193                }
23194            }
23195        }
23196    }
23197
23198    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23199        boolean changed = false;
23200        for (int i=mActiveUids.size()-1; i>=0; i--) {
23201            final UidRecord uidRec = mActiveUids.valueAt(i);
23202            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23203                uidRec.curWhitelist = onWhitelist;
23204                changed = true;
23205            }
23206        }
23207        if (changed) {
23208            updateOomAdjLocked();
23209        }
23210    }
23211
23212    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23213        boolean changed = false;
23214        final UidRecord uidRec = mActiveUids.get(uid);
23215        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23216            uidRec.curWhitelist = onWhitelist;
23217            updateOomAdjLocked();
23218        }
23219    }
23220
23221    final void trimApplications() {
23222        synchronized (this) {
23223            int i;
23224
23225            // First remove any unused application processes whose package
23226            // has been removed.
23227            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23228                final ProcessRecord app = mRemovedProcesses.get(i);
23229                if (app.activities.size() == 0
23230                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
23231                    Slog.i(
23232                        TAG, "Exiting empty application process "
23233                        + app.toShortString() + " ("
23234                        + (app.thread != null ? app.thread.asBinder() : null)
23235                        + ")\n");
23236                    if (app.pid > 0 && app.pid != MY_PID) {
23237                        app.kill("empty", false);
23238                    } else {
23239                        try {
23240                            app.thread.scheduleExit();
23241                        } catch (Exception e) {
23242                            // Ignore exceptions.
23243                        }
23244                    }
23245                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23246                    mRemovedProcesses.remove(i);
23247
23248                    if (app.persistent) {
23249                        addAppLocked(app.info, null, false, null /* ABI override */);
23250                    }
23251                }
23252            }
23253
23254            // Now update the oom adj for all processes.
23255            updateOomAdjLocked();
23256        }
23257    }
23258
23259    /** This method sends the specified signal to each of the persistent apps */
23260    public void signalPersistentProcesses(int sig) throws RemoteException {
23261        if (sig != SIGNAL_USR1) {
23262            throw new SecurityException("Only SIGNAL_USR1 is allowed");
23263        }
23264
23265        synchronized (this) {
23266            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23267                    != PackageManager.PERMISSION_GRANTED) {
23268                throw new SecurityException("Requires permission "
23269                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23270            }
23271
23272            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23273                ProcessRecord r = mLruProcesses.get(i);
23274                if (r.thread != null && r.persistent) {
23275                    sendSignal(r.pid, sig);
23276                }
23277            }
23278        }
23279    }
23280
23281    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23282        if (proc == null || proc == mProfileProc) {
23283            proc = mProfileProc;
23284            profileType = mProfileType;
23285            clearProfilerLocked();
23286        }
23287        if (proc == null) {
23288            return;
23289        }
23290        try {
23291            proc.thread.profilerControl(false, null, profileType);
23292        } catch (RemoteException e) {
23293            throw new IllegalStateException("Process disappeared");
23294        }
23295    }
23296
23297    private void clearProfilerLocked() {
23298        if (mProfileFd != null) {
23299            try {
23300                mProfileFd.close();
23301            } catch (IOException e) {
23302            }
23303        }
23304        mProfileApp = null;
23305        mProfileProc = null;
23306        mProfileFile = null;
23307        mProfileType = 0;
23308        mAutoStopProfiler = false;
23309        mStreamingOutput = false;
23310        mSamplingInterval = 0;
23311    }
23312
23313    public boolean profileControl(String process, int userId, boolean start,
23314            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23315
23316        try {
23317            synchronized (this) {
23318                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23319                // its own permission.
23320                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23321                        != PackageManager.PERMISSION_GRANTED) {
23322                    throw new SecurityException("Requires permission "
23323                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23324                }
23325
23326                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23327                    throw new IllegalArgumentException("null profile info or fd");
23328                }
23329
23330                ProcessRecord proc = null;
23331                if (process != null) {
23332                    proc = findProcessLocked(process, userId, "profileControl");
23333                }
23334
23335                if (start && (proc == null || proc.thread == null)) {
23336                    throw new IllegalArgumentException("Unknown process: " + process);
23337                }
23338
23339                if (start) {
23340                    stopProfilerLocked(null, 0);
23341                    setProfileApp(proc.info, proc.processName, profilerInfo);
23342                    mProfileProc = proc;
23343                    mProfileType = profileType;
23344                    ParcelFileDescriptor fd = profilerInfo.profileFd;
23345                    try {
23346                        fd = fd.dup();
23347                    } catch (IOException e) {
23348                        fd = null;
23349                    }
23350                    profilerInfo.profileFd = fd;
23351                    proc.thread.profilerControl(start, profilerInfo, profileType);
23352                    fd = null;
23353                    try {
23354                        mProfileFd.close();
23355                    } catch (IOException e) {
23356                    }
23357                    mProfileFd = null;
23358                } else {
23359                    stopProfilerLocked(proc, profileType);
23360                    if (profilerInfo != null && profilerInfo.profileFd != null) {
23361                        try {
23362                            profilerInfo.profileFd.close();
23363                        } catch (IOException e) {
23364                        }
23365                    }
23366                }
23367
23368                return true;
23369            }
23370        } catch (RemoteException e) {
23371            throw new IllegalStateException("Process disappeared");
23372        } finally {
23373            if (profilerInfo != null && profilerInfo.profileFd != null) {
23374                try {
23375                    profilerInfo.profileFd.close();
23376                } catch (IOException e) {
23377                }
23378            }
23379        }
23380    }
23381
23382    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23383        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23384                userId, true, ALLOW_FULL_ONLY, callName, null);
23385        ProcessRecord proc = null;
23386        try {
23387            int pid = Integer.parseInt(process);
23388            synchronized (mPidsSelfLocked) {
23389                proc = mPidsSelfLocked.get(pid);
23390            }
23391        } catch (NumberFormatException e) {
23392        }
23393
23394        if (proc == null) {
23395            ArrayMap<String, SparseArray<ProcessRecord>> all
23396                    = mProcessNames.getMap();
23397            SparseArray<ProcessRecord> procs = all.get(process);
23398            if (procs != null && procs.size() > 0) {
23399                proc = procs.valueAt(0);
23400                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23401                    for (int i=1; i<procs.size(); i++) {
23402                        ProcessRecord thisProc = procs.valueAt(i);
23403                        if (thisProc.userId == userId) {
23404                            proc = thisProc;
23405                            break;
23406                        }
23407                    }
23408                }
23409            }
23410        }
23411
23412        return proc;
23413    }
23414
23415    public boolean dumpHeap(String process, int userId, boolean managed,
23416            String path, ParcelFileDescriptor fd) throws RemoteException {
23417
23418        try {
23419            synchronized (this) {
23420                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23421                // its own permission (same as profileControl).
23422                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23423                        != PackageManager.PERMISSION_GRANTED) {
23424                    throw new SecurityException("Requires permission "
23425                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23426                }
23427
23428                if (fd == null) {
23429                    throw new IllegalArgumentException("null fd");
23430                }
23431
23432                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23433                if (proc == null || proc.thread == null) {
23434                    throw new IllegalArgumentException("Unknown process: " + process);
23435                }
23436
23437                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23438                if (!isDebuggable) {
23439                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23440                        throw new SecurityException("Process not debuggable: " + proc);
23441                    }
23442                }
23443
23444                proc.thread.dumpHeap(managed, path, fd);
23445                fd = null;
23446                return true;
23447            }
23448        } catch (RemoteException e) {
23449            throw new IllegalStateException("Process disappeared");
23450        } finally {
23451            if (fd != null) {
23452                try {
23453                    fd.close();
23454                } catch (IOException e) {
23455                }
23456            }
23457        }
23458    }
23459
23460    @Override
23461    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23462            String reportPackage) {
23463        if (processName != null) {
23464            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23465                    "setDumpHeapDebugLimit()");
23466        } else {
23467            synchronized (mPidsSelfLocked) {
23468                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23469                if (proc == null) {
23470                    throw new SecurityException("No process found for calling pid "
23471                            + Binder.getCallingPid());
23472                }
23473                if (!Build.IS_DEBUGGABLE
23474                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23475                    throw new SecurityException("Not running a debuggable build");
23476                }
23477                processName = proc.processName;
23478                uid = proc.uid;
23479                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23480                    throw new SecurityException("Package " + reportPackage + " is not running in "
23481                            + proc);
23482                }
23483            }
23484        }
23485        synchronized (this) {
23486            if (maxMemSize > 0) {
23487                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23488            } else {
23489                if (uid != 0) {
23490                    mMemWatchProcesses.remove(processName, uid);
23491                } else {
23492                    mMemWatchProcesses.getMap().remove(processName);
23493                }
23494            }
23495        }
23496    }
23497
23498    @Override
23499    public void dumpHeapFinished(String path) {
23500        synchronized (this) {
23501            if (Binder.getCallingPid() != mMemWatchDumpPid) {
23502                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23503                        + " does not match last pid " + mMemWatchDumpPid);
23504                return;
23505            }
23506            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23507                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23508                        + " does not match last path " + mMemWatchDumpFile);
23509                return;
23510            }
23511            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23512            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23513        }
23514    }
23515
23516    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23517    public void monitor() {
23518        synchronized (this) { }
23519    }
23520
23521    void onCoreSettingsChange(Bundle settings) {
23522        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23523            ProcessRecord processRecord = mLruProcesses.get(i);
23524            try {
23525                if (processRecord.thread != null) {
23526                    processRecord.thread.setCoreSettings(settings);
23527                }
23528            } catch (RemoteException re) {
23529                /* ignore */
23530            }
23531        }
23532    }
23533
23534    // Multi-user methods
23535
23536    /**
23537     * Start user, if its not already running, but don't bring it to foreground.
23538     */
23539    @Override
23540    public boolean startUserInBackground(final int userId) {
23541        return mUserController.startUser(userId, /* foreground */ false);
23542    }
23543
23544    @Override
23545    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23546        return mUserController.unlockUser(userId, token, secret, listener);
23547    }
23548
23549    @Override
23550    public boolean switchUser(final int targetUserId) {
23551        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23552        int currentUserId;
23553        UserInfo targetUserInfo;
23554        synchronized (this) {
23555            currentUserId = mUserController.getCurrentUserIdLocked();
23556            targetUserInfo = mUserController.getUserInfo(targetUserId);
23557            if (targetUserId == currentUserId) {
23558                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23559                return true;
23560            }
23561            if (targetUserInfo == null) {
23562                Slog.w(TAG, "No user info for user #" + targetUserId);
23563                return false;
23564            }
23565            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23566                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23567                        + " when device is in demo mode");
23568                return false;
23569            }
23570            if (!targetUserInfo.supportsSwitchTo()) {
23571                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23572                return false;
23573            }
23574            if (targetUserInfo.isManagedProfile()) {
23575                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23576                return false;
23577            }
23578            mUserController.setTargetUserIdLocked(targetUserId);
23579        }
23580        if (mUserController.mUserSwitchUiEnabled) {
23581            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23582            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23583            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23584            mUiHandler.sendMessage(mHandler.obtainMessage(
23585                    START_USER_SWITCH_UI_MSG, userNames));
23586        } else {
23587            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23588            mHandler.sendMessage(mHandler.obtainMessage(
23589                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
23590        }
23591        return true;
23592    }
23593
23594    void scheduleStartProfilesLocked() {
23595        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23596            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23597                    DateUtils.SECOND_IN_MILLIS);
23598        }
23599    }
23600
23601    @Override
23602    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23603        return mUserController.stopUser(userId, force, callback);
23604    }
23605
23606    @Override
23607    public UserInfo getCurrentUser() {
23608        return mUserController.getCurrentUser();
23609    }
23610
23611    String getStartedUserState(int userId) {
23612        synchronized (this) {
23613            final UserState userState = mUserController.getStartedUserStateLocked(userId);
23614            return UserState.stateToString(userState.state);
23615        }
23616    }
23617
23618    @Override
23619    public boolean isUserRunning(int userId, int flags) {
23620        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23621                && checkCallingPermission(INTERACT_ACROSS_USERS)
23622                    != PackageManager.PERMISSION_GRANTED) {
23623            String msg = "Permission Denial: isUserRunning() from pid="
23624                    + Binder.getCallingPid()
23625                    + ", uid=" + Binder.getCallingUid()
23626                    + " requires " + INTERACT_ACROSS_USERS;
23627            Slog.w(TAG, msg);
23628            throw new SecurityException(msg);
23629        }
23630        synchronized (this) {
23631            return mUserController.isUserRunningLocked(userId, flags);
23632        }
23633    }
23634
23635    @Override
23636    public int[] getRunningUserIds() {
23637        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23638                != PackageManager.PERMISSION_GRANTED) {
23639            String msg = "Permission Denial: isUserRunning() from pid="
23640                    + Binder.getCallingPid()
23641                    + ", uid=" + Binder.getCallingUid()
23642                    + " requires " + INTERACT_ACROSS_USERS;
23643            Slog.w(TAG, msg);
23644            throw new SecurityException(msg);
23645        }
23646        synchronized (this) {
23647            return mUserController.getStartedUserArrayLocked();
23648        }
23649    }
23650
23651    @Override
23652    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23653        mUserController.registerUserSwitchObserver(observer, name);
23654    }
23655
23656    @Override
23657    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23658        mUserController.unregisterUserSwitchObserver(observer);
23659    }
23660
23661    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23662        if (info == null) return null;
23663        ApplicationInfo newInfo = new ApplicationInfo(info);
23664        newInfo.initForUser(userId);
23665        return newInfo;
23666    }
23667
23668    public boolean isUserStopped(int userId) {
23669        synchronized (this) {
23670            return mUserController.getStartedUserStateLocked(userId) == null;
23671        }
23672    }
23673
23674    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23675        if (aInfo == null
23676                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23677            return aInfo;
23678        }
23679
23680        ActivityInfo info = new ActivityInfo(aInfo);
23681        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23682        return info;
23683    }
23684
23685    private boolean processSanityChecksLocked(ProcessRecord process) {
23686        if (process == null || process.thread == null) {
23687            return false;
23688        }
23689
23690        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23691        if (!isDebuggable) {
23692            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23693                return false;
23694            }
23695        }
23696
23697        return true;
23698    }
23699
23700    public boolean startBinderTracking() throws RemoteException {
23701        synchronized (this) {
23702            mBinderTransactionTrackingEnabled = true;
23703            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23704            // permission (same as profileControl).
23705            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23706                    != PackageManager.PERMISSION_GRANTED) {
23707                throw new SecurityException("Requires permission "
23708                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23709            }
23710
23711            for (int i = 0; i < mLruProcesses.size(); i++) {
23712                ProcessRecord process = mLruProcesses.get(i);
23713                if (!processSanityChecksLocked(process)) {
23714                    continue;
23715                }
23716                try {
23717                    process.thread.startBinderTracking();
23718                } catch (RemoteException e) {
23719                    Log.v(TAG, "Process disappared");
23720                }
23721            }
23722            return true;
23723        }
23724    }
23725
23726    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23727        try {
23728            synchronized (this) {
23729                mBinderTransactionTrackingEnabled = false;
23730                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23731                // permission (same as profileControl).
23732                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23733                        != PackageManager.PERMISSION_GRANTED) {
23734                    throw new SecurityException("Requires permission "
23735                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23736                }
23737
23738                if (fd == null) {
23739                    throw new IllegalArgumentException("null fd");
23740                }
23741
23742                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23743                pw.println("Binder transaction traces for all processes.\n");
23744                for (ProcessRecord process : mLruProcesses) {
23745                    if (!processSanityChecksLocked(process)) {
23746                        continue;
23747                    }
23748
23749                    pw.println("Traces for process: " + process.processName);
23750                    pw.flush();
23751                    try {
23752                        TransferPipe tp = new TransferPipe();
23753                        try {
23754                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23755                            tp.go(fd.getFileDescriptor());
23756                        } finally {
23757                            tp.kill();
23758                        }
23759                    } catch (IOException e) {
23760                        pw.println("Failure while dumping IPC traces from " + process +
23761                                ".  Exception: " + e);
23762                        pw.flush();
23763                    } catch (RemoteException e) {
23764                        pw.println("Got a RemoteException while dumping IPC traces from " +
23765                                process + ".  Exception: " + e);
23766                        pw.flush();
23767                    }
23768                }
23769                fd = null;
23770                return true;
23771            }
23772        } finally {
23773            if (fd != null) {
23774                try {
23775                    fd.close();
23776                } catch (IOException e) {
23777                }
23778            }
23779        }
23780    }
23781
23782    @VisibleForTesting
23783    final class LocalService extends ActivityManagerInternal {
23784        @Override
23785        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23786                int targetUserId) {
23787            synchronized (ActivityManagerService.this) {
23788                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23789                        targetPkg, intent, null, targetUserId);
23790            }
23791        }
23792
23793        @Override
23794        public String checkContentProviderAccess(String authority, int userId) {
23795            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23796        }
23797
23798        @Override
23799        public void onWakefulnessChanged(int wakefulness) {
23800            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23801        }
23802
23803        @Override
23804        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23805                String processName, String abiOverride, int uid, Runnable crashHandler) {
23806            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23807                    processName, abiOverride, uid, crashHandler);
23808        }
23809
23810        @Override
23811        public SleepToken acquireSleepToken(String tag) {
23812            Preconditions.checkNotNull(tag);
23813
23814            synchronized (ActivityManagerService.this) {
23815                SleepTokenImpl token = new SleepTokenImpl(tag);
23816                mSleepTokens.add(token);
23817                updateSleepIfNeededLocked();
23818                return token;
23819            }
23820        }
23821
23822        @Override
23823        public ComponentName getHomeActivityForUser(int userId) {
23824            synchronized (ActivityManagerService.this) {
23825                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23826                return homeActivity == null ? null : homeActivity.realActivity;
23827            }
23828        }
23829
23830        @Override
23831        public void onUserRemoved(int userId) {
23832            synchronized (ActivityManagerService.this) {
23833                ActivityManagerService.this.onUserStoppedLocked(userId);
23834            }
23835        }
23836
23837        @Override
23838        public void onLocalVoiceInteractionStarted(IBinder activity,
23839                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23840            synchronized (ActivityManagerService.this) {
23841                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23842                        voiceSession, voiceInteractor);
23843            }
23844        }
23845
23846        @Override
23847        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23848            synchronized (ActivityManagerService.this) {
23849                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23850                        reasons, timestamp);
23851            }
23852        }
23853
23854        @Override
23855        public void notifyAppTransitionFinished() {
23856            synchronized (ActivityManagerService.this) {
23857                mStackSupervisor.notifyAppTransitionDone();
23858            }
23859        }
23860
23861        @Override
23862        public void notifyAppTransitionCancelled() {
23863            synchronized (ActivityManagerService.this) {
23864                mStackSupervisor.notifyAppTransitionDone();
23865            }
23866        }
23867
23868        @Override
23869        public List<IBinder> getTopVisibleActivities() {
23870            synchronized (ActivityManagerService.this) {
23871                return mStackSupervisor.getTopVisibleActivities();
23872            }
23873        }
23874
23875        @Override
23876        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23877            synchronized (ActivityManagerService.this) {
23878                mStackSupervisor.setDockedStackMinimized(minimized);
23879            }
23880        }
23881
23882        @Override
23883        public void killForegroundAppsForUser(int userHandle) {
23884            synchronized (ActivityManagerService.this) {
23885                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23886                final int NP = mProcessNames.getMap().size();
23887                for (int ip = 0; ip < NP; ip++) {
23888                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23889                    final int NA = apps.size();
23890                    for (int ia = 0; ia < NA; ia++) {
23891                        final ProcessRecord app = apps.valueAt(ia);
23892                        if (app.persistent) {
23893                            // We don't kill persistent processes.
23894                            continue;
23895                        }
23896                        if (app.removed) {
23897                            procs.add(app);
23898                        } else if (app.userId == userHandle && app.foregroundActivities) {
23899                            app.removed = true;
23900                            procs.add(app);
23901                        }
23902                    }
23903                }
23904
23905                final int N = procs.size();
23906                for (int i = 0; i < N; i++) {
23907                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
23908                }
23909            }
23910        }
23911
23912        @Override
23913        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23914                long duration) {
23915            if (!(target instanceof PendingIntentRecord)) {
23916                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23917                return;
23918            }
23919            ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23920        }
23921
23922        @Override
23923        public void setDeviceIdleWhitelist(int[] appids) {
23924            synchronized (ActivityManagerService.this) {
23925                mDeviceIdleWhitelist = appids;
23926            }
23927        }
23928
23929        @Override
23930        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23931            synchronized (ActivityManagerService.this) {
23932                mDeviceIdleTempWhitelist = appids;
23933                setAppIdTempWhitelistStateLocked(changingAppId, adding);
23934            }
23935        }
23936
23937        @Override
23938        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23939                int userId) {
23940            Preconditions.checkNotNull(values, "Configuration must not be null");
23941            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23942            synchronized (ActivityManagerService.this) {
23943                updateConfigurationLocked(values, null, false, true, userId,
23944                        false /* deferResume */);
23945            }
23946        }
23947
23948        @Override
23949        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23950                Bundle bOptions) {
23951            Preconditions.checkNotNull(intents, "intents");
23952            final String[] resolvedTypes = new String[intents.length];
23953            for (int i = 0; i < intents.length; i++) {
23954                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23955            }
23956
23957            // UID of the package on user userId.
23958            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23959            // packageUid may not be initialized.
23960            int packageUid = 0;
23961            try {
23962                packageUid = AppGlobals.getPackageManager().getPackageUid(
23963                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23964            } catch (RemoteException e) {
23965                // Shouldn't happen.
23966            }
23967
23968            synchronized (ActivityManagerService.this) {
23969                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23970                        /*resultTo*/ null, bOptions, userId);
23971            }
23972        }
23973
23974        @Override
23975        public int getUidProcessState(int uid) {
23976            return getUidState(uid);
23977        }
23978
23979        @Override
23980        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23981            synchronized (ActivityManagerService.this) {
23982
23983                // We might change the visibilities here, so prepare an empty app transition which
23984                // might be overridden later if we actually change visibilities.
23985                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23986                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23987                mWindowManager.executeAppTransition();
23988            }
23989            if (callback != null) {
23990                callback.run();
23991            }
23992        }
23993
23994        @Override
23995        public boolean isSystemReady() {
23996            // no need to synchronize(this) just to read & return the value
23997            return mSystemReady;
23998        }
23999
24000        @Override
24001        public void notifyKeyguardTrustedChanged() {
24002            synchronized (ActivityManagerService.this) {
24003                if (mKeyguardController.isKeyguardShowing()) {
24004                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24005                }
24006            }
24007        }
24008
24009        /**
24010         * Sets if the given pid has an overlay UI or not.
24011         *
24012         * @param pid The pid we are setting overlay UI for.
24013         * @param hasOverlayUi True if the process has overlay UI.
24014         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24015         */
24016        @Override
24017        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24018            synchronized (ActivityManagerService.this) {
24019                final ProcessRecord pr;
24020                synchronized (mPidsSelfLocked) {
24021                    pr = mPidsSelfLocked.get(pid);
24022                    if (pr == null) {
24023                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24024                        return;
24025                    }
24026                }
24027                if (pr.hasOverlayUi == hasOverlayUi) {
24028                    return;
24029                }
24030                pr.hasOverlayUi = hasOverlayUi;
24031                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24032                updateOomAdjLocked(pr, true);
24033            }
24034        }
24035
24036        /**
24037         * Called after the network policy rules are updated by
24038         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24039         * and {@param procStateSeq}.
24040         */
24041        @Override
24042        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24043            if (DEBUG_NETWORK) {
24044                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24045                        + uid + " seq: " + procStateSeq);
24046            }
24047            UidRecord record;
24048            synchronized (ActivityManagerService.this) {
24049                record = mActiveUids.get(uid);
24050                if (record == null) {
24051                    if (DEBUG_NETWORK) {
24052                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24053                                + " procStateSeq: " + procStateSeq);
24054                    }
24055                    return;
24056                }
24057            }
24058            synchronized (record.networkStateLock) {
24059                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24060                    if (DEBUG_NETWORK) {
24061                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24062                                + " been handled for uid: " + uid);
24063                    }
24064                    return;
24065                }
24066                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24067                if (record.curProcStateSeq > procStateSeq) {
24068                    if (DEBUG_NETWORK) {
24069                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24070                                + ", curProcstateSeq: " + record.curProcStateSeq
24071                                + ", procStateSeq: " + procStateSeq);
24072                    }
24073                    return;
24074                }
24075                if (record.waitingForNetwork) {
24076                    if (DEBUG_NETWORK) {
24077                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24078                                + ", procStateSeq: " + procStateSeq);
24079                    }
24080                    record.networkStateLock.notifyAll();
24081                }
24082            }
24083        }
24084
24085        /**
24086         * Called after virtual display Id is updated by
24087         * {@link com.android.server.vr.Vr2dDisplay} with a specific
24088         * {@param vrVr2dDisplayId}.
24089         */
24090        @Override
24091        public void setVr2dDisplayId(int vr2dDisplayId) {
24092            if (DEBUG_STACK) {
24093                Slog.d(TAG, "setVr2dDisplayId called for: " +
24094                        vr2dDisplayId);
24095            }
24096            synchronized (ActivityManagerService.this) {
24097                mVr2dDisplayId = vr2dDisplayId;
24098            }
24099        }
24100
24101        @Override
24102        public void saveANRState(String reason) {
24103            synchronized (ActivityManagerService.this) {
24104                final StringWriter sw = new StringWriter();
24105                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24106                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24107                if (reason != null) {
24108                    pw.println("  Reason: " + reason);
24109                }
24110                pw.println();
24111                mActivityStarter.dump(pw, "  ");
24112                pw.println();
24113                pw.println("-------------------------------------------------------------------------------");
24114                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24115                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24116                        "" /* header */);
24117                pw.println();
24118                pw.close();
24119
24120                mLastANRState = sw.toString();
24121            }
24122        }
24123
24124        @Override
24125        public void clearSavedANRState() {
24126            synchronized (ActivityManagerService.this) {
24127                mLastANRState = null;
24128            }
24129        }
24130    }
24131
24132    /**
24133     * Called by app main thread to wait for the network policy rules to get updated.
24134     *
24135     * @param procStateSeq The sequence number indicating the process state change that the main
24136     *                     thread is interested in.
24137     */
24138    @Override
24139    public void waitForNetworkStateUpdate(long procStateSeq) {
24140        final int callingUid = Binder.getCallingUid();
24141        if (DEBUG_NETWORK) {
24142            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24143        }
24144        UidRecord record;
24145        synchronized (this) {
24146            record = mActiveUids.get(callingUid);
24147            if (record == null) {
24148                return;
24149            }
24150        }
24151        synchronized (record.networkStateLock) {
24152            if (record.lastDispatchedProcStateSeq < procStateSeq) {
24153                if (DEBUG_NETWORK) {
24154                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24155                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24156                            + " lastProcStateSeqDispatchedToObservers: "
24157                            + record.lastDispatchedProcStateSeq);
24158                }
24159                return;
24160            }
24161            if (record.curProcStateSeq > procStateSeq) {
24162                if (DEBUG_NETWORK) {
24163                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24164                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24165                            + ", procStateSeq: " + procStateSeq);
24166                }
24167                return;
24168            }
24169            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24170                if (DEBUG_NETWORK) {
24171                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24172                            + procStateSeq + ", so no need to wait. Uid: "
24173                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24174                            + record.lastNetworkUpdatedProcStateSeq);
24175                }
24176                return;
24177            }
24178            try {
24179                if (DEBUG_NETWORK) {
24180                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24181                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24182                }
24183                final long startTime = SystemClock.uptimeMillis();
24184                record.waitingForNetwork = true;
24185                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24186                record.waitingForNetwork = false;
24187                final long totalTime = SystemClock.uptimeMillis() - startTime;
24188                if (totalTime >= mWaitForNetworkTimeoutMs) {
24189                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24190                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24191                            + procStateSeq + " UidRec: " + record
24192                            + " validateUidRec: " + mValidateUids.get(callingUid));
24193                }
24194            } catch (InterruptedException e) {
24195                Thread.currentThread().interrupt();
24196            }
24197        }
24198    }
24199
24200    public void waitForBroadcastIdle(PrintWriter pw) {
24201        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24202        while (true) {
24203            boolean idle = true;
24204            synchronized (this) {
24205                for (BroadcastQueue queue : mBroadcastQueues) {
24206                    if (!queue.isIdle()) {
24207                        final String msg = "Waiting for queue " + queue + " to become idle...";
24208                        pw.println(msg);
24209                        pw.flush();
24210                        Slog.v(TAG, msg);
24211                        idle = false;
24212                    }
24213                }
24214            }
24215
24216            if (idle) {
24217                final String msg = "All broadcast queues are idle!";
24218                pw.println(msg);
24219                pw.flush();
24220                Slog.v(TAG, msg);
24221                return;
24222            } else {
24223                SystemClock.sleep(1000);
24224            }
24225        }
24226    }
24227
24228    /**
24229     * Return the user id of the last resumed activity.
24230     */
24231    @Override
24232    public @UserIdInt int getLastResumedActivityUserId() {
24233        enforceCallingPermission(
24234                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24235        synchronized (this) {
24236            if (mLastResumedActivity == null) {
24237                return mUserController.getCurrentUserIdLocked();
24238            }
24239            return mLastResumedActivity.userId;
24240        }
24241    }
24242
24243    private final class SleepTokenImpl extends SleepToken {
24244        private final String mTag;
24245        private final long mAcquireTime;
24246
24247        public SleepTokenImpl(String tag) {
24248            mTag = tag;
24249            mAcquireTime = SystemClock.uptimeMillis();
24250        }
24251
24252        @Override
24253        public void release() {
24254            synchronized (ActivityManagerService.this) {
24255                if (mSleepTokens.remove(this)) {
24256                    updateSleepIfNeededLocked();
24257                }
24258            }
24259        }
24260
24261        @Override
24262        public String toString() {
24263            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
24264        }
24265    }
24266
24267    /**
24268     * An implementation of IAppTask, that allows an app to manage its own tasks via
24269     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24270     * only the process that calls getAppTasks() can call the AppTask methods.
24271     */
24272    class AppTaskImpl extends IAppTask.Stub {
24273        private int mTaskId;
24274        private int mCallingUid;
24275
24276        public AppTaskImpl(int taskId, int callingUid) {
24277            mTaskId = taskId;
24278            mCallingUid = callingUid;
24279        }
24280
24281        private void checkCaller() {
24282            if (mCallingUid != Binder.getCallingUid()) {
24283                throw new SecurityException("Caller " + mCallingUid
24284                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24285            }
24286        }
24287
24288        @Override
24289        public void finishAndRemoveTask() {
24290            checkCaller();
24291
24292            synchronized (ActivityManagerService.this) {
24293                long origId = Binder.clearCallingIdentity();
24294                try {
24295                    // We remove the task from recents to preserve backwards
24296                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24297                            REMOVE_FROM_RECENTS)) {
24298                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24299                    }
24300                } finally {
24301                    Binder.restoreCallingIdentity(origId);
24302                }
24303            }
24304        }
24305
24306        @Override
24307        public ActivityManager.RecentTaskInfo getTaskInfo() {
24308            checkCaller();
24309
24310            synchronized (ActivityManagerService.this) {
24311                long origId = Binder.clearCallingIdentity();
24312                try {
24313                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24314                    if (tr == null) {
24315                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24316                    }
24317                    return createRecentTaskInfoFromTaskRecord(tr);
24318                } finally {
24319                    Binder.restoreCallingIdentity(origId);
24320                }
24321            }
24322        }
24323
24324        @Override
24325        public void moveToFront() {
24326            checkCaller();
24327            // Will bring task to front if it already has a root activity.
24328            final long origId = Binder.clearCallingIdentity();
24329            try {
24330                synchronized (this) {
24331                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24332                }
24333            } finally {
24334                Binder.restoreCallingIdentity(origId);
24335            }
24336        }
24337
24338        @Override
24339        public int startActivity(IBinder whoThread, String callingPackage,
24340                Intent intent, String resolvedType, Bundle bOptions) {
24341            checkCaller();
24342
24343            int callingUser = UserHandle.getCallingUserId();
24344            TaskRecord tr;
24345            IApplicationThread appThread;
24346            synchronized (ActivityManagerService.this) {
24347                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24348                if (tr == null) {
24349                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24350                }
24351                appThread = IApplicationThread.Stub.asInterface(whoThread);
24352                if (appThread == null) {
24353                    throw new IllegalArgumentException("Bad app thread " + appThread);
24354                }
24355            }
24356            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24357                    resolvedType, null, null, null, null, 0, 0, null, null,
24358                    null, bOptions, false, callingUser, null, tr, "AppTaskImpl");
24359        }
24360
24361        @Override
24362        public void setExcludeFromRecents(boolean exclude) {
24363            checkCaller();
24364
24365            synchronized (ActivityManagerService.this) {
24366                long origId = Binder.clearCallingIdentity();
24367                try {
24368                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24369                    if (tr == null) {
24370                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24371                    }
24372                    Intent intent = tr.getBaseIntent();
24373                    if (exclude) {
24374                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24375                    } else {
24376                        intent.setFlags(intent.getFlags()
24377                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24378                    }
24379                } finally {
24380                    Binder.restoreCallingIdentity(origId);
24381                }
24382            }
24383        }
24384    }
24385
24386    /**
24387     * Kill processes for the user with id userId and that depend on the package named packageName
24388     */
24389    @Override
24390    public void killPackageDependents(String packageName, int userId) {
24391        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24392        if (packageName == null) {
24393            throw new NullPointerException(
24394                    "Cannot kill the dependents of a package without its name.");
24395        }
24396
24397        long callingId = Binder.clearCallingIdentity();
24398        IPackageManager pm = AppGlobals.getPackageManager();
24399        int pkgUid = -1;
24400        try {
24401            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24402        } catch (RemoteException e) {
24403        }
24404        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24405            throw new IllegalArgumentException(
24406                    "Cannot kill dependents of non-existing package " + packageName);
24407        }
24408        try {
24409            synchronized(this) {
24410                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24411                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24412                        "dep: " + packageName);
24413            }
24414        } finally {
24415            Binder.restoreCallingIdentity(callingId);
24416        }
24417    }
24418
24419    @Override
24420    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24421            throws RemoteException {
24422        final long callingId = Binder.clearCallingIdentity();
24423        try {
24424            mKeyguardController.dismissKeyguard(token, callback);
24425        } finally {
24426            Binder.restoreCallingIdentity(callingId);
24427        }
24428    }
24429
24430    @Override
24431    public int restartUserInBackground(final int userId) {
24432        return mUserController.restartUser(userId, /* foreground */ false);
24433    }
24434
24435    @Override
24436    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24437        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24438                "scheduleApplicationInfoChanged()");
24439
24440        synchronized (this) {
24441            final long origId = Binder.clearCallingIdentity();
24442            try {
24443                updateApplicationInfoLocked(packageNames, userId);
24444            } finally {
24445                Binder.restoreCallingIdentity(origId);
24446            }
24447        }
24448    }
24449
24450    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24451        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24452        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24453            final ProcessRecord app = mLruProcesses.get(i);
24454            if (app.thread == null) {
24455                continue;
24456            }
24457
24458            if (userId != UserHandle.USER_ALL && app.userId != userId) {
24459                continue;
24460            }
24461
24462            final int packageCount = app.pkgList.size();
24463            for (int j = 0; j < packageCount; j++) {
24464                final String packageName = app.pkgList.keyAt(j);
24465                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24466                    try {
24467                        final ApplicationInfo ai = AppGlobals.getPackageManager()
24468                                .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
24469                        if (ai != null) {
24470                            app.thread.scheduleApplicationInfoChanged(ai);
24471                        }
24472                    } catch (RemoteException e) {
24473                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24474                                    packageName, app));
24475                    }
24476                }
24477            }
24478        }
24479    }
24480
24481    /**
24482     * Attach an agent to the specified process (proces name or PID)
24483     */
24484    public void attachAgent(String process, String path) {
24485        try {
24486            synchronized (this) {
24487                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24488                if (proc == null || proc.thread == null) {
24489                    throw new IllegalArgumentException("Unknown process: " + process);
24490                }
24491
24492                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24493                if (!isDebuggable) {
24494                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24495                        throw new SecurityException("Process not debuggable: " + proc);
24496                    }
24497                }
24498
24499                proc.thread.attachAgent(path);
24500            }
24501        } catch (RemoteException e) {
24502            throw new IllegalStateException("Process disappeared");
24503        }
24504    }
24505
24506    @VisibleForTesting
24507    public static class Injector {
24508        private NetworkManagementInternal mNmi;
24509
24510        public Context getContext() {
24511            return null;
24512        }
24513
24514        public AppOpsService getAppOpsService(File file, Handler handler) {
24515            return new AppOpsService(file, handler);
24516        }
24517
24518        public Handler getUiHandler(ActivityManagerService service) {
24519            return service.new UiHandler();
24520        }
24521
24522        public boolean isNetworkRestrictedForUid(int uid) {
24523            if (ensureHasNetworkManagementInternal()) {
24524                return mNmi.isNetworkRestrictedForUid(uid);
24525            }
24526            return false;
24527        }
24528
24529        private boolean ensureHasNetworkManagementInternal() {
24530            if (mNmi == null) {
24531                mNmi = LocalServices.getService(NetworkManagementInternal.class);
24532            }
24533            return mNmi != null;
24534        }
24535    }
24536}
24537