ActivityManagerService.java revision 0fe7ce968bc7f0eff64f08e2d51c8b1e6b4a6fc8
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.INTERACT_ACROSS_USERS;
21import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
22import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
23import static android.Manifest.permission.READ_FRAME_BUFFER;
24import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
25import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
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_FREEFORM_WINDOW_MANAGEMENT;
34import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
35import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
36import static android.content.pm.PackageManager.GET_PROVIDERS;
37import static android.content.pm.PackageManager.MATCH_ANY_USER;
38import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
39import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
40import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
41import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
42import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
43import static android.content.pm.PackageManager.PERMISSION_GRANTED;
44import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
45import static android.os.Build.VERSION_CODES.N;
46import static android.os.Process.PROC_CHAR;
47import static android.os.Process.PROC_OUT_LONG;
48import static android.os.Process.PROC_PARENS;
49import static android.os.Process.PROC_SPACE_TERM;
50import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
51import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
52import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
53import static android.provider.Settings.Global.DEBUG_APP;
54import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
55import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
56import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
57import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
58import static android.provider.Settings.System.FONT_SCALE;
59import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
60import static android.view.Display.DEFAULT_DISPLAY;
61import static com.android.internal.util.XmlUtils.readBooleanAttribute;
62import static com.android.internal.util.XmlUtils.readIntAttribute;
63import static com.android.internal.util.XmlUtils.readLongAttribute;
64import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
65import static com.android.internal.util.XmlUtils.writeIntAttribute;
66import static com.android.internal.util.XmlUtils.writeLongAttribute;
67import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
68import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
69import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
70import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
71import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
72import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
73import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
74import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
75import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
76import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
77import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
78import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
79import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
80import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
81import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
82import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
83import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
84import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
85import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
86import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
87import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
88import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
89import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
90import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
91import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
92import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
93import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
94import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
95import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
96import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
97import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
98import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
99import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
100import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
101import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
102import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
103import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
104import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
105import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
106import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
107import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
108import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
109import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
110import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
111import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
112import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
113import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
114import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
115import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
116import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
117import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
118import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
119import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
120import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
121import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
122import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
123import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
124import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
125import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
126import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
127import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
128import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
129import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
130import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
131import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
132import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
133import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
134import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
135import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
136import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
137import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
138import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
139import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
140import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
141import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
142import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
143import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
144import static com.android.server.wm.AppTransition.TRANSIT_NONE;
145import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
146import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
147import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
148import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
149import static org.xmlpull.v1.XmlPullParser.START_TAG;
150
151import android.Manifest;
152import android.Manifest.permission;
153import android.annotation.NonNull;
154import android.annotation.Nullable;
155import android.annotation.UserIdInt;
156import android.app.Activity;
157import android.app.ActivityManager;
158import android.app.ActivityManager.RunningTaskInfo;
159import android.app.ActivityManager.StackId;
160import android.app.ActivityManager.StackInfo;
161import android.app.ActivityManager.TaskSnapshot;
162import android.app.ActivityManager.TaskThumbnailInfo;
163import android.app.ActivityManagerInternal;
164import android.app.ActivityManagerInternal.SleepToken;
165import android.app.ActivityOptions;
166import android.app.ActivityThread;
167import android.app.AlertDialog;
168import android.app.AppGlobals;
169import android.app.AppOpsManager;
170import android.app.ApplicationErrorReport;
171import android.app.ApplicationThreadConstants;
172import android.app.BroadcastOptions;
173import android.app.ContentProviderHolder;
174import android.app.Dialog;
175import android.app.IActivityContainer;
176import android.app.IActivityContainerCallback;
177import android.app.IActivityController;
178import android.app.IActivityManager;
179import android.app.IAppTask;
180import android.app.IApplicationThread;
181import android.app.IInstrumentationWatcher;
182import android.app.INotificationManager;
183import android.app.IProcessObserver;
184import android.app.IServiceConnection;
185import android.app.IStopUserCallback;
186import android.app.ITaskStackListener;
187import android.app.IUiAutomationConnection;
188import android.app.IUidObserver;
189import android.app.IUserSwitchObserver;
190import android.app.Instrumentation;
191import android.app.Notification;
192import android.app.NotificationManager;
193import android.app.PendingIntent;
194import android.app.PictureInPictureArgs;
195import android.app.ProfilerInfo;
196import android.app.RemoteAction;
197import android.app.WaitResult;
198import android.app.admin.DevicePolicyManager;
199import android.app.assist.AssistContent;
200import android.app.assist.AssistStructure;
201import android.app.backup.IBackupManager;
202import android.app.usage.UsageEvents;
203import android.app.usage.UsageStatsManagerInternal;
204import android.appwidget.AppWidgetManager;
205import android.content.ActivityNotFoundException;
206import android.content.BroadcastReceiver;
207import android.content.ClipData;
208import android.content.ComponentCallbacks2;
209import android.content.ComponentName;
210import android.content.ContentProvider;
211import android.content.ContentResolver;
212import android.content.Context;
213import android.content.DialogInterface;
214import android.content.IContentProvider;
215import android.content.IIntentReceiver;
216import android.content.IIntentSender;
217import android.content.Intent;
218import android.content.IntentFilter;
219import android.content.IntentSender;
220import android.content.pm.ActivityInfo;
221import android.content.pm.ApplicationInfo;
222import android.content.pm.ConfigurationInfo;
223import android.content.pm.IPackageDataObserver;
224import android.content.pm.IPackageManager;
225import android.content.pm.InstrumentationInfo;
226import android.content.pm.PackageInfo;
227import android.content.pm.PackageManager;
228import android.content.pm.PackageManager.NameNotFoundException;
229import android.content.pm.PackageManagerInternal;
230import android.content.pm.ParceledListSlice;
231import android.content.pm.PathPermission;
232import android.content.pm.PermissionInfo;
233import android.content.pm.ProviderInfo;
234import android.content.pm.ResolveInfo;
235import android.content.pm.SELinuxUtil;
236import android.content.pm.ServiceInfo;
237import android.content.pm.UserInfo;
238import android.content.res.CompatibilityInfo;
239import android.content.res.Configuration;
240import android.content.res.Resources;
241import android.database.ContentObserver;
242import android.graphics.Bitmap;
243import android.graphics.Point;
244import android.graphics.Rect;
245import android.location.LocationManager;
246import android.media.audiofx.AudioEffect;
247import android.metrics.LogMaker;
248import android.net.Proxy;
249import android.net.ProxyInfo;
250import android.net.Uri;
251import android.os.BatteryStats;
252import android.os.Binder;
253import android.os.Build;
254import android.os.Bundle;
255import android.os.Debug;
256import android.os.DropBoxManager;
257import android.os.Environment;
258import android.os.FactoryTest;
259import android.os.FileObserver;
260import android.os.FileUtils;
261import android.os.Handler;
262import android.os.IBinder;
263import android.os.IDeviceIdentifiersPolicyService;
264import android.os.IPermissionController;
265import android.os.IProcessInfoService;
266import android.os.IProgressListener;
267import android.os.LocaleList;
268import android.os.Looper;
269import android.os.Message;
270import android.os.Parcel;
271import android.os.ParcelFileDescriptor;
272import android.os.PersistableBundle;
273import android.os.PowerManager;
274import android.os.PowerManagerInternal;
275import android.os.Process;
276import android.os.RemoteCallbackList;
277import android.os.RemoteException;
278import android.os.ResultReceiver;
279import android.os.ServiceManager;
280import android.os.ShellCallback;
281import android.os.StrictMode;
282import android.os.SystemClock;
283import android.os.SystemProperties;
284import android.os.Trace;
285import android.os.TransactionTooLargeException;
286import android.os.UpdateLock;
287import android.os.UserHandle;
288import android.os.UserManager;
289import android.os.WorkSource;
290import android.os.storage.IStorageManager;
291import android.os.storage.StorageManager;
292import android.os.storage.StorageManagerInternal;
293import android.provider.Downloads;
294import android.provider.Settings;
295import android.service.voice.IVoiceInteractionSession;
296import android.service.voice.VoiceInteractionManagerInternal;
297import android.service.voice.VoiceInteractionSession;
298import android.telecom.TelecomManager;
299import android.text.TextUtils;
300import android.text.format.DateUtils;
301import android.text.format.Time;
302import android.text.style.SuggestionSpan;
303import android.util.ArrayMap;
304import android.util.ArraySet;
305import android.util.AtomicFile;
306import android.util.BootTimingsTraceLog;
307import android.util.DebugUtils;
308import android.util.DisplayMetrics;
309import android.util.EventLog;
310import android.util.Log;
311import android.util.Pair;
312import android.util.PrintWriterPrinter;
313import android.util.Slog;
314import android.util.SparseArray;
315import android.util.SparseIntArray;
316import android.util.TimeUtils;
317import android.util.Xml;
318import android.view.Gravity;
319import android.view.LayoutInflater;
320import android.view.View;
321import android.view.WindowManager;
322
323import com.android.internal.notification.SystemNotificationChannels;
324import com.google.android.collect.Lists;
325import com.google.android.collect.Maps;
326
327import com.android.internal.R;
328import com.android.internal.annotations.GuardedBy;
329import com.android.internal.annotations.VisibleForTesting;
330import com.android.internal.app.AssistUtils;
331import com.android.internal.app.DumpHeapActivity;
332import com.android.internal.app.IAppOpsCallback;
333import com.android.internal.app.IAppOpsService;
334import com.android.internal.app.IVoiceInteractor;
335import com.android.internal.app.ProcessMap;
336import com.android.internal.app.SystemUserHomeActivity;
337import com.android.internal.app.procstats.ProcessStats;
338import com.android.internal.logging.MetricsLogger;
339import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
340import com.android.internal.os.BackgroundThread;
341import com.android.internal.os.BatteryStatsImpl;
342import com.android.internal.os.IResultReceiver;
343import com.android.internal.os.ProcessCpuTracker;
344import com.android.internal.os.TransferPipe;
345import com.android.internal.os.Zygote;
346import com.android.internal.policy.IKeyguardDismissCallback;
347import com.android.internal.telephony.TelephonyIntents;
348import com.android.internal.util.ArrayUtils;
349import com.android.internal.util.FastPrintWriter;
350import com.android.internal.util.FastXmlSerializer;
351import com.android.internal.util.MemInfoReader;
352import com.android.internal.util.Preconditions;
353import com.android.server.AppOpsService;
354import com.android.server.AttributeCache;
355import com.android.server.DeviceIdleController;
356import com.android.server.IntentResolver;
357import com.android.server.LocalServices;
358import com.android.server.LockGuard;
359import com.android.server.RescueParty;
360import com.android.server.ServiceThread;
361import com.android.server.SystemConfig;
362import com.android.server.SystemService;
363import com.android.server.SystemServiceManager;
364import com.android.server.Watchdog;
365import com.android.server.am.ActivityStack.ActivityState;
366import com.android.server.firewall.IntentFirewall;
367import com.android.server.pm.Installer;
368import com.android.server.pm.Installer.InstallerException;
369import com.android.server.statusbar.StatusBarManagerInternal;
370import com.android.server.vr.PersistentVrStateListener;
371import com.android.server.vr.VrManagerInternal;
372import com.android.server.wm.WindowManagerService;
373
374import org.xmlpull.v1.XmlPullParser;
375import org.xmlpull.v1.XmlPullParserException;
376import org.xmlpull.v1.XmlSerializer;
377
378import java.io.File;
379import java.io.FileDescriptor;
380import java.io.FileInputStream;
381import java.io.FileNotFoundException;
382import java.io.FileOutputStream;
383import java.io.IOException;
384import java.io.InputStreamReader;
385import java.io.PrintWriter;
386import java.io.StringWriter;
387import java.lang.ref.WeakReference;
388import java.nio.charset.StandardCharsets;
389import java.util.ArrayList;
390import java.util.Arrays;
391import java.util.Collections;
392import java.util.Comparator;
393import java.util.HashMap;
394import java.util.HashSet;
395import java.util.Iterator;
396import java.util.List;
397import java.util.Locale;
398import java.util.Map;
399import java.util.Objects;
400import java.util.Set;
401import java.util.concurrent.CountDownLatch;
402import java.util.concurrent.atomic.AtomicBoolean;
403import java.util.concurrent.atomic.AtomicLong;
404
405import dalvik.system.VMRuntime;
406
407import libcore.io.IoUtils;
408import libcore.util.EmptyArray;
409
410public class ActivityManagerService extends IActivityManager.Stub
411        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
412
413    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
414    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
415    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
416    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
417    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
418    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
419    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
420    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
421    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
422    private static final String TAG_LRU = TAG + POSTFIX_LRU;
423    private static final String TAG_MU = TAG + POSTFIX_MU;
424    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
425    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
426    private static final String TAG_POWER = TAG + POSTFIX_POWER;
427    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
428    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
429    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
430    private static final String TAG_PSS = TAG + POSTFIX_PSS;
431    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
432    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
433    private static final String TAG_STACK = TAG + POSTFIX_STACK;
434    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
435    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
436    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
437    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
438    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
439
440    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
441    // here so that while the job scheduler can depend on AMS, the other way around
442    // need not be the case.
443    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
444
445    /** Control over CPU and battery monitoring */
446    // write battery stats every 30 minutes.
447    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
448    static final boolean MONITOR_CPU_USAGE = true;
449    // don't sample cpu less than every 5 seconds.
450    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
451    // wait possibly forever for next cpu sample.
452    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
453    static final boolean MONITOR_THREAD_CPU_USAGE = false;
454
455    // The flags that are set for all calls we make to the package manager.
456    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
457
458    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
459
460    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
461
462    // Amount of time after a call to stopAppSwitches() during which we will
463    // prevent further untrusted switches from happening.
464    static final long APP_SWITCH_DELAY_TIME = 5*1000;
465
466    // How long we wait for a launched process to attach to the activity manager
467    // before we decide it's never going to come up for real.
468    static final int PROC_START_TIMEOUT = 10*1000;
469    // How long we wait for an attached process to publish its content providers
470    // before we decide it must be hung.
471    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
472
473    // How long we will retain processes hosting content providers in the "last activity"
474    // state before allowing them to drop down to the regular cached LRU list.  This is
475    // to avoid thrashing of provider processes under low memory situations.
476    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
477
478    // How long we wait for a launched process to attach to the activity manager
479    // before we decide it's never going to come up for real, when the process was
480    // started with a wrapper for instrumentation (such as Valgrind) because it
481    // could take much longer than usual.
482    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
483
484    // How long to wait after going idle before forcing apps to GC.
485    static final int GC_TIMEOUT = 5*1000;
486
487    // The minimum amount of time between successive GC requests for a process.
488    static final int GC_MIN_INTERVAL = 60*1000;
489
490    // The minimum amount of time between successive PSS requests for a process.
491    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
492
493    // The minimum amount of time between successive PSS requests for a process
494    // when the request is due to the memory state being lowered.
495    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
496
497    // The rate at which we check for apps using excessive power -- 15 mins.
498    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
499
500    // The minimum sample duration we will allow before deciding we have
501    // enough data on wake locks to start killing things.
502    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
503
504    // The minimum sample duration we will allow before deciding we have
505    // enough data on CPU usage to start killing things.
506    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
507
508    // How long we allow a receiver to run before giving up on it.
509    static final int BROADCAST_FG_TIMEOUT = 10*1000;
510    static final int BROADCAST_BG_TIMEOUT = 60*1000;
511
512    // How long we wait until we timeout on key dispatching.
513    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
514
515    // How long we wait until we timeout on key dispatching during instrumentation.
516    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
517
518    // This is the amount of time an app needs to be running a foreground service before
519    // we will consider it to be doing interaction for usage stats.
520    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
521
522    // Maximum amount of time we will allow to elapse before re-reporting usage stats
523    // interaction with foreground processes.
524    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
525
526    // This is the amount of time we allow an app to settle after it goes into the background,
527    // before we start restricting what it can do.
528    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
529
530    // How long to wait in getAssistContextExtras for the activity and foreground services
531    // to respond with the result.
532    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
533
534    // How long top wait when going through the modern assist (which doesn't need to block
535    // on getting this result before starting to launch its UI).
536    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
537
538    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
539    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
540
541    // Maximum number of persisted Uri grants a package is allowed
542    static final int MAX_PERSISTED_URI_GRANTS = 128;
543
544    static final int MY_PID = Process.myPid();
545
546    static final String[] EMPTY_STRING_ARRAY = new String[0];
547
548    // How many bytes to write into the dropbox log before truncating
549    static final int DROPBOX_MAX_SIZE = 192 * 1024;
550    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
551    // as one line, but close enough for now.
552    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
553
554    // Access modes for handleIncomingUser.
555    static final int ALLOW_NON_FULL = 0;
556    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
557    static final int ALLOW_FULL_ONLY = 2;
558
559    // Necessary ApplicationInfo flags to mark an app as persistent
560    private static final int PERSISTENT_MASK =
561            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
562
563    // Intent sent when remote bugreport collection has been completed
564    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
565            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
566
567    // Used to indicate that an app transition should be animated.
568    static final boolean ANIMATE = true;
569
570    // Determines whether to take full screen screenshots
571    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
572
573    /**
574     * Indicates the maximum time spent waiting for the network rules to get updated.
575     */
576    private static final long WAIT_FOR_NETWORK_TIMEOUT_MS = 2000; // 2 sec
577
578    /**
579     * State indicating that there is no need for any blocking for network.
580     */
581    @VisibleForTesting
582    static final int NETWORK_STATE_NO_CHANGE = 0;
583
584    /**
585     * State indicating that the main thread needs to be informed about the network wait.
586     */
587    @VisibleForTesting
588    static final int NETWORK_STATE_BLOCK = 1;
589
590    /**
591     * State indicating that any threads waiting for network state to get updated can be unblocked.
592     */
593    @VisibleForTesting
594    static final int NETWORK_STATE_UNBLOCK = 2;
595
596    /** All system services */
597    SystemServiceManager mSystemServiceManager;
598    AssistUtils mAssistUtils;
599
600    private Installer mInstaller;
601
602    /** Run all ActivityStacks through this */
603    final ActivityStackSupervisor mStackSupervisor;
604    private final KeyguardController mKeyguardController;
605
606    final ActivityStarter mActivityStarter;
607
608    final TaskChangeNotificationController mTaskChangeNotificationController;
609
610    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
611
612    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
613
614    public final IntentFirewall mIntentFirewall;
615
616    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
617    // default action automatically.  Important for devices without direct input
618    // devices.
619    private boolean mShowDialogs = true;
620    // VR state flags.
621    static final int NON_VR_MODE = 0;
622    static final int VR_MODE = 1;
623    static final int PERSISTENT_VR_MODE = 2;
624    private int mVrState = NON_VR_MODE;
625    private int mTopAppVrThreadTid = 0;
626    private int mPersistentVrThreadTid = 0;
627    final PersistentVrStateListener mPersistentVrModeListener =
628            new PersistentVrStateListener() {
629        @Override
630        public void onPersistentVrStateChanged(boolean enabled) {
631            synchronized(ActivityManagerService.this) {
632                // There are 4 possible cases here:
633                //
634                // Cases for enabled == true
635                // Invariant: mVrState != PERSISTENT_VR_MODE;
636                //    This is guaranteed as only this function sets mVrState to PERSISTENT_VR_MODE
637                // Invariant: mPersistentVrThreadTid == 0
638                //   This is guaranteed by VrManagerService, which only emits callbacks when the
639                //   mode changes, and in setPersistentVrThread, which only sets
640                //   mPersistentVrThreadTid when mVrState = PERSISTENT_VR_MODE
641                // Case 1: mTopAppVrThreadTid > 0 (someone called setVrThread successfully and is
642                // the top-app)
643                //     We reset the app which currently has SCHED_FIFO (mPersistentVrThreadTid) to
644                //     SCHED_OTHER
645                // Case 2: mTopAppVrThreadTid == 0
646                //     Do nothing
647                //
648                // Cases for enabled == false
649                // Invariant: mVrState == PERSISTENT_VR_MODE;
650                //     This is guaranteed by VrManagerService, which only emits callbacks when the
651                //     mode changes, and the only other assignment of mVrState outside of this
652                //     function checks if mVrState != PERSISTENT_VR_MODE
653                // Invariant: mTopAppVrThreadTid == 0
654                //     This is guaranteed in that mTopAppVrThreadTid is only set to a tid when
655                //     mVrState is VR_MODE, and is explicitly set to 0 when setPersistentVrThread is
656                //     called
657                //   mPersistentVrThreadTid > 0 (someone called setPersistentVrThread successfully)
658                //     3. Reset mPersistentVrThreadTidto SCHED_OTHER
659                //   mPersistentVrThreadTid == 0
660                //     4. Do nothing
661                if (enabled) {
662                    mVrState = PERSISTENT_VR_MODE;
663                } else {
664                    // Leaving persistent mode implies leaving VR mode.
665                    mVrState = NON_VR_MODE;
666                }
667
668                if (mVrState == PERSISTENT_VR_MODE) {
669                    if (mTopAppVrThreadTid > 0) {
670                        // Ensure that when entering persistent VR mode the last top-app loses
671                        // SCHED_FIFO.
672                        Process.setThreadScheduler(mTopAppVrThreadTid, Process.SCHED_OTHER, 0);
673                        mTopAppVrThreadTid = 0;
674                    }
675                } else if (mPersistentVrThreadTid > 0) {
676                    // Ensure that when leaving persistent VR mode we reschedule the high priority
677                    // persistent thread.
678                    Process.setThreadScheduler(mPersistentVrThreadTid, Process.SCHED_OTHER, 0);
679                    mPersistentVrThreadTid = 0;
680                }
681            }
682        }
683    };
684
685    // Whether we should use SCHED_FIFO for UI and RenderThreads.
686    private boolean mUseFifoUiScheduling = false;
687
688    BroadcastQueue mFgBroadcastQueue;
689    BroadcastQueue mBgBroadcastQueue;
690    // Convenient for easy iteration over the queues. Foreground is first
691    // so that dispatch of foreground broadcasts gets precedence.
692    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
693
694    BroadcastStats mLastBroadcastStats;
695    BroadcastStats mCurBroadcastStats;
696
697    BroadcastQueue broadcastQueueForIntent(Intent intent) {
698        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
699        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
700                "Broadcast intent " + intent + " on "
701                + (isFg ? "foreground" : "background") + " queue");
702        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
703    }
704
705    /**
706     * The last resumed activity. This is identical to the current resumed activity most
707     * of the time but could be different when we're pausing one activity before we resume
708     * another activity.
709     */
710    private ActivityRecord mLastResumedActivity;
711
712    /**
713     * If non-null, we are tracking the time the user spends in the currently focused app.
714     */
715    private AppTimeTracker mCurAppTimeTracker;
716
717    /**
718     * List of intents that were used to start the most recent tasks.
719     */
720    final RecentTasks mRecentTasks;
721
722    /**
723     * For addAppTask: cached of the last activity component that was added.
724     */
725    ComponentName mLastAddedTaskComponent;
726
727    /**
728     * For addAppTask: cached of the last activity uid that was added.
729     */
730    int mLastAddedTaskUid;
731
732    /**
733     * For addAppTask: cached of the last ActivityInfo that was added.
734     */
735    ActivityInfo mLastAddedTaskActivity;
736
737    /**
738     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
739     */
740    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
741
742    /**
743     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
744     */
745    String mDeviceOwnerName;
746
747    final UserController mUserController;
748
749    final AppErrors mAppErrors;
750
751    public boolean canShowErrorDialogs() {
752        return mShowDialogs && !mSleeping && !mShuttingDown
753                && !mKeyguardController.isKeyguardShowing();
754    }
755
756    private static final class PriorityState {
757        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
758        // the current thread is currently in. When it drops down to zero, we will no longer boost
759        // the thread's priority.
760        private int regionCounter = 0;
761
762        // The thread's previous priority before boosting.
763        private int prevPriority = Integer.MIN_VALUE;
764    }
765
766    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
767        @Override protected PriorityState initialValue() {
768            return new PriorityState();
769        }
770    };
771
772    static void boostPriorityForLockedSection() {
773        int tid = Process.myTid();
774        int prevPriority = Process.getThreadPriority(tid);
775        PriorityState state = sThreadPriorityState.get();
776        if (state.regionCounter == 0 && prevPriority > -2) {
777            state.prevPriority = prevPriority;
778            Process.setThreadPriority(tid, -2);
779        }
780        state.regionCounter++;
781        if (LockGuard.ENABLED) {
782            LockGuard.guard(LockGuard.INDEX_ACTIVITY);
783        }
784    }
785
786    static void resetPriorityAfterLockedSection() {
787        PriorityState state = sThreadPriorityState.get();
788        state.regionCounter--;
789        if (state.regionCounter == 0 && state.prevPriority > -2) {
790            Process.setThreadPriority(Process.myTid(), state.prevPriority);
791        }
792    }
793
794    public class PendingAssistExtras extends Binder implements Runnable {
795        public final ActivityRecord activity;
796        public boolean isHome;
797        public final Bundle extras;
798        public final Intent intent;
799        public final String hint;
800        public final IResultReceiver receiver;
801        public final int userHandle;
802        public boolean haveResult = false;
803        public Bundle result = null;
804        public AssistStructure structure = null;
805        public AssistContent content = null;
806        public Bundle receiverExtras;
807
808        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
809                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
810            activity = _activity;
811            extras = _extras;
812            intent = _intent;
813            hint = _hint;
814            receiver = _receiver;
815            receiverExtras = _receiverExtras;
816            userHandle = _userHandle;
817        }
818
819        @Override
820        public void run() {
821            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
822            synchronized (this) {
823                haveResult = true;
824                notifyAll();
825            }
826            pendingAssistExtrasTimedOut(this);
827        }
828    }
829
830    final ArrayList<PendingAssistExtras> mPendingAssistExtras
831            = new ArrayList<PendingAssistExtras>();
832
833    /**
834     * Process management.
835     */
836    final ProcessList mProcessList = new ProcessList();
837
838    /**
839     * All of the applications we currently have running organized by name.
840     * The keys are strings of the application package name (as
841     * returned by the package manager), and the keys are ApplicationRecord
842     * objects.
843     */
844    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
845
846    /**
847     * Tracking long-term execution of processes to look for abuse and other
848     * bad app behavior.
849     */
850    final ProcessStatsService mProcessStats;
851
852    /**
853     * The currently running isolated processes.
854     */
855    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
856
857    /**
858     * Counter for assigning isolated process uids, to avoid frequently reusing the
859     * same ones.
860     */
861    int mNextIsolatedProcessUid = 0;
862
863    /**
864     * The currently running heavy-weight process, if any.
865     */
866    ProcessRecord mHeavyWeightProcess = null;
867
868    /**
869     * Non-persistent app uid whitelist for background restrictions
870     */
871    int[] mBackgroundUidWhitelist = new int[] {
872            Process.BLUETOOTH_UID
873    };
874
875    /**
876     * Broadcast actions that will always be deliverable to unlaunched/background apps
877     */
878    ArraySet<String> mBackgroundLaunchBroadcasts;
879
880    /**
881     * All of the processes we currently have running organized by pid.
882     * The keys are the pid running the application.
883     *
884     * <p>NOTE: This object is protected by its own lock, NOT the global
885     * activity manager lock!
886     */
887    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
888
889    /**
890     * All of the processes that have been forced to be foreground.  The key
891     * is the pid of the caller who requested it (we hold a death
892     * link on it).
893     */
894    abstract class ForegroundToken implements IBinder.DeathRecipient {
895        int pid;
896        IBinder token;
897    }
898    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
899
900    /**
901     * List of records for processes that someone had tried to start before the
902     * system was ready.  We don't start them at that point, but ensure they
903     * are started by the time booting is complete.
904     */
905    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
906
907    /**
908     * List of persistent applications that are in the process
909     * of being started.
910     */
911    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
912
913    /**
914     * Processes that are being forcibly torn down.
915     */
916    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
917
918    /**
919     * List of running applications, sorted by recent usage.
920     * The first entry in the list is the least recently used.
921     */
922    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
923
924    /**
925     * Where in mLruProcesses that the processes hosting activities start.
926     */
927    int mLruProcessActivityStart = 0;
928
929    /**
930     * Where in mLruProcesses that the processes hosting services start.
931     * This is after (lower index) than mLruProcessesActivityStart.
932     */
933    int mLruProcessServiceStart = 0;
934
935    /**
936     * List of processes that should gc as soon as things are idle.
937     */
938    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
939
940    /**
941     * Processes we want to collect PSS data from.
942     */
943    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
944
945    private boolean mBinderTransactionTrackingEnabled = false;
946
947    /**
948     * Last time we requested PSS data of all processes.
949     */
950    long mLastFullPssTime = SystemClock.uptimeMillis();
951
952    /**
953     * If set, the next time we collect PSS data we should do a full collection
954     * with data from native processes and the kernel.
955     */
956    boolean mFullPssPending = false;
957
958    /**
959     * This is the process holding what we currently consider to be
960     * the "home" activity.
961     */
962    ProcessRecord mHomeProcess;
963
964    /**
965     * This is the process holding the activity the user last visited that
966     * is in a different process from the one they are currently in.
967     */
968    ProcessRecord mPreviousProcess;
969
970    /**
971     * The time at which the previous process was last visible.
972     */
973    long mPreviousProcessVisibleTime;
974
975    /**
976     * Track all uids that have actively running processes.
977     */
978    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
979
980    /**
981     * This is for verifying the UID report flow.
982     */
983    static final boolean VALIDATE_UID_STATES = true;
984    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
985
986    /**
987     * Packages that the user has asked to have run in screen size
988     * compatibility mode instead of filling the screen.
989     */
990    final CompatModePackages mCompatModePackages;
991
992    /**
993     * Set of IntentSenderRecord objects that are currently active.
994     */
995    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
996            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
997
998    /**
999     * Fingerprints (hashCode()) of stack traces that we've
1000     * already logged DropBox entries for.  Guarded by itself.  If
1001     * something (rogue user app) forces this over
1002     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1003     */
1004    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1005    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1006
1007    /**
1008     * Strict Mode background batched logging state.
1009     *
1010     * The string buffer is guarded by itself, and its lock is also
1011     * used to determine if another batched write is already
1012     * in-flight.
1013     */
1014    private final StringBuilder mStrictModeBuffer = new StringBuilder();
1015
1016    /**
1017     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1018     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1019     */
1020    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1021
1022    /**
1023     * Resolver for broadcast intents to registered receivers.
1024     * Holds BroadcastFilter (subclass of IntentFilter).
1025     */
1026    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1027            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1028        @Override
1029        protected boolean allowFilterResult(
1030                BroadcastFilter filter, List<BroadcastFilter> dest) {
1031            IBinder target = filter.receiverList.receiver.asBinder();
1032            for (int i = dest.size() - 1; i >= 0; i--) {
1033                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1034                    return false;
1035                }
1036            }
1037            return true;
1038        }
1039
1040        @Override
1041        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1042            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1043                    || userId == filter.owningUserId) {
1044                return super.newResult(filter, match, userId);
1045            }
1046            return null;
1047        }
1048
1049        @Override
1050        protected BroadcastFilter[] newArray(int size) {
1051            return new BroadcastFilter[size];
1052        }
1053
1054        @Override
1055        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1056            return packageName.equals(filter.packageName);
1057        }
1058    };
1059
1060    /**
1061     * State of all active sticky broadcasts per user.  Keys are the action of the
1062     * sticky Intent, values are an ArrayList of all broadcasted intents with
1063     * that action (which should usually be one).  The SparseArray is keyed
1064     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1065     * for stickies that are sent to all users.
1066     */
1067    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1068            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1069
1070    final ActiveServices mServices;
1071
1072    final static class Association {
1073        final int mSourceUid;
1074        final String mSourceProcess;
1075        final int mTargetUid;
1076        final ComponentName mTargetComponent;
1077        final String mTargetProcess;
1078
1079        int mCount;
1080        long mTime;
1081
1082        int mNesting;
1083        long mStartTime;
1084
1085        // states of the source process when the bind occurred.
1086        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1087        long mLastStateUptime;
1088        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1089                - ActivityManager.MIN_PROCESS_STATE+1];
1090
1091        Association(int sourceUid, String sourceProcess, int targetUid,
1092                ComponentName targetComponent, String targetProcess) {
1093            mSourceUid = sourceUid;
1094            mSourceProcess = sourceProcess;
1095            mTargetUid = targetUid;
1096            mTargetComponent = targetComponent;
1097            mTargetProcess = targetProcess;
1098        }
1099    }
1100
1101    /**
1102     * When service association tracking is enabled, this is all of the associations we
1103     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1104     * -> association data.
1105     */
1106    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1107            mAssociations = new SparseArray<>();
1108    boolean mTrackingAssociations;
1109
1110    /**
1111     * Backup/restore process management
1112     */
1113    String mBackupAppName = null;
1114    BackupRecord mBackupTarget = null;
1115
1116    final ProviderMap mProviderMap;
1117
1118    /**
1119     * List of content providers who have clients waiting for them.  The
1120     * application is currently being launched and the provider will be
1121     * removed from this list once it is published.
1122     */
1123    final ArrayList<ContentProviderRecord> mLaunchingProviders
1124            = new ArrayList<ContentProviderRecord>();
1125
1126    /**
1127     * File storing persisted {@link #mGrantedUriPermissions}.
1128     */
1129    private final AtomicFile mGrantFile;
1130
1131    /** XML constants used in {@link #mGrantFile} */
1132    private static final String TAG_URI_GRANTS = "uri-grants";
1133    private static final String TAG_URI_GRANT = "uri-grant";
1134    private static final String ATTR_USER_HANDLE = "userHandle";
1135    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1136    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1137    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1138    private static final String ATTR_TARGET_PKG = "targetPkg";
1139    private static final String ATTR_URI = "uri";
1140    private static final String ATTR_MODE_FLAGS = "modeFlags";
1141    private static final String ATTR_CREATED_TIME = "createdTime";
1142    private static final String ATTR_PREFIX = "prefix";
1143
1144    /**
1145     * Global set of specific {@link Uri} permissions that have been granted.
1146     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1147     * to {@link UriPermission#uri} to {@link UriPermission}.
1148     */
1149    @GuardedBy("this")
1150    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1151            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1152
1153    public static class GrantUri {
1154        public final int sourceUserId;
1155        public final Uri uri;
1156        public boolean prefix;
1157
1158        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1159            this.sourceUserId = sourceUserId;
1160            this.uri = uri;
1161            this.prefix = prefix;
1162        }
1163
1164        @Override
1165        public int hashCode() {
1166            int hashCode = 1;
1167            hashCode = 31 * hashCode + sourceUserId;
1168            hashCode = 31 * hashCode + uri.hashCode();
1169            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1170            return hashCode;
1171        }
1172
1173        @Override
1174        public boolean equals(Object o) {
1175            if (o instanceof GrantUri) {
1176                GrantUri other = (GrantUri) o;
1177                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1178                        && prefix == other.prefix;
1179            }
1180            return false;
1181        }
1182
1183        @Override
1184        public String toString() {
1185            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1186            if (prefix) result += " [prefix]";
1187            return result;
1188        }
1189
1190        public String toSafeString() {
1191            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1192            if (prefix) result += " [prefix]";
1193            return result;
1194        }
1195
1196        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1197            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1198                    ContentProvider.getUriWithoutUserId(uri), false);
1199        }
1200    }
1201
1202    CoreSettingsObserver mCoreSettingsObserver;
1203
1204    FontScaleSettingObserver mFontScaleSettingObserver;
1205
1206    private final class FontScaleSettingObserver extends ContentObserver {
1207        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1208
1209        public FontScaleSettingObserver() {
1210            super(mHandler);
1211            ContentResolver resolver = mContext.getContentResolver();
1212            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1213        }
1214
1215        @Override
1216        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1217            if (mFontScaleUri.equals(uri)) {
1218                updateFontScaleIfNeeded(userId);
1219            }
1220        }
1221    }
1222
1223    /**
1224     * Thread-local storage used to carry caller permissions over through
1225     * indirect content-provider access.
1226     */
1227    private class Identity {
1228        public final IBinder token;
1229        public final int pid;
1230        public final int uid;
1231
1232        Identity(IBinder _token, int _pid, int _uid) {
1233            token = _token;
1234            pid = _pid;
1235            uid = _uid;
1236        }
1237    }
1238
1239    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1240
1241    /**
1242     * All information we have collected about the runtime performance of
1243     * any user id that can impact battery performance.
1244     */
1245    final BatteryStatsService mBatteryStatsService;
1246
1247    /**
1248     * Information about component usage
1249     */
1250    UsageStatsManagerInternal mUsageStatsService;
1251
1252    /**
1253     * Access to DeviceIdleController service.
1254     */
1255    DeviceIdleController.LocalService mLocalDeviceIdleController;
1256
1257    /**
1258     * Set of app ids that are whitelisted for device idle and thus background check.
1259     */
1260    int[] mDeviceIdleWhitelist = new int[0];
1261
1262    /**
1263     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1264     */
1265    int[] mDeviceIdleTempWhitelist = new int[0];
1266
1267    /**
1268     * Information about and control over application operations
1269     */
1270    final AppOpsService mAppOpsService;
1271
1272    /** Current sequencing integer of the configuration, for skipping old configurations. */
1273    private int mConfigurationSeq;
1274
1275    /**
1276     * Temp object used when global and/or display override configuration is updated. It is also
1277     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1278     * anyone...
1279     */
1280    private Configuration mTempConfig = new Configuration();
1281
1282    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1283            new UpdateConfigurationResult();
1284    private static final class UpdateConfigurationResult {
1285        // Configuration changes that were updated.
1286        int changes;
1287        // If the activity was relaunched to match the new configuration.
1288        boolean activityRelaunched;
1289
1290        void reset() {
1291            changes = 0;
1292            activityRelaunched = false;
1293        }
1294    }
1295
1296    boolean mSuppressResizeConfigChanges;
1297
1298    /**
1299     * Hardware-reported OpenGLES version.
1300     */
1301    final int GL_ES_VERSION;
1302
1303    /**
1304     * List of initialization arguments to pass to all processes when binding applications to them.
1305     * For example, references to the commonly used services.
1306     */
1307    HashMap<String, IBinder> mAppBindArgs;
1308    HashMap<String, IBinder> mIsolatedAppBindArgs;
1309
1310    /**
1311     * Temporary to avoid allocations.  Protected by main lock.
1312     */
1313    final StringBuilder mStringBuilder = new StringBuilder(256);
1314
1315    /**
1316     * Used to control how we initialize the service.
1317     */
1318    ComponentName mTopComponent;
1319    String mTopAction = Intent.ACTION_MAIN;
1320    String mTopData;
1321
1322    volatile boolean mProcessesReady = false;
1323    volatile boolean mSystemReady = false;
1324    volatile boolean mOnBattery = false;
1325    volatile int mFactoryTest;
1326
1327    @GuardedBy("this") boolean mBooting = false;
1328    @GuardedBy("this") boolean mCallFinishBooting = false;
1329    @GuardedBy("this") boolean mBootAnimationComplete = false;
1330    @GuardedBy("this") boolean mLaunchWarningShown = false;
1331    @GuardedBy("this") boolean mCheckedForSetup = false;
1332
1333    Context mContext;
1334
1335    /**
1336     * The time at which we will allow normal application switches again,
1337     * after a call to {@link #stopAppSwitches()}.
1338     */
1339    long mAppSwitchesAllowedTime;
1340
1341    /**
1342     * This is set to true after the first switch after mAppSwitchesAllowedTime
1343     * is set; any switches after that will clear the time.
1344     */
1345    boolean mDidAppSwitch;
1346
1347    /**
1348     * Last time (in realtime) at which we checked for power usage.
1349     */
1350    long mLastPowerCheckRealtime;
1351
1352    /**
1353     * Last time (in uptime) at which we checked for power usage.
1354     */
1355    long mLastPowerCheckUptime;
1356
1357    /**
1358     * Set while we are wanting to sleep, to prevent any
1359     * activities from being started/resumed.
1360     *
1361     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1362     *
1363     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1364     * while in the sleep state until there is a pending transition out of sleep, in which case
1365     * mSleeping is set to false, and remains false while awake.
1366     *
1367     * Whether mSleeping can quickly toggled between true/false without the device actually
1368     * display changing states is undefined.
1369     */
1370    private boolean mSleeping = false;
1371
1372    /**
1373     * The process state used for processes that are running the top activities.
1374     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1375     */
1376    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1377
1378    /**
1379     * Set while we are running a voice interaction.  This overrides
1380     * sleeping while it is active.
1381     */
1382    private IVoiceInteractionSession mRunningVoice;
1383
1384    /**
1385     * For some direct access we need to power manager.
1386     */
1387    PowerManagerInternal mLocalPowerManager;
1388
1389    /**
1390     * We want to hold a wake lock while running a voice interaction session, since
1391     * this may happen with the screen off and we need to keep the CPU running to
1392     * be able to continue to interact with the user.
1393     */
1394    PowerManager.WakeLock mVoiceWakeLock;
1395
1396    /**
1397     * State of external calls telling us if the device is awake or asleep.
1398     */
1399    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1400
1401    /**
1402     * A list of tokens that cause the top activity to be put to sleep.
1403     * They are used by components that may hide and block interaction with underlying
1404     * activities.
1405     */
1406    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1407
1408    /**
1409     * Set if we are shutting down the system, similar to sleeping.
1410     */
1411    boolean mShuttingDown = false;
1412
1413    /**
1414     * Current sequence id for oom_adj computation traversal.
1415     */
1416    int mAdjSeq = 0;
1417
1418    /**
1419     * Current sequence id for process LRU updating.
1420     */
1421    int mLruSeq = 0;
1422
1423    /**
1424     * Keep track of the non-cached/empty process we last found, to help
1425     * determine how to distribute cached/empty processes next time.
1426     */
1427    int mNumNonCachedProcs = 0;
1428
1429    /**
1430     * Keep track of the number of cached hidden procs, to balance oom adj
1431     * distribution between those and empty procs.
1432     */
1433    int mNumCachedHiddenProcs = 0;
1434
1435    /**
1436     * Keep track of the number of service processes we last found, to
1437     * determine on the next iteration which should be B services.
1438     */
1439    int mNumServiceProcs = 0;
1440    int mNewNumAServiceProcs = 0;
1441    int mNewNumServiceProcs = 0;
1442
1443    /**
1444     * Allow the current computed overall memory level of the system to go down?
1445     * This is set to false when we are killing processes for reasons other than
1446     * memory management, so that the now smaller process list will not be taken as
1447     * an indication that memory is tighter.
1448     */
1449    boolean mAllowLowerMemLevel = false;
1450
1451    /**
1452     * The last computed memory level, for holding when we are in a state that
1453     * processes are going away for other reasons.
1454     */
1455    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1456
1457    /**
1458     * The last total number of process we have, to determine if changes actually look
1459     * like a shrinking number of process due to lower RAM.
1460     */
1461    int mLastNumProcesses;
1462
1463    /**
1464     * The uptime of the last time we performed idle maintenance.
1465     */
1466    long mLastIdleTime = SystemClock.uptimeMillis();
1467
1468    /**
1469     * Total time spent with RAM that has been added in the past since the last idle time.
1470     */
1471    long mLowRamTimeSinceLastIdle = 0;
1472
1473    /**
1474     * If RAM is currently low, when that horrible situation started.
1475     */
1476    long mLowRamStartTime = 0;
1477
1478    /**
1479     * For reporting to battery stats the current top application.
1480     */
1481    private String mCurResumedPackage = null;
1482    private int mCurResumedUid = -1;
1483
1484    /**
1485     * For reporting to battery stats the apps currently running foreground
1486     * service.  The ProcessMap is package/uid tuples; each of these contain
1487     * an array of the currently foreground processes.
1488     */
1489    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1490            = new ProcessMap<ArrayList<ProcessRecord>>();
1491
1492    /**
1493     * This is set if we had to do a delayed dexopt of an app before launching
1494     * it, to increase the ANR timeouts in that case.
1495     */
1496    boolean mDidDexOpt;
1497
1498    /**
1499     * Set if the systemServer made a call to enterSafeMode.
1500     */
1501    boolean mSafeMode;
1502
1503    /**
1504     * If true, we are running under a test environment so will sample PSS from processes
1505     * much more rapidly to try to collect better data when the tests are rapidly
1506     * running through apps.
1507     */
1508    boolean mTestPssMode = false;
1509
1510    String mDebugApp = null;
1511    boolean mWaitForDebugger = false;
1512    boolean mDebugTransient = false;
1513    String mOrigDebugApp = null;
1514    boolean mOrigWaitForDebugger = false;
1515    boolean mAlwaysFinishActivities = false;
1516    boolean mForceResizableActivities;
1517    boolean mSupportsMultiWindow;
1518    boolean mSupportsSplitScreenMultiWindow;
1519    boolean mSupportsFreeformWindowManagement;
1520    boolean mSupportsPictureInPicture;
1521    boolean mSupportsLeanbackOnly;
1522    IActivityController mController = null;
1523    boolean mControllerIsAMonkey = false;
1524    String mProfileApp = null;
1525    ProcessRecord mProfileProc = null;
1526    String mProfileFile;
1527    ParcelFileDescriptor mProfileFd;
1528    int mSamplingInterval = 0;
1529    boolean mAutoStopProfiler = false;
1530    boolean mStreamingOutput = false;
1531    int mProfileType = 0;
1532    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1533    String mMemWatchDumpProcName;
1534    String mMemWatchDumpFile;
1535    int mMemWatchDumpPid;
1536    int mMemWatchDumpUid;
1537    String mTrackAllocationApp = null;
1538    String mNativeDebuggingApp = null;
1539
1540    final long[] mTmpLong = new long[2];
1541
1542    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1543
1544    /**
1545     * A global counter for generating sequence numbers.
1546     * This value will be used when incrementing sequence numbers in individual uidRecords.
1547     *
1548     * Having a global counter ensures that seq numbers are monotonically increasing for a
1549     * particular uid even when the uidRecord is re-created.
1550     */
1551    @GuardedBy("this")
1552    @VisibleForTesting
1553    long mProcStateSeqCounter = 0;
1554
1555    private final Injector mInjector;
1556
1557    static final class ProcessChangeItem {
1558        static final int CHANGE_ACTIVITIES = 1<<0;
1559        int changes;
1560        int uid;
1561        int pid;
1562        int processState;
1563        boolean foregroundActivities;
1564    }
1565
1566    static final class UidObserverRegistration {
1567        final int uid;
1568        final String pkg;
1569        final int which;
1570        final int cutpoint;
1571
1572        final SparseIntArray lastProcStates;
1573
1574        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1575            uid = _uid;
1576            pkg = _pkg;
1577            which = _which;
1578            cutpoint = _cutpoint;
1579            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1580                lastProcStates = new SparseIntArray();
1581            } else {
1582                lastProcStates = null;
1583            }
1584        }
1585    }
1586
1587    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1588    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1589
1590    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1591    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1592
1593    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1594    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1595
1596    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1597    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1598
1599    /**
1600     * Runtime CPU use collection thread.  This object's lock is used to
1601     * perform synchronization with the thread (notifying it to run).
1602     */
1603    final Thread mProcessCpuThread;
1604
1605    /**
1606     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1607     * Must acquire this object's lock when accessing it.
1608     * NOTE: this lock will be held while doing long operations (trawling
1609     * through all processes in /proc), so it should never be acquired by
1610     * any critical paths such as when holding the main activity manager lock.
1611     */
1612    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1613            MONITOR_THREAD_CPU_USAGE);
1614    final AtomicLong mLastCpuTime = new AtomicLong(0);
1615    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1616    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1617
1618    long mLastWriteTime = 0;
1619
1620    /**
1621     * Used to retain an update lock when the foreground activity is in
1622     * immersive mode.
1623     */
1624    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1625
1626    /**
1627     * Set to true after the system has finished booting.
1628     */
1629    boolean mBooted = false;
1630
1631    WindowManagerService mWindowManager;
1632    final ActivityThread mSystemThread;
1633
1634    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1635        final ProcessRecord mApp;
1636        final int mPid;
1637        final IApplicationThread mAppThread;
1638
1639        AppDeathRecipient(ProcessRecord app, int pid,
1640                IApplicationThread thread) {
1641            if (DEBUG_ALL) Slog.v(
1642                TAG, "New death recipient " + this
1643                + " for thread " + thread.asBinder());
1644            mApp = app;
1645            mPid = pid;
1646            mAppThread = thread;
1647        }
1648
1649        @Override
1650        public void binderDied() {
1651            if (DEBUG_ALL) Slog.v(
1652                TAG, "Death received in " + this
1653                + " for thread " + mAppThread.asBinder());
1654            synchronized(ActivityManagerService.this) {
1655                appDiedLocked(mApp, mPid, mAppThread, true);
1656            }
1657        }
1658    }
1659
1660    static final int SHOW_ERROR_UI_MSG = 1;
1661    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1662    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1663    static final int UPDATE_CONFIGURATION_MSG = 4;
1664    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1665    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1666    static final int SERVICE_TIMEOUT_MSG = 12;
1667    static final int UPDATE_TIME_ZONE = 13;
1668    static final int SHOW_UID_ERROR_UI_MSG = 14;
1669    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1670    static final int PROC_START_TIMEOUT_MSG = 20;
1671    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1672    static final int KILL_APPLICATION_MSG = 22;
1673    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1674    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1675    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1676    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1677    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1678    static final int CLEAR_DNS_CACHE_MSG = 28;
1679    static final int UPDATE_HTTP_PROXY_MSG = 29;
1680    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1681    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1682    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1683    static final int REPORT_MEM_USAGE_MSG = 33;
1684    static final int REPORT_USER_SWITCH_MSG = 34;
1685    static final int CONTINUE_USER_SWITCH_MSG = 35;
1686    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1687    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1688    static final int PERSIST_URI_GRANTS_MSG = 38;
1689    static final int REQUEST_ALL_PSS_MSG = 39;
1690    static final int START_PROFILES_MSG = 40;
1691    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1692    static final int SYSTEM_USER_START_MSG = 42;
1693    static final int SYSTEM_USER_CURRENT_MSG = 43;
1694    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1695    static final int FINISH_BOOTING_MSG = 45;
1696    static final int START_USER_SWITCH_UI_MSG = 46;
1697    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1698    static final int DISMISS_DIALOG_UI_MSG = 48;
1699    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1700    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1701    static final int DELETE_DUMPHEAP_MSG = 51;
1702    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1703    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1704    static final int REPORT_TIME_TRACKER_MSG = 54;
1705    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1706    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1707    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1708    static final int IDLE_UIDS_MSG = 58;
1709    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1710    static final int LOG_STACK_STATE = 60;
1711    static final int VR_MODE_CHANGE_MSG = 61;
1712    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1713    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1714    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1715    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1716    static final int START_USER_SWITCH_FG_MSG = 712;
1717
1718    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1719    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1720    static final int FIRST_COMPAT_MODE_MSG = 300;
1721    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1722
1723    static ServiceThread sKillThread = null;
1724    static KillHandler sKillHandler = null;
1725
1726    CompatModeDialog mCompatModeDialog;
1727    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1728    long mLastMemUsageReportTime = 0;
1729
1730    /**
1731     * Flag whether the current user is a "monkey", i.e. whether
1732     * the UI is driven by a UI automation tool.
1733     */
1734    private boolean mUserIsMonkey;
1735
1736    /** Flag whether the device has a Recents UI */
1737    boolean mHasRecents;
1738
1739    /** The dimensions of the thumbnails in the Recents UI. */
1740    int mThumbnailWidth;
1741    int mThumbnailHeight;
1742    float mFullscreenThumbnailScale;
1743
1744    final ServiceThread mHandlerThread;
1745    final MainHandler mHandler;
1746    final Handler mUiHandler;
1747
1748    final ActivityManagerConstants mConstants;
1749
1750    PackageManagerInternal mPackageManagerInt;
1751
1752    // VoiceInteraction session ID that changes for each new request except when
1753    // being called for multiwindow assist in a single session.
1754    private int mViSessionId = 1000;
1755
1756    final boolean mPermissionReviewRequired;
1757
1758    /**
1759     * Current global configuration information. Contains general settings for the entire system,
1760     * also corresponds to the merged configuration of the default display.
1761     */
1762    Configuration getGlobalConfiguration() {
1763        return mStackSupervisor.getConfiguration();
1764    }
1765
1766    final class KillHandler extends Handler {
1767        static final int KILL_PROCESS_GROUP_MSG = 4000;
1768
1769        public KillHandler(Looper looper) {
1770            super(looper, null, true);
1771        }
1772
1773        @Override
1774        public void handleMessage(Message msg) {
1775            switch (msg.what) {
1776                case KILL_PROCESS_GROUP_MSG:
1777                {
1778                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1779                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1780                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1781                }
1782                break;
1783
1784                default:
1785                    super.handleMessage(msg);
1786            }
1787        }
1788    }
1789
1790    final class UiHandler extends Handler {
1791        public UiHandler() {
1792            super(com.android.server.UiThread.get().getLooper(), null, true);
1793        }
1794
1795        @Override
1796        public void handleMessage(Message msg) {
1797            switch (msg.what) {
1798            case SHOW_ERROR_UI_MSG: {
1799                mAppErrors.handleShowAppErrorUi(msg);
1800                ensureBootCompleted();
1801            } break;
1802            case SHOW_NOT_RESPONDING_UI_MSG: {
1803                mAppErrors.handleShowAnrUi(msg);
1804                ensureBootCompleted();
1805            } break;
1806            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1807                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1808                synchronized (ActivityManagerService.this) {
1809                    ProcessRecord proc = (ProcessRecord) data.get("app");
1810                    if (proc == null) {
1811                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1812                        break;
1813                    }
1814                    if (proc.crashDialog != null) {
1815                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1816                        return;
1817                    }
1818                    AppErrorResult res = (AppErrorResult) data.get("result");
1819                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1820                        Dialog d = new StrictModeViolationDialog(mContext,
1821                                ActivityManagerService.this, res, proc);
1822                        d.show();
1823                        proc.crashDialog = d;
1824                    } else {
1825                        // The device is asleep, so just pretend that the user
1826                        // saw a crash dialog and hit "force quit".
1827                        res.set(0);
1828                    }
1829                }
1830                ensureBootCompleted();
1831            } break;
1832            case SHOW_FACTORY_ERROR_UI_MSG: {
1833                Dialog d = new FactoryErrorDialog(
1834                    mContext, msg.getData().getCharSequence("msg"));
1835                d.show();
1836                ensureBootCompleted();
1837            } break;
1838            case WAIT_FOR_DEBUGGER_UI_MSG: {
1839                synchronized (ActivityManagerService.this) {
1840                    ProcessRecord app = (ProcessRecord)msg.obj;
1841                    if (msg.arg1 != 0) {
1842                        if (!app.waitedForDebugger) {
1843                            Dialog d = new AppWaitingForDebuggerDialog(
1844                                    ActivityManagerService.this,
1845                                    mContext, app);
1846                            app.waitDialog = d;
1847                            app.waitedForDebugger = true;
1848                            d.show();
1849                        }
1850                    } else {
1851                        if (app.waitDialog != null) {
1852                            app.waitDialog.dismiss();
1853                            app.waitDialog = null;
1854                        }
1855                    }
1856                }
1857            } break;
1858            case SHOW_UID_ERROR_UI_MSG: {
1859                if (mShowDialogs) {
1860                    AlertDialog d = new BaseErrorDialog(mContext);
1861                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1862                    d.setCancelable(false);
1863                    d.setTitle(mContext.getText(R.string.android_system_label));
1864                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1865                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1866                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1867                    d.show();
1868                }
1869            } break;
1870            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1871                if (mShowDialogs) {
1872                    AlertDialog d = new BaseErrorDialog(mContext);
1873                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1874                    d.setCancelable(false);
1875                    d.setTitle(mContext.getText(R.string.android_system_label));
1876                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1877                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1878                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1879                    d.show();
1880                }
1881            } break;
1882            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1883                synchronized (ActivityManagerService.this) {
1884                    ActivityRecord ar = (ActivityRecord) msg.obj;
1885                    if (mCompatModeDialog != null) {
1886                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1887                                ar.info.applicationInfo.packageName)) {
1888                            return;
1889                        }
1890                        mCompatModeDialog.dismiss();
1891                        mCompatModeDialog = null;
1892                    }
1893                    if (ar != null && false) {
1894                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1895                                ar.packageName)) {
1896                            int mode = mCompatModePackages.computeCompatModeLocked(
1897                                    ar.info.applicationInfo);
1898                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1899                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1900                                mCompatModeDialog = new CompatModeDialog(
1901                                        ActivityManagerService.this, mContext,
1902                                        ar.info.applicationInfo);
1903                                mCompatModeDialog.show();
1904                            }
1905                        }
1906                    }
1907                }
1908                break;
1909            }
1910            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1911                synchronized (ActivityManagerService.this) {
1912                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1913                    if (mUnsupportedDisplaySizeDialog != null) {
1914                        mUnsupportedDisplaySizeDialog.dismiss();
1915                        mUnsupportedDisplaySizeDialog = null;
1916                    }
1917                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1918                            ar.packageName)) {
1919                        // TODO(multi-display): Show dialog on appropriate display.
1920                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1921                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1922                        mUnsupportedDisplaySizeDialog.show();
1923                    }
1924                }
1925                break;
1926            }
1927            case START_USER_SWITCH_UI_MSG: {
1928                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1929                break;
1930            }
1931            case DISMISS_DIALOG_UI_MSG: {
1932                final Dialog d = (Dialog) msg.obj;
1933                d.dismiss();
1934                break;
1935            }
1936            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1937                dispatchProcessesChanged();
1938                break;
1939            }
1940            case DISPATCH_PROCESS_DIED_UI_MSG: {
1941                final int pid = msg.arg1;
1942                final int uid = msg.arg2;
1943                dispatchProcessDied(pid, uid);
1944                break;
1945            }
1946            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1947                dispatchUidsChanged();
1948            } break;
1949            }
1950        }
1951    }
1952
1953    final class MainHandler extends Handler {
1954        public MainHandler(Looper looper) {
1955            super(looper, null, true);
1956        }
1957
1958        @Override
1959        public void handleMessage(Message msg) {
1960            switch (msg.what) {
1961            case UPDATE_CONFIGURATION_MSG: {
1962                final ContentResolver resolver = mContext.getContentResolver();
1963                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1964                        msg.arg1);
1965            } break;
1966            case GC_BACKGROUND_PROCESSES_MSG: {
1967                synchronized (ActivityManagerService.this) {
1968                    performAppGcsIfAppropriateLocked();
1969                }
1970            } break;
1971            case SERVICE_TIMEOUT_MSG: {
1972                if (mDidDexOpt) {
1973                    mDidDexOpt = false;
1974                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1975                    nmsg.obj = msg.obj;
1976                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1977                    return;
1978                }
1979                mServices.serviceTimeout((ProcessRecord)msg.obj);
1980            } break;
1981            case UPDATE_TIME_ZONE: {
1982                synchronized (ActivityManagerService.this) {
1983                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1984                        ProcessRecord r = mLruProcesses.get(i);
1985                        if (r.thread != null) {
1986                            try {
1987                                r.thread.updateTimeZone();
1988                            } catch (RemoteException ex) {
1989                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1990                            }
1991                        }
1992                    }
1993                }
1994            } break;
1995            case CLEAR_DNS_CACHE_MSG: {
1996                synchronized (ActivityManagerService.this) {
1997                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1998                        ProcessRecord r = mLruProcesses.get(i);
1999                        if (r.thread != null) {
2000                            try {
2001                                r.thread.clearDnsCache();
2002                            } catch (RemoteException ex) {
2003                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2004                            }
2005                        }
2006                    }
2007                }
2008            } break;
2009            case UPDATE_HTTP_PROXY_MSG: {
2010                ProxyInfo proxy = (ProxyInfo)msg.obj;
2011                String host = "";
2012                String port = "";
2013                String exclList = "";
2014                Uri pacFileUrl = Uri.EMPTY;
2015                if (proxy != null) {
2016                    host = proxy.getHost();
2017                    port = Integer.toString(proxy.getPort());
2018                    exclList = proxy.getExclusionListAsString();
2019                    pacFileUrl = proxy.getPacFileUrl();
2020                }
2021                synchronized (ActivityManagerService.this) {
2022                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2023                        ProcessRecord r = mLruProcesses.get(i);
2024                        if (r.thread != null) {
2025                            try {
2026                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2027                            } catch (RemoteException ex) {
2028                                Slog.w(TAG, "Failed to update http proxy for: " +
2029                                        r.info.processName);
2030                            }
2031                        }
2032                    }
2033                }
2034            } break;
2035            case PROC_START_TIMEOUT_MSG: {
2036                if (mDidDexOpt) {
2037                    mDidDexOpt = false;
2038                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2039                    nmsg.obj = msg.obj;
2040                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
2041                    return;
2042                }
2043                ProcessRecord app = (ProcessRecord)msg.obj;
2044                synchronized (ActivityManagerService.this) {
2045                    processStartTimedOutLocked(app);
2046                }
2047            } break;
2048            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2049                ProcessRecord app = (ProcessRecord)msg.obj;
2050                synchronized (ActivityManagerService.this) {
2051                    processContentProviderPublishTimedOutLocked(app);
2052                }
2053            } break;
2054            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2055                synchronized (ActivityManagerService.this) {
2056                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2057                }
2058            } break;
2059            case KILL_APPLICATION_MSG: {
2060                synchronized (ActivityManagerService.this) {
2061                    final int appId = msg.arg1;
2062                    final int userId = msg.arg2;
2063                    Bundle bundle = (Bundle)msg.obj;
2064                    String pkg = bundle.getString("pkg");
2065                    String reason = bundle.getString("reason");
2066                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2067                            false, userId, reason);
2068                }
2069            } break;
2070            case FINALIZE_PENDING_INTENT_MSG: {
2071                ((PendingIntentRecord)msg.obj).completeFinalize();
2072            } break;
2073            case POST_HEAVY_NOTIFICATION_MSG: {
2074                INotificationManager inm = NotificationManager.getService();
2075                if (inm == null) {
2076                    return;
2077                }
2078
2079                ActivityRecord root = (ActivityRecord)msg.obj;
2080                ProcessRecord process = root.app;
2081                if (process == null) {
2082                    return;
2083                }
2084
2085                try {
2086                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2087                    String text = mContext.getString(R.string.heavy_weight_notification,
2088                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2089                    Notification notification =
2090                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2091                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2092                            .setWhen(0)
2093                            .setOngoing(true)
2094                            .setTicker(text)
2095                            .setColor(mContext.getColor(
2096                                    com.android.internal.R.color.system_notification_accent_color))
2097                            .setContentTitle(text)
2098                            .setContentText(
2099                                    mContext.getText(R.string.heavy_weight_notification_detail))
2100                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2101                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2102                                    new UserHandle(root.userId)))
2103                            .build();
2104                    try {
2105                        int[] outId = new int[1];
2106                        inm.enqueueNotificationWithTag("android", "android", null,
2107                                R.string.heavy_weight_notification,
2108                                notification, outId, root.userId);
2109                    } catch (RuntimeException e) {
2110                        Slog.w(ActivityManagerService.TAG,
2111                                "Error showing notification for heavy-weight app", e);
2112                    } catch (RemoteException e) {
2113                    }
2114                } catch (NameNotFoundException e) {
2115                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2116                }
2117            } break;
2118            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2119                INotificationManager inm = NotificationManager.getService();
2120                if (inm == null) {
2121                    return;
2122                }
2123                try {
2124                    inm.cancelNotificationWithTag("android", null,
2125                            R.string.heavy_weight_notification,  msg.arg1);
2126                } catch (RuntimeException e) {
2127                    Slog.w(ActivityManagerService.TAG,
2128                            "Error canceling notification for service", e);
2129                } catch (RemoteException e) {
2130                }
2131            } break;
2132            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2133                synchronized (ActivityManagerService.this) {
2134                    checkExcessivePowerUsageLocked(true);
2135                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2136                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2137                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
2138                }
2139            } break;
2140            case REPORT_MEM_USAGE_MSG: {
2141                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2142                Thread thread = new Thread() {
2143                    @Override public void run() {
2144                        reportMemUsage(memInfos);
2145                    }
2146                };
2147                thread.start();
2148                break;
2149            }
2150            case START_USER_SWITCH_FG_MSG: {
2151                mUserController.startUserInForeground(msg.arg1);
2152                break;
2153            }
2154            case REPORT_USER_SWITCH_MSG: {
2155                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2156                break;
2157            }
2158            case CONTINUE_USER_SWITCH_MSG: {
2159                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2160                break;
2161            }
2162            case USER_SWITCH_TIMEOUT_MSG: {
2163                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2164                break;
2165            }
2166            case IMMERSIVE_MODE_LOCK_MSG: {
2167                final boolean nextState = (msg.arg1 != 0);
2168                if (mUpdateLock.isHeld() != nextState) {
2169                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2170                            "Applying new update lock state '" + nextState
2171                            + "' for " + (ActivityRecord)msg.obj);
2172                    if (nextState) {
2173                        mUpdateLock.acquire();
2174                    } else {
2175                        mUpdateLock.release();
2176                    }
2177                }
2178                break;
2179            }
2180            case PERSIST_URI_GRANTS_MSG: {
2181                writeGrantedUriPermissions();
2182                break;
2183            }
2184            case REQUEST_ALL_PSS_MSG: {
2185                synchronized (ActivityManagerService.this) {
2186                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2187                }
2188                break;
2189            }
2190            case START_PROFILES_MSG: {
2191                synchronized (ActivityManagerService.this) {
2192                    mUserController.startProfilesLocked();
2193                }
2194                break;
2195            }
2196            case UPDATE_TIME_PREFERENCE_MSG: {
2197                // The user's time format preference might have changed.
2198                // For convenience we re-use the Intent extra values.
2199                synchronized (ActivityManagerService.this) {
2200                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2201                        ProcessRecord r = mLruProcesses.get(i);
2202                        if (r.thread != null) {
2203                            try {
2204                                r.thread.updateTimePrefs(msg.arg1);
2205                            } catch (RemoteException ex) {
2206                                Slog.w(TAG, "Failed to update preferences for: "
2207                                        + r.info.processName);
2208                            }
2209                        }
2210                    }
2211                }
2212                break;
2213            }
2214            case SYSTEM_USER_START_MSG: {
2215                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2216                        Integer.toString(msg.arg1), msg.arg1);
2217                mSystemServiceManager.startUser(msg.arg1);
2218                break;
2219            }
2220            case SYSTEM_USER_UNLOCK_MSG: {
2221                final int userId = msg.arg1;
2222                mSystemServiceManager.unlockUser(userId);
2223                synchronized (ActivityManagerService.this) {
2224                    mRecentTasks.loadUserRecentsLocked(userId);
2225                }
2226                if (userId == UserHandle.USER_SYSTEM) {
2227                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2228                }
2229                installEncryptionUnawareProviders(userId);
2230                mUserController.finishUserUnlocked((UserState) msg.obj);
2231                break;
2232            }
2233            case SYSTEM_USER_CURRENT_MSG: {
2234                mBatteryStatsService.noteEvent(
2235                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2236                        Integer.toString(msg.arg2), msg.arg2);
2237                mBatteryStatsService.noteEvent(
2238                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2239                        Integer.toString(msg.arg1), msg.arg1);
2240                mSystemServiceManager.switchUser(msg.arg1);
2241                break;
2242            }
2243            case ENTER_ANIMATION_COMPLETE_MSG: {
2244                synchronized (ActivityManagerService.this) {
2245                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2246                    if (r != null && r.app != null && r.app.thread != null) {
2247                        try {
2248                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2249                        } catch (RemoteException e) {
2250                        }
2251                    }
2252                }
2253                break;
2254            }
2255            case FINISH_BOOTING_MSG: {
2256                if (msg.arg1 != 0) {
2257                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2258                    finishBooting();
2259                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2260                }
2261                if (msg.arg2 != 0) {
2262                    enableScreenAfterBoot();
2263                }
2264                break;
2265            }
2266            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2267                try {
2268                    Locale l = (Locale) msg.obj;
2269                    IBinder service = ServiceManager.getService("mount");
2270                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2271                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2272                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2273                } catch (RemoteException e) {
2274                    Log.e(TAG, "Error storing locale for decryption UI", e);
2275                }
2276                break;
2277            }
2278            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2279                final int uid = msg.arg1;
2280                final byte[] firstPacket = (byte[]) msg.obj;
2281
2282                synchronized (mPidsSelfLocked) {
2283                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2284                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2285                        if (p.uid == uid) {
2286                            try {
2287                                p.thread.notifyCleartextNetwork(firstPacket);
2288                            } catch (RemoteException ignored) {
2289                            }
2290                        }
2291                    }
2292                }
2293                break;
2294            }
2295            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2296                final String procName;
2297                final int uid;
2298                final long memLimit;
2299                final String reportPackage;
2300                synchronized (ActivityManagerService.this) {
2301                    procName = mMemWatchDumpProcName;
2302                    uid = mMemWatchDumpUid;
2303                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2304                    if (val == null) {
2305                        val = mMemWatchProcesses.get(procName, 0);
2306                    }
2307                    if (val != null) {
2308                        memLimit = val.first;
2309                        reportPackage = val.second;
2310                    } else {
2311                        memLimit = 0;
2312                        reportPackage = null;
2313                    }
2314                }
2315                if (procName == null) {
2316                    return;
2317                }
2318
2319                if (DEBUG_PSS) Slog.d(TAG_PSS,
2320                        "Showing dump heap notification from " + procName + "/" + uid);
2321
2322                INotificationManager inm = NotificationManager.getService();
2323                if (inm == null) {
2324                    return;
2325                }
2326
2327                String text = mContext.getString(R.string.dump_heap_notification, procName);
2328
2329
2330                Intent deleteIntent = new Intent();
2331                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2332                Intent intent = new Intent();
2333                intent.setClassName("android", DumpHeapActivity.class.getName());
2334                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2335                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2336                if (reportPackage != null) {
2337                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2338                }
2339                int userId = UserHandle.getUserId(uid);
2340                Notification notification =
2341                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2342                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2343                        .setWhen(0)
2344                        .setOngoing(true)
2345                        .setAutoCancel(true)
2346                        .setTicker(text)
2347                        .setColor(mContext.getColor(
2348                                com.android.internal.R.color.system_notification_accent_color))
2349                        .setContentTitle(text)
2350                        .setContentText(
2351                                mContext.getText(R.string.dump_heap_notification_detail))
2352                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2353                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2354                                new UserHandle(userId)))
2355                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2356                                deleteIntent, 0, UserHandle.SYSTEM))
2357                        .build();
2358
2359                try {
2360                    int[] outId = new int[1];
2361                    inm.enqueueNotificationWithTag("android", "android", null,
2362                            R.string.dump_heap_notification,
2363                            notification, outId, userId);
2364                } catch (RuntimeException e) {
2365                    Slog.w(ActivityManagerService.TAG,
2366                            "Error showing notification for dump heap", e);
2367                } catch (RemoteException e) {
2368                }
2369            } break;
2370            case DELETE_DUMPHEAP_MSG: {
2371                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2372                        DumpHeapActivity.JAVA_URI,
2373                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2374                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2375                        UserHandle.myUserId());
2376                synchronized (ActivityManagerService.this) {
2377                    mMemWatchDumpFile = null;
2378                    mMemWatchDumpProcName = null;
2379                    mMemWatchDumpPid = -1;
2380                    mMemWatchDumpUid = -1;
2381                }
2382            } break;
2383            case FOREGROUND_PROFILE_CHANGED_MSG: {
2384                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2385            } break;
2386            case REPORT_TIME_TRACKER_MSG: {
2387                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2388                tracker.deliverResult(mContext);
2389            } break;
2390            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2391                mUserController.dispatchUserSwitchComplete(msg.arg1);
2392            } break;
2393            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2394                mUserController.dispatchLockedBootComplete(msg.arg1);
2395            } break;
2396            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2397                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2398                try {
2399                    connection.shutdown();
2400                } catch (RemoteException e) {
2401                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2402                }
2403                // Only a UiAutomation can set this flag and now that
2404                // it is finished we make sure it is reset to its default.
2405                mUserIsMonkey = false;
2406            } break;
2407            case IDLE_UIDS_MSG: {
2408                idleUids();
2409            } break;
2410            case VR_MODE_CHANGE_MSG: {
2411                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2412                if (vrService == null) {
2413                    break;
2414                }
2415                final ActivityRecord r = (ActivityRecord) msg.obj;
2416                boolean vrMode;
2417                boolean inVrMode;
2418                ComponentName requestedPackage;
2419                ComponentName callingPackage;
2420                int userId;
2421                synchronized (ActivityManagerService.this) {
2422                    vrMode = r.requestedVrComponent != null;
2423                    inVrMode = mVrState != NON_VR_MODE;
2424                    requestedPackage = r.requestedVrComponent;
2425                    userId = r.userId;
2426                    callingPackage = r.info.getComponentName();
2427                    if (vrMode != inVrMode) {
2428                        // Don't change state if we're in persistent VR mode, but do update thread
2429                        // priorities if necessary.
2430                        if (mVrState != PERSISTENT_VR_MODE) {
2431                            mVrState = vrMode ? VR_MODE : NON_VR_MODE;
2432                        }
2433                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), vrMode);
2434                        if (r.app != null) {
2435                            ProcessRecord proc = r.app;
2436                            if (proc.vrThreadTid > 0) {
2437                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2438                                    try {
2439                                        if (mVrState == VR_MODE) {
2440                                            Process.setThreadScheduler(proc.vrThreadTid,
2441                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2442                                            mTopAppVrThreadTid = proc.vrThreadTid;
2443                                        } else {
2444                                            Process.setThreadScheduler(proc.vrThreadTid,
2445                                                Process.SCHED_OTHER, 0);
2446                                            mTopAppVrThreadTid = 0;
2447                                        }
2448                                    } catch (IllegalArgumentException e) {
2449                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2450                                                + " not exist:\n" + e);
2451                                    }
2452                                }
2453                            }
2454                        }
2455                    }
2456                }
2457                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2458            } break;
2459            case NOTIFY_VR_SLEEPING_MSG: {
2460                notifyVrManagerOfSleepState(msg.arg1 != 0);
2461            } break;
2462            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2463                synchronized (ActivityManagerService.this) {
2464                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2465                        ProcessRecord r = mLruProcesses.get(i);
2466                        if (r.thread != null) {
2467                            try {
2468                                r.thread.handleTrustStorageUpdate();
2469                            } catch (RemoteException ex) {
2470                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2471                                        r.info.processName);
2472                            }
2473                        }
2474                    }
2475                }
2476            } break;
2477            }
2478        }
2479    };
2480
2481    static final int COLLECT_PSS_BG_MSG = 1;
2482
2483    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2484        @Override
2485        public void handleMessage(Message msg) {
2486            switch (msg.what) {
2487            case COLLECT_PSS_BG_MSG: {
2488                long start = SystemClock.uptimeMillis();
2489                MemInfoReader memInfo = null;
2490                synchronized (ActivityManagerService.this) {
2491                    if (mFullPssPending) {
2492                        mFullPssPending = false;
2493                        memInfo = new MemInfoReader();
2494                    }
2495                }
2496                if (memInfo != null) {
2497                    updateCpuStatsNow();
2498                    long nativeTotalPss = 0;
2499                    final List<ProcessCpuTracker.Stats> stats;
2500                    synchronized (mProcessCpuTracker) {
2501                        stats = mProcessCpuTracker.getStats( (st)-> {
2502                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2503                        });
2504                    }
2505                    final int N = stats.size();
2506                    for (int j = 0; j < N; j++) {
2507                        synchronized (mPidsSelfLocked) {
2508                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2509                                // This is one of our own processes; skip it.
2510                                continue;
2511                            }
2512                        }
2513                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2514                    }
2515                    memInfo.readMemInfo();
2516                    synchronized (ActivityManagerService.this) {
2517                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2518                                + (SystemClock.uptimeMillis()-start) + "ms");
2519                        final long cachedKb = memInfo.getCachedSizeKb();
2520                        final long freeKb = memInfo.getFreeSizeKb();
2521                        final long zramKb = memInfo.getZramTotalSizeKb();
2522                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2523                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2524                                kernelKb*1024, nativeTotalPss*1024);
2525                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2526                                nativeTotalPss);
2527                    }
2528                }
2529
2530                int num = 0;
2531                long[] tmp = new long[2];
2532                do {
2533                    ProcessRecord proc;
2534                    int procState;
2535                    int pid;
2536                    long lastPssTime;
2537                    synchronized (ActivityManagerService.this) {
2538                        if (mPendingPssProcesses.size() <= 0) {
2539                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2540                                    "Collected PSS of " + num + " processes in "
2541                                    + (SystemClock.uptimeMillis() - start) + "ms");
2542                            mPendingPssProcesses.clear();
2543                            return;
2544                        }
2545                        proc = mPendingPssProcesses.remove(0);
2546                        procState = proc.pssProcState;
2547                        lastPssTime = proc.lastPssTime;
2548                        if (proc.thread != null && procState == proc.setProcState
2549                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2550                                        < SystemClock.uptimeMillis()) {
2551                            pid = proc.pid;
2552                        } else {
2553                            proc = null;
2554                            pid = 0;
2555                        }
2556                    }
2557                    if (proc != null) {
2558                        long pss = Debug.getPss(pid, tmp, null);
2559                        synchronized (ActivityManagerService.this) {
2560                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2561                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2562                                num++;
2563                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2564                                        SystemClock.uptimeMillis());
2565                            }
2566                        }
2567                    }
2568                } while (true);
2569            }
2570            }
2571        }
2572    };
2573
2574    public void setSystemProcess() {
2575        try {
2576            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2577            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2578            ServiceManager.addService("meminfo", new MemBinder(this));
2579            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2580            ServiceManager.addService("dbinfo", new DbBinder(this));
2581            if (MONITOR_CPU_USAGE) {
2582                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2583            }
2584            ServiceManager.addService("permission", new PermissionController(this));
2585            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2586
2587            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2588                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2589            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2590
2591            synchronized (this) {
2592                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2593                app.persistent = true;
2594                app.pid = MY_PID;
2595                app.maxAdj = ProcessList.SYSTEM_ADJ;
2596                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2597                synchronized (mPidsSelfLocked) {
2598                    mPidsSelfLocked.put(app.pid, app);
2599                }
2600                updateLruProcessLocked(app, false, null);
2601                updateOomAdjLocked();
2602            }
2603        } catch (PackageManager.NameNotFoundException e) {
2604            throw new RuntimeException(
2605                    "Unable to find android system package", e);
2606        }
2607    }
2608
2609    public void setWindowManager(WindowManagerService wm) {
2610        mWindowManager = wm;
2611        mStackSupervisor.setWindowManager(wm);
2612        mActivityStarter.setWindowManager(wm);
2613    }
2614
2615    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2616        mUsageStatsService = usageStatsManager;
2617    }
2618
2619    public void startObservingNativeCrashes() {
2620        final NativeCrashListener ncl = new NativeCrashListener(this);
2621        ncl.start();
2622    }
2623
2624    public IAppOpsService getAppOpsService() {
2625        return mAppOpsService;
2626    }
2627
2628    static class MemBinder extends Binder {
2629        ActivityManagerService mActivityManagerService;
2630        MemBinder(ActivityManagerService activityManagerService) {
2631            mActivityManagerService = activityManagerService;
2632        }
2633
2634        @Override
2635        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2636            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2637                    != PackageManager.PERMISSION_GRANTED) {
2638                pw.println("Permission Denial: can't dump meminfo from from pid="
2639                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2640                        + " without permission " + android.Manifest.permission.DUMP);
2641                return;
2642            }
2643
2644            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2645        }
2646    }
2647
2648    static class GraphicsBinder extends Binder {
2649        ActivityManagerService mActivityManagerService;
2650        GraphicsBinder(ActivityManagerService activityManagerService) {
2651            mActivityManagerService = activityManagerService;
2652        }
2653
2654        @Override
2655        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2656            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2657                    != PackageManager.PERMISSION_GRANTED) {
2658                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2659                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2660                        + " without permission " + android.Manifest.permission.DUMP);
2661                return;
2662            }
2663
2664            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2665        }
2666    }
2667
2668    static class DbBinder extends Binder {
2669        ActivityManagerService mActivityManagerService;
2670        DbBinder(ActivityManagerService activityManagerService) {
2671            mActivityManagerService = activityManagerService;
2672        }
2673
2674        @Override
2675        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2676            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2677                    != PackageManager.PERMISSION_GRANTED) {
2678                pw.println("Permission Denial: can't dump dbinfo from from pid="
2679                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2680                        + " without permission " + android.Manifest.permission.DUMP);
2681                return;
2682            }
2683
2684            mActivityManagerService.dumpDbInfo(fd, pw, args);
2685        }
2686    }
2687
2688    static class CpuBinder extends Binder {
2689        ActivityManagerService mActivityManagerService;
2690        CpuBinder(ActivityManagerService activityManagerService) {
2691            mActivityManagerService = activityManagerService;
2692        }
2693
2694        @Override
2695        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2696            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2697                    != PackageManager.PERMISSION_GRANTED) {
2698                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2699                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2700                        + " without permission " + android.Manifest.permission.DUMP);
2701                return;
2702            }
2703
2704            synchronized (mActivityManagerService.mProcessCpuTracker) {
2705                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2706                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2707                        SystemClock.uptimeMillis()));
2708            }
2709        }
2710    }
2711
2712    public static final class Lifecycle extends SystemService {
2713        private final ActivityManagerService mService;
2714
2715        public Lifecycle(Context context) {
2716            super(context);
2717            mService = new ActivityManagerService(context);
2718        }
2719
2720        @Override
2721        public void onStart() {
2722            mService.start();
2723        }
2724
2725        public ActivityManagerService getService() {
2726            return mService;
2727        }
2728    }
2729
2730    @VisibleForTesting
2731    public ActivityManagerService(Injector injector) {
2732        mInjector = injector;
2733        GL_ES_VERSION = 0;
2734        mActivityStarter = null;
2735        mAppErrors = null;
2736        mAppOpsService = mInjector.getAppOpsService(null, null);
2737        mBatteryStatsService = null;
2738        mCompatModePackages = null;
2739        mConstants = null;
2740        mGrantFile = null;
2741        mHandler = null;
2742        mHandlerThread = null;
2743        mIntentFirewall = null;
2744        mKeyguardController = null;
2745        mPermissionReviewRequired = false;
2746        mProcessCpuThread = null;
2747        mProcessStats = null;
2748        mProviderMap = null;
2749        mRecentTasks = null;
2750        mServices = null;
2751        mStackSupervisor = null;
2752        mSystemThread = null;
2753        mTaskChangeNotificationController = null;
2754        mUiHandler = injector.getUiHandler(null);
2755        mUserController = null;
2756    }
2757
2758    // Note: This method is invoked on the main thread but may need to attach various
2759    // handlers to other threads.  So take care to be explicit about the looper.
2760    public ActivityManagerService(Context systemContext) {
2761        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2762        mInjector = new Injector();
2763        mContext = systemContext;
2764        mFactoryTest = FactoryTest.getMode();
2765        mSystemThread = ActivityThread.currentActivityThread();
2766
2767        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2768
2769        mPermissionReviewRequired = mContext.getResources().getBoolean(
2770                com.android.internal.R.bool.config_permissionReviewRequired);
2771
2772        mHandlerThread = new ServiceThread(TAG,
2773                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2774        mHandlerThread.start();
2775        mHandler = new MainHandler(mHandlerThread.getLooper());
2776        mUiHandler = mInjector.getUiHandler(this);
2777
2778        mConstants = new ActivityManagerConstants(this, mHandler);
2779
2780        if (DEBUG_BACKGROUND_CHECK) {
2781            Slog.d(TAG, "Enforcing O+ bg restrictions: " + mConstants.ENFORCE_BG_CHECK);
2782            StringBuilder sb = new StringBuilder(200);
2783            sb.append("  ");
2784            for (String a : getBackgroundLaunchBroadcasts()) {
2785                sb.append(' '); sb.append(a);
2786            }
2787            Slog.d(TAG, "Background implicit broadcasts:");
2788            Slog.d(TAG, sb.toString());
2789        }
2790
2791        /* static; one-time init here */
2792        if (sKillHandler == null) {
2793            sKillThread = new ServiceThread(TAG + ":kill",
2794                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2795            sKillThread.start();
2796            sKillHandler = new KillHandler(sKillThread.getLooper());
2797        }
2798
2799        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2800                "foreground", BROADCAST_FG_TIMEOUT, false);
2801        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2802                "background", BROADCAST_BG_TIMEOUT, true);
2803        mBroadcastQueues[0] = mFgBroadcastQueue;
2804        mBroadcastQueues[1] = mBgBroadcastQueue;
2805
2806        mServices = new ActiveServices(this);
2807        mProviderMap = new ProviderMap(this);
2808        mAppErrors = new AppErrors(mContext, this);
2809
2810        // TODO: Move creation of battery stats service outside of activity manager service.
2811        File dataDir = Environment.getDataDirectory();
2812        File systemDir = new File(dataDir, "system");
2813        systemDir.mkdirs();
2814        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2815        mBatteryStatsService.getActiveStatistics().readLocked();
2816        mBatteryStatsService.scheduleWriteToDisk();
2817        mOnBattery = DEBUG_POWER ? true
2818                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2819        mBatteryStatsService.getActiveStatistics().setCallback(this);
2820
2821        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2822
2823        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2824        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2825                new IAppOpsCallback.Stub() {
2826                    @Override public void opChanged(int op, int uid, String packageName) {
2827                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2828                            if (mAppOpsService.checkOperation(op, uid, packageName)
2829                                    != AppOpsManager.MODE_ALLOWED) {
2830                                runInBackgroundDisabled(uid);
2831                            }
2832                        }
2833                    }
2834                });
2835
2836        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2837
2838        mUserController = new UserController(this);
2839
2840        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2841            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2842
2843        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2844            mUseFifoUiScheduling = true;
2845        }
2846
2847        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2848        mTempConfig.setToDefaults();
2849        mTempConfig.setLocales(LocaleList.getDefault());
2850        mConfigurationSeq = mTempConfig.seq = 1;
2851        mStackSupervisor = new ActivityStackSupervisor(this);
2852        mStackSupervisor.onConfigurationChanged(mTempConfig);
2853        mKeyguardController = mStackSupervisor.mKeyguardController;
2854        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2855        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2856        mTaskChangeNotificationController =
2857                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2858        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2859        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2860
2861        mProcessCpuThread = new Thread("CpuTracker") {
2862            @Override
2863            public void run() {
2864                synchronized (mProcessCpuTracker) {
2865                    mProcessCpuInitLatch.countDown();
2866                    mProcessCpuTracker.init();
2867                }
2868                while (true) {
2869                    try {
2870                        try {
2871                            synchronized(this) {
2872                                final long now = SystemClock.uptimeMillis();
2873                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2874                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2875                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2876                                //        + ", write delay=" + nextWriteDelay);
2877                                if (nextWriteDelay < nextCpuDelay) {
2878                                    nextCpuDelay = nextWriteDelay;
2879                                }
2880                                if (nextCpuDelay > 0) {
2881                                    mProcessCpuMutexFree.set(true);
2882                                    this.wait(nextCpuDelay);
2883                                }
2884                            }
2885                        } catch (InterruptedException e) {
2886                        }
2887                        updateCpuStatsNow();
2888                    } catch (Exception e) {
2889                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2890                    }
2891                }
2892            }
2893        };
2894
2895        Watchdog.getInstance().addMonitor(this);
2896        Watchdog.getInstance().addThread(mHandler);
2897    }
2898
2899    public void setSystemServiceManager(SystemServiceManager mgr) {
2900        mSystemServiceManager = mgr;
2901    }
2902
2903    public void setInstaller(Installer installer) {
2904        mInstaller = installer;
2905    }
2906
2907    private void start() {
2908        Process.removeAllProcessGroups();
2909        mProcessCpuThread.start();
2910
2911        mBatteryStatsService.publish(mContext);
2912        mAppOpsService.publish(mContext);
2913        Slog.d("AppOps", "AppOpsService published");
2914        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2915        // Wait for the synchronized block started in mProcessCpuThread,
2916        // so that any other acccess to mProcessCpuTracker from main thread
2917        // will be blocked during mProcessCpuTracker initialization.
2918        try {
2919            mProcessCpuInitLatch.await();
2920        } catch (InterruptedException e) {
2921            Slog.wtf(TAG, "Interrupted wait during start", e);
2922            Thread.currentThread().interrupt();
2923            throw new IllegalStateException("Interrupted wait during start");
2924        }
2925    }
2926
2927    void onUserStoppedLocked(int userId) {
2928        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2929    }
2930
2931    public void initPowerManagement() {
2932        mStackSupervisor.initPowerManagement();
2933        mBatteryStatsService.initPowerManagement();
2934        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2935        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2936        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2937        mVoiceWakeLock.setReferenceCounted(false);
2938    }
2939
2940    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2941        if (mBackgroundLaunchBroadcasts == null) {
2942            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2943        }
2944        return mBackgroundLaunchBroadcasts;
2945    }
2946
2947    @Override
2948    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2949            throws RemoteException {
2950        if (code == SYSPROPS_TRANSACTION) {
2951            // We need to tell all apps about the system property change.
2952            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2953            synchronized(this) {
2954                final int NP = mProcessNames.getMap().size();
2955                for (int ip=0; ip<NP; ip++) {
2956                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2957                    final int NA = apps.size();
2958                    for (int ia=0; ia<NA; ia++) {
2959                        ProcessRecord app = apps.valueAt(ia);
2960                        if (app.thread != null) {
2961                            procs.add(app.thread.asBinder());
2962                        }
2963                    }
2964                }
2965            }
2966
2967            int N = procs.size();
2968            for (int i=0; i<N; i++) {
2969                Parcel data2 = Parcel.obtain();
2970                try {
2971                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2972                            Binder.FLAG_ONEWAY);
2973                } catch (RemoteException e) {
2974                }
2975                data2.recycle();
2976            }
2977        }
2978        try {
2979            return super.onTransact(code, data, reply, flags);
2980        } catch (RuntimeException e) {
2981            // The activity manager only throws security exceptions, so let's
2982            // log all others.
2983            if (!(e instanceof SecurityException)) {
2984                Slog.wtf(TAG, "Activity Manager Crash", e);
2985            }
2986            throw e;
2987        }
2988    }
2989
2990    void updateCpuStats() {
2991        final long now = SystemClock.uptimeMillis();
2992        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2993            return;
2994        }
2995        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2996            synchronized (mProcessCpuThread) {
2997                mProcessCpuThread.notify();
2998            }
2999        }
3000    }
3001
3002    void updateCpuStatsNow() {
3003        synchronized (mProcessCpuTracker) {
3004            mProcessCpuMutexFree.set(false);
3005            final long now = SystemClock.uptimeMillis();
3006            boolean haveNewCpuStats = false;
3007
3008            if (MONITOR_CPU_USAGE &&
3009                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3010                mLastCpuTime.set(now);
3011                mProcessCpuTracker.update();
3012                if (mProcessCpuTracker.hasGoodLastStats()) {
3013                    haveNewCpuStats = true;
3014                    //Slog.i(TAG, mProcessCpu.printCurrentState());
3015                    //Slog.i(TAG, "Total CPU usage: "
3016                    //        + mProcessCpu.getTotalCpuPercent() + "%");
3017
3018                    // Slog the cpu usage if the property is set.
3019                    if ("true".equals(SystemProperties.get("events.cpu"))) {
3020                        int user = mProcessCpuTracker.getLastUserTime();
3021                        int system = mProcessCpuTracker.getLastSystemTime();
3022                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
3023                        int irq = mProcessCpuTracker.getLastIrqTime();
3024                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3025                        int idle = mProcessCpuTracker.getLastIdleTime();
3026
3027                        int total = user + system + iowait + irq + softIrq + idle;
3028                        if (total == 0) total = 1;
3029
3030                        EventLog.writeEvent(EventLogTags.CPU,
3031                                ((user+system+iowait+irq+softIrq) * 100) / total,
3032                                (user * 100) / total,
3033                                (system * 100) / total,
3034                                (iowait * 100) / total,
3035                                (irq * 100) / total,
3036                                (softIrq * 100) / total);
3037                    }
3038                }
3039            }
3040
3041            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3042            synchronized(bstats) {
3043                synchronized(mPidsSelfLocked) {
3044                    if (haveNewCpuStats) {
3045                        if (bstats.startAddingCpuLocked()) {
3046                            int totalUTime = 0;
3047                            int totalSTime = 0;
3048                            final int N = mProcessCpuTracker.countStats();
3049                            for (int i=0; i<N; i++) {
3050                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3051                                if (!st.working) {
3052                                    continue;
3053                                }
3054                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3055                                totalUTime += st.rel_utime;
3056                                totalSTime += st.rel_stime;
3057                                if (pr != null) {
3058                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3059                                    if (ps == null || !ps.isActive()) {
3060                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3061                                                pr.info.uid, pr.processName);
3062                                    }
3063                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3064                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3065                                } else {
3066                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3067                                    if (ps == null || !ps.isActive()) {
3068                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3069                                                bstats.mapUid(st.uid), st.name);
3070                                    }
3071                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3072                                }
3073                            }
3074                            final int userTime = mProcessCpuTracker.getLastUserTime();
3075                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3076                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3077                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3078                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3079                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3080                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3081                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3082                        }
3083                    }
3084                }
3085
3086                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3087                    mLastWriteTime = now;
3088                    mBatteryStatsService.scheduleWriteToDisk();
3089                }
3090            }
3091        }
3092    }
3093
3094    @Override
3095    public void batteryNeedsCpuUpdate() {
3096        updateCpuStatsNow();
3097    }
3098
3099    @Override
3100    public void batteryPowerChanged(boolean onBattery) {
3101        // When plugging in, update the CPU stats first before changing
3102        // the plug state.
3103        updateCpuStatsNow();
3104        synchronized (this) {
3105            synchronized(mPidsSelfLocked) {
3106                mOnBattery = DEBUG_POWER ? true : onBattery;
3107            }
3108        }
3109    }
3110
3111    @Override
3112    public void batterySendBroadcast(Intent intent) {
3113        synchronized (this) {
3114            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3115                    AppOpsManager.OP_NONE, null, false, false,
3116                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
3117        }
3118    }
3119
3120    /**
3121     * Initialize the application bind args. These are passed to each
3122     * process when the bindApplication() IPC is sent to the process. They're
3123     * lazily setup to make sure the services are running when they're asked for.
3124     */
3125    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3126        // Isolated processes won't get this optimization, so that we don't
3127        // violate the rules about which services they have access to.
3128        if (isolated) {
3129            if (mIsolatedAppBindArgs == null) {
3130                mIsolatedAppBindArgs = new HashMap<>();
3131                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3132            }
3133            return mIsolatedAppBindArgs;
3134        }
3135
3136        if (mAppBindArgs == null) {
3137            mAppBindArgs = new HashMap<>();
3138
3139            // Setup the application init args
3140            mAppBindArgs.put("package", ServiceManager.getService("package"));
3141            mAppBindArgs.put("window", ServiceManager.getService("window"));
3142            mAppBindArgs.put(Context.ALARM_SERVICE,
3143                    ServiceManager.getService(Context.ALARM_SERVICE));
3144        }
3145        return mAppBindArgs;
3146    }
3147
3148    /**
3149     * Update AMS states when an activity is resumed. This should only be called by
3150     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3151     */
3152    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3153        if (r.task.isApplicationTask()) {
3154            if (mCurAppTimeTracker != r.appTimeTracker) {
3155                // We are switching app tracking.  Complete the current one.
3156                if (mCurAppTimeTracker != null) {
3157                    mCurAppTimeTracker.stop();
3158                    mHandler.obtainMessage(
3159                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3160                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3161                    mCurAppTimeTracker = null;
3162                }
3163                if (r.appTimeTracker != null) {
3164                    mCurAppTimeTracker = r.appTimeTracker;
3165                    startTimeTrackingFocusedActivityLocked();
3166                }
3167            } else {
3168                startTimeTrackingFocusedActivityLocked();
3169            }
3170        } else {
3171            r.appTimeTracker = null;
3172        }
3173        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3174        // TODO: Probably not, because we don't want to resume voice on switching
3175        // back to this activity
3176        if (r.task.voiceInteractor != null) {
3177            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3178        } else {
3179            finishRunningVoiceLocked();
3180
3181            if (mLastResumedActivity != null) {
3182                final IVoiceInteractionSession session;
3183
3184                if (mLastResumedActivity.task != null
3185                        && mLastResumedActivity.task.voiceSession != null) {
3186                    session = mLastResumedActivity.task.voiceSession;
3187                } else {
3188                    session = mLastResumedActivity.voiceSession;
3189                }
3190
3191                if (session != null) {
3192                    // We had been in a voice interaction session, but now focused has
3193                    // move to something different.  Just finish the session, we can't
3194                    // return to it and retain the proper state and synchronization with
3195                    // the voice interaction service.
3196                    finishVoiceTask(session);
3197                }
3198            }
3199        }
3200
3201        mWindowManager.setFocusedApp(r.appToken, true);
3202
3203        applyUpdateLockStateLocked(r);
3204        applyUpdateVrModeLocked(r);
3205        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3206            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3207            mHandler.obtainMessage(
3208                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3209        }
3210
3211        mLastResumedActivity = r;
3212
3213        EventLogTags.writeAmSetResumedActivity(
3214                r == null ? -1 : r.userId,
3215                r == null ? "NULL" : r.shortComponentName,
3216                reason);
3217    }
3218
3219    @Override
3220    public void setFocusedStack(int stackId) {
3221        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3222        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3223        final long callingId = Binder.clearCallingIdentity();
3224        try {
3225            synchronized (this) {
3226                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3227                if (stack == null) {
3228                    return;
3229                }
3230                final ActivityRecord r = stack.topRunningActivityLocked();
3231                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3232                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3233                }
3234            }
3235        } finally {
3236            Binder.restoreCallingIdentity(callingId);
3237        }
3238    }
3239
3240    @Override
3241    public void setFocusedTask(int taskId) {
3242        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3243        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3244        final long callingId = Binder.clearCallingIdentity();
3245        try {
3246            synchronized (this) {
3247                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3248                if (task == null) {
3249                    return;
3250                }
3251                final ActivityRecord r = task.topRunningActivityLocked();
3252                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3253                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3254                }
3255            }
3256        } finally {
3257            Binder.restoreCallingIdentity(callingId);
3258        }
3259    }
3260
3261    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3262    @Override
3263    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3264        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3265        mTaskChangeNotificationController.registerTaskStackListener(listener);
3266    }
3267
3268    /**
3269     * Unregister a task stack listener so that it stops receiving callbacks.
3270     */
3271    @Override
3272    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3273         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3274         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3275     }
3276
3277    @Override
3278    public void notifyActivityDrawn(IBinder token) {
3279        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3280        synchronized (this) {
3281            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3282            if (r != null) {
3283                r.getStack().notifyActivityDrawnLocked(r);
3284            }
3285        }
3286    }
3287
3288    final void applyUpdateLockStateLocked(ActivityRecord r) {
3289        // Modifications to the UpdateLock state are done on our handler, outside
3290        // the activity manager's locks.  The new state is determined based on the
3291        // state *now* of the relevant activity record.  The object is passed to
3292        // the handler solely for logging detail, not to be consulted/modified.
3293        final boolean nextState = r != null && r.immersive;
3294        mHandler.sendMessage(
3295                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3296    }
3297
3298    final void applyUpdateVrModeLocked(ActivityRecord r) {
3299        mHandler.sendMessage(
3300                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3301    }
3302
3303    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3304        mHandler.sendMessage(
3305                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3306    }
3307
3308    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3309        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3310        if (vrService == null) {
3311            return;
3312        }
3313        vrService.onSleepStateChanged(isSleeping);
3314    }
3315
3316    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3317        Message msg = Message.obtain();
3318        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3319        msg.obj = r.task.askedCompatMode ? null : r;
3320        mUiHandler.sendMessage(msg);
3321    }
3322
3323    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3324        final Configuration globalConfig = getGlobalConfiguration();
3325        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3326                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3327            final Message msg = Message.obtain();
3328            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3329            msg.obj = r;
3330            mUiHandler.sendMessage(msg);
3331        }
3332    }
3333
3334    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3335            String what, Object obj, ProcessRecord srcApp) {
3336        app.lastActivityTime = now;
3337
3338        if (app.activities.size() > 0) {
3339            // Don't want to touch dependent processes that are hosting activities.
3340            return index;
3341        }
3342
3343        int lrui = mLruProcesses.lastIndexOf(app);
3344        if (lrui < 0) {
3345            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3346                    + what + " " + obj + " from " + srcApp);
3347            return index;
3348        }
3349
3350        if (lrui >= index) {
3351            // Don't want to cause this to move dependent processes *back* in the
3352            // list as if they were less frequently used.
3353            return index;
3354        }
3355
3356        if (lrui >= mLruProcessActivityStart) {
3357            // Don't want to touch dependent processes that are hosting activities.
3358            return index;
3359        }
3360
3361        mLruProcesses.remove(lrui);
3362        if (index > 0) {
3363            index--;
3364        }
3365        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3366                + " in LRU list: " + app);
3367        mLruProcesses.add(index, app);
3368        return index;
3369    }
3370
3371    static void killProcessGroup(int uid, int pid) {
3372        if (sKillHandler != null) {
3373            sKillHandler.sendMessage(
3374                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3375        } else {
3376            Slog.w(TAG, "Asked to kill process group before system bringup!");
3377            Process.killProcessGroup(uid, pid);
3378        }
3379    }
3380
3381    final void removeLruProcessLocked(ProcessRecord app) {
3382        int lrui = mLruProcesses.lastIndexOf(app);
3383        if (lrui >= 0) {
3384            if (!app.killed) {
3385                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3386                Process.killProcessQuiet(app.pid);
3387                killProcessGroup(app.uid, app.pid);
3388            }
3389            if (lrui <= mLruProcessActivityStart) {
3390                mLruProcessActivityStart--;
3391            }
3392            if (lrui <= mLruProcessServiceStart) {
3393                mLruProcessServiceStart--;
3394            }
3395            mLruProcesses.remove(lrui);
3396        }
3397    }
3398
3399    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3400            ProcessRecord client) {
3401        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3402                || app.treatLikeActivity;
3403        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3404        if (!activityChange && hasActivity) {
3405            // The process has activities, so we are only allowing activity-based adjustments
3406            // to move it.  It should be kept in the front of the list with other
3407            // processes that have activities, and we don't want those to change their
3408            // order except due to activity operations.
3409            return;
3410        }
3411
3412        mLruSeq++;
3413        final long now = SystemClock.uptimeMillis();
3414        app.lastActivityTime = now;
3415
3416        // First a quick reject: if the app is already at the position we will
3417        // put it, then there is nothing to do.
3418        if (hasActivity) {
3419            final int N = mLruProcesses.size();
3420            if (N > 0 && mLruProcesses.get(N-1) == app) {
3421                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3422                return;
3423            }
3424        } else {
3425            if (mLruProcessServiceStart > 0
3426                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3427                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3428                return;
3429            }
3430        }
3431
3432        int lrui = mLruProcesses.lastIndexOf(app);
3433
3434        if (app.persistent && lrui >= 0) {
3435            // We don't care about the position of persistent processes, as long as
3436            // they are in the list.
3437            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3438            return;
3439        }
3440
3441        /* In progress: compute new position first, so we can avoid doing work
3442           if the process is not actually going to move.  Not yet working.
3443        int addIndex;
3444        int nextIndex;
3445        boolean inActivity = false, inService = false;
3446        if (hasActivity) {
3447            // Process has activities, put it at the very tipsy-top.
3448            addIndex = mLruProcesses.size();
3449            nextIndex = mLruProcessServiceStart;
3450            inActivity = true;
3451        } else if (hasService) {
3452            // Process has services, put it at the top of the service list.
3453            addIndex = mLruProcessActivityStart;
3454            nextIndex = mLruProcessServiceStart;
3455            inActivity = true;
3456            inService = true;
3457        } else  {
3458            // Process not otherwise of interest, it goes to the top of the non-service area.
3459            addIndex = mLruProcessServiceStart;
3460            if (client != null) {
3461                int clientIndex = mLruProcesses.lastIndexOf(client);
3462                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3463                        + app);
3464                if (clientIndex >= 0 && addIndex > clientIndex) {
3465                    addIndex = clientIndex;
3466                }
3467            }
3468            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3469        }
3470
3471        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3472                + mLruProcessActivityStart + "): " + app);
3473        */
3474
3475        if (lrui >= 0) {
3476            if (lrui < mLruProcessActivityStart) {
3477                mLruProcessActivityStart--;
3478            }
3479            if (lrui < mLruProcessServiceStart) {
3480                mLruProcessServiceStart--;
3481            }
3482            /*
3483            if (addIndex > lrui) {
3484                addIndex--;
3485            }
3486            if (nextIndex > lrui) {
3487                nextIndex--;
3488            }
3489            */
3490            mLruProcesses.remove(lrui);
3491        }
3492
3493        /*
3494        mLruProcesses.add(addIndex, app);
3495        if (inActivity) {
3496            mLruProcessActivityStart++;
3497        }
3498        if (inService) {
3499            mLruProcessActivityStart++;
3500        }
3501        */
3502
3503        int nextIndex;
3504        if (hasActivity) {
3505            final int N = mLruProcesses.size();
3506            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3507                // Process doesn't have activities, but has clients with
3508                // activities...  move it up, but one below the top (the top
3509                // should always have a real activity).
3510                if (DEBUG_LRU) Slog.d(TAG_LRU,
3511                        "Adding to second-top of LRU activity list: " + app);
3512                mLruProcesses.add(N - 1, app);
3513                // To keep it from spamming the LRU list (by making a bunch of clients),
3514                // we will push down any other entries owned by the app.
3515                final int uid = app.info.uid;
3516                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3517                    ProcessRecord subProc = mLruProcesses.get(i);
3518                    if (subProc.info.uid == uid) {
3519                        // We want to push this one down the list.  If the process after
3520                        // it is for the same uid, however, don't do so, because we don't
3521                        // want them internally to be re-ordered.
3522                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3523                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3524                                    "Pushing uid " + uid + " swapping at " + i + ": "
3525                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3526                            ProcessRecord tmp = mLruProcesses.get(i);
3527                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3528                            mLruProcesses.set(i - 1, tmp);
3529                            i--;
3530                        }
3531                    } else {
3532                        // A gap, we can stop here.
3533                        break;
3534                    }
3535                }
3536            } else {
3537                // Process has activities, put it at the very tipsy-top.
3538                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3539                mLruProcesses.add(app);
3540            }
3541            nextIndex = mLruProcessServiceStart;
3542        } else if (hasService) {
3543            // Process has services, put it at the top of the service list.
3544            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3545            mLruProcesses.add(mLruProcessActivityStart, app);
3546            nextIndex = mLruProcessServiceStart;
3547            mLruProcessActivityStart++;
3548        } else  {
3549            // Process not otherwise of interest, it goes to the top of the non-service area.
3550            int index = mLruProcessServiceStart;
3551            if (client != null) {
3552                // If there is a client, don't allow the process to be moved up higher
3553                // in the list than that client.
3554                int clientIndex = mLruProcesses.lastIndexOf(client);
3555                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3556                        + " when updating " + app);
3557                if (clientIndex <= lrui) {
3558                    // Don't allow the client index restriction to push it down farther in the
3559                    // list than it already is.
3560                    clientIndex = lrui;
3561                }
3562                if (clientIndex >= 0 && index > clientIndex) {
3563                    index = clientIndex;
3564                }
3565            }
3566            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3567            mLruProcesses.add(index, app);
3568            nextIndex = index-1;
3569            mLruProcessActivityStart++;
3570            mLruProcessServiceStart++;
3571        }
3572
3573        // If the app is currently using a content provider or service,
3574        // bump those processes as well.
3575        for (int j=app.connections.size()-1; j>=0; j--) {
3576            ConnectionRecord cr = app.connections.valueAt(j);
3577            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3578                    && cr.binding.service.app != null
3579                    && cr.binding.service.app.lruSeq != mLruSeq
3580                    && !cr.binding.service.app.persistent) {
3581                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3582                        "service connection", cr, app);
3583            }
3584        }
3585        for (int j=app.conProviders.size()-1; j>=0; j--) {
3586            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3587            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3588                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3589                        "provider reference", cpr, app);
3590            }
3591        }
3592    }
3593
3594    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3595        if (uid == Process.SYSTEM_UID) {
3596            // The system gets to run in any process.  If there are multiple
3597            // processes with the same uid, just pick the first (this
3598            // should never happen).
3599            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3600            if (procs == null) return null;
3601            final int procCount = procs.size();
3602            for (int i = 0; i < procCount; i++) {
3603                final int procUid = procs.keyAt(i);
3604                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3605                    // Don't use an app process or different user process for system component.
3606                    continue;
3607                }
3608                return procs.valueAt(i);
3609            }
3610        }
3611        ProcessRecord proc = mProcessNames.get(processName, uid);
3612        if (false && proc != null && !keepIfLarge
3613                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3614                && proc.lastCachedPss >= 4000) {
3615            // Turn this condition on to cause killing to happen regularly, for testing.
3616            if (proc.baseProcessTracker != null) {
3617                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3618            }
3619            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3620        } else if (proc != null && !keepIfLarge
3621                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3622                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3623            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3624            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3625                if (proc.baseProcessTracker != null) {
3626                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3627                }
3628                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3629            }
3630        }
3631        return proc;
3632    }
3633
3634    void notifyPackageUse(String packageName, int reason) {
3635        IPackageManager pm = AppGlobals.getPackageManager();
3636        try {
3637            pm.notifyPackageUse(packageName, reason);
3638        } catch (RemoteException e) {
3639        }
3640    }
3641
3642    boolean isNextTransitionForward() {
3643        int transit = mWindowManager.getPendingAppTransition();
3644        return transit == TRANSIT_ACTIVITY_OPEN
3645                || transit == TRANSIT_TASK_OPEN
3646                || transit == TRANSIT_TASK_TO_FRONT;
3647    }
3648
3649    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3650            String processName, String abiOverride, int uid, Runnable crashHandler) {
3651        synchronized(this) {
3652            ApplicationInfo info = new ApplicationInfo();
3653            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3654            // For isolated processes, the former contains the parent's uid and the latter the
3655            // actual uid of the isolated process.
3656            // In the special case introduced by this method (which is, starting an isolated
3657            // process directly from the SystemServer without an actual parent app process) the
3658            // closest thing to a parent's uid is SYSTEM_UID.
3659            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3660            // the |isolated| logic in the ProcessRecord constructor.
3661            info.uid = Process.SYSTEM_UID;
3662            info.processName = processName;
3663            info.className = entryPoint;
3664            info.packageName = "android";
3665            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3666            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3667                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3668                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3669                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3670                    crashHandler);
3671            return proc != null ? proc.pid : 0;
3672        }
3673    }
3674
3675    final ProcessRecord startProcessLocked(String processName,
3676            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3677            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3678            boolean isolated, boolean keepIfLarge) {
3679        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3680                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3681                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3682                null /* crashHandler */);
3683    }
3684
3685    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3686            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3687            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3688            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3689        long startTime = SystemClock.elapsedRealtime();
3690        ProcessRecord app;
3691        if (!isolated) {
3692            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3693            checkTime(startTime, "startProcess: after getProcessRecord");
3694
3695            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3696                // If we are in the background, then check to see if this process
3697                // is bad.  If so, we will just silently fail.
3698                if (mAppErrors.isBadProcessLocked(info)) {
3699                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3700                            + "/" + info.processName);
3701                    return null;
3702                }
3703            } else {
3704                // When the user is explicitly starting a process, then clear its
3705                // crash count so that we won't make it bad until they see at
3706                // least one crash dialog again, and make the process good again
3707                // if it had been bad.
3708                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3709                        + "/" + info.processName);
3710                mAppErrors.resetProcessCrashTimeLocked(info);
3711                if (mAppErrors.isBadProcessLocked(info)) {
3712                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3713                            UserHandle.getUserId(info.uid), info.uid,
3714                            info.processName);
3715                    mAppErrors.clearBadProcessLocked(info);
3716                    if (app != null) {
3717                        app.bad = false;
3718                    }
3719                }
3720            }
3721        } else {
3722            // If this is an isolated process, it can't re-use an existing process.
3723            app = null;
3724        }
3725
3726        // We don't have to do anything more if:
3727        // (1) There is an existing application record; and
3728        // (2) The caller doesn't think it is dead, OR there is no thread
3729        //     object attached to it so we know it couldn't have crashed; and
3730        // (3) There is a pid assigned to it, so it is either starting or
3731        //     already running.
3732        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3733                + " app=" + app + " knownToBeDead=" + knownToBeDead
3734                + " thread=" + (app != null ? app.thread : null)
3735                + " pid=" + (app != null ? app.pid : -1));
3736        if (app != null && app.pid > 0) {
3737            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3738                // We already have the app running, or are waiting for it to
3739                // come up (we have a pid but not yet its thread), so keep it.
3740                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3741                // If this is a new package in the process, add the package to the list
3742                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3743                checkTime(startTime, "startProcess: done, added package to proc");
3744                return app;
3745            }
3746
3747            // An application record is attached to a previous process,
3748            // clean it up now.
3749            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3750            checkTime(startTime, "startProcess: bad proc running, killing");
3751            killProcessGroup(app.uid, app.pid);
3752            handleAppDiedLocked(app, true, true);
3753            checkTime(startTime, "startProcess: done killing old proc");
3754        }
3755
3756        String hostingNameStr = hostingName != null
3757                ? hostingName.flattenToShortString() : null;
3758
3759        if (app == null) {
3760            checkTime(startTime, "startProcess: creating new process record");
3761            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3762            if (app == null) {
3763                Slog.w(TAG, "Failed making new process record for "
3764                        + processName + "/" + info.uid + " isolated=" + isolated);
3765                return null;
3766            }
3767            app.crashHandler = crashHandler;
3768            checkTime(startTime, "startProcess: done creating new process record");
3769        } else {
3770            // If this is a new package in the process, add the package to the list
3771            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3772            checkTime(startTime, "startProcess: added package to existing proc");
3773        }
3774
3775        // If the system is not ready yet, then hold off on starting this
3776        // process until it is.
3777        if (!mProcessesReady
3778                && !isAllowedWhileBooting(info)
3779                && !allowWhileBooting) {
3780            if (!mProcessesOnHold.contains(app)) {
3781                mProcessesOnHold.add(app);
3782            }
3783            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3784                    "System not ready, putting on hold: " + app);
3785            checkTime(startTime, "startProcess: returning with proc on hold");
3786            return app;
3787        }
3788
3789        checkTime(startTime, "startProcess: stepping in to startProcess");
3790        startProcessLocked(
3791                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3792        checkTime(startTime, "startProcess: done starting proc!");
3793        return (app.pid != 0) ? app : null;
3794    }
3795
3796    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3797        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3798    }
3799
3800    private final void startProcessLocked(ProcessRecord app,
3801            String hostingType, String hostingNameStr) {
3802        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3803                null /* entryPoint */, null /* entryPointArgs */);
3804    }
3805
3806    private final void startProcessLocked(ProcessRecord app, String hostingType,
3807            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3808        long startTime = SystemClock.elapsedRealtime();
3809        if (app.pid > 0 && app.pid != MY_PID) {
3810            checkTime(startTime, "startProcess: removing from pids map");
3811            synchronized (mPidsSelfLocked) {
3812                mPidsSelfLocked.remove(app.pid);
3813                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3814            }
3815            checkTime(startTime, "startProcess: done removing from pids map");
3816            app.setPid(0);
3817        }
3818
3819        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3820                "startProcessLocked removing on hold: " + app);
3821        mProcessesOnHold.remove(app);
3822
3823        checkTime(startTime, "startProcess: starting to update cpu stats");
3824        updateCpuStats();
3825        checkTime(startTime, "startProcess: done updating cpu stats");
3826
3827        try {
3828            try {
3829                final int userId = UserHandle.getUserId(app.uid);
3830                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3831            } catch (RemoteException e) {
3832                throw e.rethrowAsRuntimeException();
3833            }
3834
3835            int uid = app.uid;
3836            int[] gids = null;
3837            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3838            if (!app.isolated) {
3839                int[] permGids = null;
3840                try {
3841                    checkTime(startTime, "startProcess: getting gids from package manager");
3842                    final IPackageManager pm = AppGlobals.getPackageManager();
3843                    permGids = pm.getPackageGids(app.info.packageName,
3844                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3845                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3846                            StorageManagerInternal.class);
3847                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3848                            app.info.packageName);
3849                } catch (RemoteException e) {
3850                    throw e.rethrowAsRuntimeException();
3851                }
3852
3853                /*
3854                 * Add shared application and profile GIDs so applications can share some
3855                 * resources like shared libraries and access user-wide resources
3856                 */
3857                if (ArrayUtils.isEmpty(permGids)) {
3858                    gids = new int[3];
3859                } else {
3860                    gids = new int[permGids.length + 3];
3861                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3862                }
3863                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3864                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3865                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3866            }
3867            checkTime(startTime, "startProcess: building args");
3868            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3869                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3870                        && mTopComponent != null
3871                        && app.processName.equals(mTopComponent.getPackageName())) {
3872                    uid = 0;
3873                }
3874                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3875                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3876                    uid = 0;
3877                }
3878            }
3879            int debugFlags = 0;
3880            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3881                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3882                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3883                // Also turn on CheckJNI for debuggable apps. It's quite
3884                // awkward to turn on otherwise.
3885                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3886            }
3887            // Run the app in safe mode if its manifest requests so or the
3888            // system is booted in safe mode.
3889            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3890                mSafeMode == true) {
3891                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3892            }
3893            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3894                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3895            }
3896            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3897            if ("true".equals(genDebugInfoProperty)) {
3898                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3899            }
3900            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3901                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3902            }
3903            if ("1".equals(SystemProperties.get("debug.assert"))) {
3904                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3905            }
3906            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3907                // Enable all debug flags required by the native debugger.
3908                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3909                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3910                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3911                mNativeDebuggingApp = null;
3912            }
3913
3914            String invokeWith = null;
3915            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3916                // Debuggable apps may include a wrapper script with their library directory.
3917                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3918                if (new File(wrapperFileName).exists()) {
3919                    invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3920                }
3921            }
3922
3923            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3924            if (requiredAbi == null) {
3925                requiredAbi = Build.SUPPORTED_ABIS[0];
3926            }
3927
3928            String instructionSet = null;
3929            if (app.info.primaryCpuAbi != null) {
3930                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3931            }
3932
3933            app.gids = gids;
3934            app.requiredAbi = requiredAbi;
3935            app.instructionSet = instructionSet;
3936
3937            // the per-user SELinux context must be set
3938            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3939                Slog.wtf(TAG, "SELinux tag not defined",
3940                        new IllegalStateException("SELinux tag not defined"));
3941            }
3942            final String seInfo = app.info.seInfo
3943                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3944            // Start the process.  It will either succeed and return a result containing
3945            // the PID of the new process, or else throw a RuntimeException.
3946            boolean isActivityProcess = (entryPoint == null);
3947            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3948            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3949                    app.processName);
3950            checkTime(startTime, "startProcess: asking zygote to start proc");
3951            Process.ProcessStartResult startResult;
3952            if (hostingType.equals("webview_service")) {
3953                startResult = Process.startWebView(entryPoint,
3954                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3955                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3956                        app.info.dataDir, null, entryPointArgs);
3957            } else {
3958                startResult = Process.start(entryPoint,
3959                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3960                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3961                        app.info.dataDir, invokeWith, entryPointArgs);
3962            }
3963            checkTime(startTime, "startProcess: returned from zygote!");
3964            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3965
3966            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3967            checkTime(startTime, "startProcess: done updating battery stats");
3968
3969            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3970                    UserHandle.getUserId(uid), startResult.pid, uid,
3971                    app.processName, hostingType,
3972                    hostingNameStr != null ? hostingNameStr : "");
3973
3974            try {
3975                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3976                        seInfo, app.info.sourceDir, startResult.pid);
3977            } catch (RemoteException ex) {
3978                // Ignore
3979            }
3980
3981            if (app.persistent) {
3982                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3983            }
3984
3985            checkTime(startTime, "startProcess: building log message");
3986            StringBuilder buf = mStringBuilder;
3987            buf.setLength(0);
3988            buf.append("Start proc ");
3989            buf.append(startResult.pid);
3990            buf.append(':');
3991            buf.append(app.processName);
3992            buf.append('/');
3993            UserHandle.formatUid(buf, uid);
3994            if (!isActivityProcess) {
3995                buf.append(" [");
3996                buf.append(entryPoint);
3997                buf.append("]");
3998            }
3999            buf.append(" for ");
4000            buf.append(hostingType);
4001            if (hostingNameStr != null) {
4002                buf.append(" ");
4003                buf.append(hostingNameStr);
4004            }
4005            Slog.i(TAG, buf.toString());
4006            app.setPid(startResult.pid);
4007            app.usingWrapper = startResult.usingWrapper;
4008            app.removed = false;
4009            app.killed = false;
4010            app.killedByAm = false;
4011            checkTime(startTime, "startProcess: starting to update pids map");
4012            ProcessRecord oldApp;
4013            synchronized (mPidsSelfLocked) {
4014                oldApp = mPidsSelfLocked.get(startResult.pid);
4015            }
4016            // If there is already an app occupying that pid that hasn't been cleaned up
4017            if (oldApp != null && !app.isolated) {
4018                // Clean up anything relating to this pid first
4019                Slog.w(TAG, "Reusing pid " + startResult.pid
4020                        + " while app is still mapped to it");
4021                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4022                        true /*replacingPid*/);
4023            }
4024            synchronized (mPidsSelfLocked) {
4025                this.mPidsSelfLocked.put(startResult.pid, app);
4026                if (isActivityProcess) {
4027                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4028                    msg.obj = app;
4029                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4030                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4031                }
4032            }
4033            checkTime(startTime, "startProcess: done updating pids map");
4034        } catch (RuntimeException e) {
4035            Slog.e(TAG, "Failure starting process " + app.processName, e);
4036
4037            // Something went very wrong while trying to start this process; one
4038            // common case is when the package is frozen due to an active
4039            // upgrade. To recover, clean up any active bookkeeping related to
4040            // starting this process. (We already invoked this method once when
4041            // the package was initially frozen through KILL_APPLICATION_MSG, so
4042            // it doesn't hurt to use it again.)
4043            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4044                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4045        }
4046    }
4047
4048    void updateUsageStats(ActivityRecord component, boolean resumed) {
4049        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4050                "updateUsageStats: comp=" + component + "res=" + resumed);
4051        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4052        if (resumed) {
4053            if (mUsageStatsService != null) {
4054                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4055                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4056            }
4057            synchronized (stats) {
4058                stats.noteActivityResumedLocked(component.app.uid);
4059            }
4060        } else {
4061            if (mUsageStatsService != null) {
4062                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4063                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4064            }
4065            synchronized (stats) {
4066                stats.noteActivityPausedLocked(component.app.uid);
4067            }
4068        }
4069    }
4070
4071    Intent getHomeIntent() {
4072        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4073        intent.setComponent(mTopComponent);
4074        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4075        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4076            intent.addCategory(Intent.CATEGORY_HOME);
4077        }
4078        return intent;
4079    }
4080
4081    boolean startHomeActivityLocked(int userId, String reason) {
4082        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4083                && mTopAction == null) {
4084            // We are running in factory test mode, but unable to find
4085            // the factory test app, so just sit around displaying the
4086            // error message and don't try to start anything.
4087            return false;
4088        }
4089        Intent intent = getHomeIntent();
4090        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4091        if (aInfo != null) {
4092            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4093            // Don't do this if the home app is currently being
4094            // instrumented.
4095            aInfo = new ActivityInfo(aInfo);
4096            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4097            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4098                    aInfo.applicationInfo.uid, true);
4099            if (app == null || app.instr == null) {
4100                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4101                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
4102            }
4103        } else {
4104            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4105        }
4106
4107        return true;
4108    }
4109
4110    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4111        ActivityInfo ai = null;
4112        ComponentName comp = intent.getComponent();
4113        try {
4114            if (comp != null) {
4115                // Factory test.
4116                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4117            } else {
4118                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4119                        intent,
4120                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4121                        flags, userId);
4122
4123                if (info != null) {
4124                    ai = info.activityInfo;
4125                }
4126            }
4127        } catch (RemoteException e) {
4128            // ignore
4129        }
4130
4131        return ai;
4132    }
4133
4134    /**
4135     * Starts the "new version setup screen" if appropriate.
4136     */
4137    void startSetupActivityLocked() {
4138        // Only do this once per boot.
4139        if (mCheckedForSetup) {
4140            return;
4141        }
4142
4143        // We will show this screen if the current one is a different
4144        // version than the last one shown, and we are not running in
4145        // low-level factory test mode.
4146        final ContentResolver resolver = mContext.getContentResolver();
4147        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4148                Settings.Global.getInt(resolver,
4149                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4150            mCheckedForSetup = true;
4151
4152            // See if we should be showing the platform update setup UI.
4153            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4154            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4155                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4156            if (!ris.isEmpty()) {
4157                final ResolveInfo ri = ris.get(0);
4158                String vers = ri.activityInfo.metaData != null
4159                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4160                        : null;
4161                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4162                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4163                            Intent.METADATA_SETUP_VERSION);
4164                }
4165                String lastVers = Settings.Secure.getString(
4166                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4167                if (vers != null && !vers.equals(lastVers)) {
4168                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4169                    intent.setComponent(new ComponentName(
4170                            ri.activityInfo.packageName, ri.activityInfo.name));
4171                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4172                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4173                            null, 0, 0, 0, null, false, false, null, null, null);
4174                }
4175            }
4176        }
4177    }
4178
4179    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4180        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4181    }
4182
4183    void enforceNotIsolatedCaller(String caller) {
4184        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4185            throw new SecurityException("Isolated process not allowed to call " + caller);
4186        }
4187    }
4188
4189    void enforceShellRestriction(String restriction, int userHandle) {
4190        if (Binder.getCallingUid() == Process.SHELL_UID) {
4191            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4192                throw new SecurityException("Shell does not have permission to access user "
4193                        + userHandle);
4194            }
4195        }
4196    }
4197
4198    @Override
4199    public int getFrontActivityScreenCompatMode() {
4200        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4201        synchronized (this) {
4202            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4203        }
4204    }
4205
4206    @Override
4207    public void setFrontActivityScreenCompatMode(int mode) {
4208        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4209                "setFrontActivityScreenCompatMode");
4210        synchronized (this) {
4211            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4212        }
4213    }
4214
4215    @Override
4216    public int getPackageScreenCompatMode(String packageName) {
4217        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4218        synchronized (this) {
4219            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4220        }
4221    }
4222
4223    @Override
4224    public void setPackageScreenCompatMode(String packageName, int mode) {
4225        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4226                "setPackageScreenCompatMode");
4227        synchronized (this) {
4228            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4229        }
4230    }
4231
4232    @Override
4233    public boolean getPackageAskScreenCompat(String packageName) {
4234        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4235        synchronized (this) {
4236            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4237        }
4238    }
4239
4240    @Override
4241    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4242        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4243                "setPackageAskScreenCompat");
4244        synchronized (this) {
4245            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4246        }
4247    }
4248
4249    private boolean hasUsageStatsPermission(String callingPackage) {
4250        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4251                Binder.getCallingUid(), callingPackage);
4252        if (mode == AppOpsManager.MODE_DEFAULT) {
4253            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4254                    == PackageManager.PERMISSION_GRANTED;
4255        }
4256        return mode == AppOpsManager.MODE_ALLOWED;
4257    }
4258
4259    @Override
4260    public int getPackageProcessState(String packageName, String callingPackage) {
4261        if (!hasUsageStatsPermission(callingPackage)) {
4262            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4263                    "getPackageProcessState");
4264        }
4265
4266        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4267        synchronized (this) {
4268            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4269                final ProcessRecord proc = mLruProcesses.get(i);
4270                if (procState > proc.setProcState) {
4271                    if (proc.pkgList.containsKey(packageName) ||
4272                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4273                        procState = proc.setProcState;
4274                    }
4275                }
4276            }
4277        }
4278        return procState;
4279    }
4280
4281    @Override
4282    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4283            throws RemoteException {
4284        synchronized (this) {
4285            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4286            if (app == null) {
4287                throw new IllegalArgumentException("Unknown process: " + process);
4288            }
4289            if (app.thread == null) {
4290                throw new IllegalArgumentException("Process has no app thread");
4291            }
4292            if (app.trimMemoryLevel >= level) {
4293                throw new IllegalArgumentException(
4294                        "Unable to set a higher trim level than current level");
4295            }
4296            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4297                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4298                throw new IllegalArgumentException("Unable to set a background trim level "
4299                    + "on a foreground process");
4300            }
4301            app.thread.scheduleTrimMemory(level);
4302            app.trimMemoryLevel = level;
4303            return true;
4304        }
4305    }
4306
4307    private void dispatchProcessesChanged() {
4308        int N;
4309        synchronized (this) {
4310            N = mPendingProcessChanges.size();
4311            if (mActiveProcessChanges.length < N) {
4312                mActiveProcessChanges = new ProcessChangeItem[N];
4313            }
4314            mPendingProcessChanges.toArray(mActiveProcessChanges);
4315            mPendingProcessChanges.clear();
4316            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4317                    "*** Delivering " + N + " process changes");
4318        }
4319
4320        int i = mProcessObservers.beginBroadcast();
4321        while (i > 0) {
4322            i--;
4323            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4324            if (observer != null) {
4325                try {
4326                    for (int j=0; j<N; j++) {
4327                        ProcessChangeItem item = mActiveProcessChanges[j];
4328                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4329                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4330                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4331                                    + item.uid + ": " + item.foregroundActivities);
4332                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4333                                    item.foregroundActivities);
4334                        }
4335                    }
4336                } catch (RemoteException e) {
4337                }
4338            }
4339        }
4340        mProcessObservers.finishBroadcast();
4341
4342        synchronized (this) {
4343            for (int j=0; j<N; j++) {
4344                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4345            }
4346        }
4347    }
4348
4349    private void dispatchProcessDied(int pid, int uid) {
4350        int i = mProcessObservers.beginBroadcast();
4351        while (i > 0) {
4352            i--;
4353            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4354            if (observer != null) {
4355                try {
4356                    observer.onProcessDied(pid, uid);
4357                } catch (RemoteException e) {
4358                }
4359            }
4360        }
4361        mProcessObservers.finishBroadcast();
4362    }
4363
4364    @VisibleForTesting
4365    void dispatchUidsChanged() {
4366        int N;
4367        synchronized (this) {
4368            N = mPendingUidChanges.size();
4369            if (mActiveUidChanges.length < N) {
4370                mActiveUidChanges = new UidRecord.ChangeItem[N];
4371            }
4372            for (int i=0; i<N; i++) {
4373                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4374                mActiveUidChanges[i] = change;
4375                if (change.uidRecord != null) {
4376                    change.uidRecord.pendingChange = null;
4377                    change.uidRecord = null;
4378                }
4379            }
4380            mPendingUidChanges.clear();
4381            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4382                    "*** Delivering " + N + " uid changes");
4383        }
4384
4385        int i = mUidObservers.beginBroadcast();
4386        while (i > 0) {
4387            i--;
4388            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4389                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4390        }
4391        mUidObservers.finishBroadcast();
4392
4393        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4394            for (int j = 0; j < N; ++j) {
4395                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4396                if (item.change == UidRecord.CHANGE_GONE
4397                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4398                    mValidateUids.remove(item.uid);
4399                } else {
4400                    UidRecord validateUid = mValidateUids.get(item.uid);
4401                    if (validateUid == null) {
4402                        validateUid = new UidRecord(item.uid);
4403                        mValidateUids.put(item.uid, validateUid);
4404                    }
4405                    if (item.change == UidRecord.CHANGE_IDLE) {
4406                        validateUid.idle = true;
4407                    } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4408                        validateUid.idle = false;
4409                    }
4410                    validateUid.curProcState = validateUid.setProcState = item.processState;
4411                }
4412            }
4413        }
4414
4415        synchronized (this) {
4416            for (int j = 0; j < N; j++) {
4417                mAvailUidChanges.add(mActiveUidChanges[j]);
4418            }
4419        }
4420    }
4421
4422    private void dispatchUidsChangedForObserver(IUidObserver observer,
4423            UidObserverRegistration reg, int changesSize) {
4424        if (observer == null) {
4425            return;
4426        }
4427        try {
4428            for (int j = 0; j < changesSize; j++) {
4429                UidRecord.ChangeItem item = mActiveUidChanges[j];
4430                final int change = item.change;
4431                if (change == UidRecord.CHANGE_IDLE
4432                        || change == UidRecord.CHANGE_GONE_IDLE) {
4433                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4434                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4435                                "UID idle uid=" + item.uid);
4436                        observer.onUidIdle(item.uid, item.ephemeral);
4437                    }
4438                } else if (change == UidRecord.CHANGE_ACTIVE) {
4439                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4440                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4441                                "UID active uid=" + item.uid);
4442                        observer.onUidActive(item.uid);
4443                    }
4444                }
4445                if (change == UidRecord.CHANGE_GONE
4446                        || change == UidRecord.CHANGE_GONE_IDLE) {
4447                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4448                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4449                                "UID gone uid=" + item.uid);
4450                        observer.onUidGone(item.uid, item.ephemeral);
4451                    }
4452                    if (reg.lastProcStates != null) {
4453                        reg.lastProcStates.delete(item.uid);
4454                    }
4455                } else {
4456                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4457                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4458                                "UID CHANGED uid=" + item.uid
4459                                        + ": " + item.processState);
4460                        boolean doReport = true;
4461                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4462                            final int lastState = reg.lastProcStates.get(item.uid,
4463                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4464                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4465                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4466                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4467                                doReport = lastAboveCut != newAboveCut;
4468                            } else {
4469                                doReport = item.processState
4470                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4471                            }
4472                        }
4473                        if (doReport) {
4474                            if (reg.lastProcStates != null) {
4475                                reg.lastProcStates.put(item.uid, item.processState);
4476                            }
4477                            observer.onUidStateChanged(item.uid, item.processState,
4478                                    item.procStateSeq);
4479                        }
4480                    }
4481                }
4482            }
4483        } catch (RemoteException e) {
4484        }
4485    }
4486
4487    @Override
4488    public final int startActivity(IApplicationThread caller, String callingPackage,
4489            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4490            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4491        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4492                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4493                UserHandle.getCallingUserId());
4494    }
4495
4496    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4497        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4498        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4499                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4500                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4501
4502        // TODO: Switch to user app stacks here.
4503        String mimeType = intent.getType();
4504        final Uri data = intent.getData();
4505        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4506            mimeType = getProviderMimeType(data, userId);
4507        }
4508        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4509
4510        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4511        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4512                null, 0, 0, null, null, null, null, false, userId, container, null);
4513    }
4514
4515    @Override
4516    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4517            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4518            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4519        enforceNotIsolatedCaller("startActivity");
4520        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4521                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4522        // TODO: Switch to user app stacks here.
4523        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4524                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4525                profilerInfo, null, null, bOptions, false, userId, null, null);
4526    }
4527
4528    @Override
4529    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4530            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4531            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4532            int userId) {
4533
4534        // This is very dangerous -- it allows you to perform a start activity (including
4535        // permission grants) as any app that may launch one of your own activities.  So
4536        // we will only allow this to be done from activities that are part of the core framework,
4537        // and then only when they are running as the system.
4538        final ActivityRecord sourceRecord;
4539        final int targetUid;
4540        final String targetPackage;
4541        synchronized (this) {
4542            if (resultTo == null) {
4543                throw new SecurityException("Must be called from an activity");
4544            }
4545            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4546            if (sourceRecord == null) {
4547                throw new SecurityException("Called with bad activity token: " + resultTo);
4548            }
4549            if (!sourceRecord.info.packageName.equals("android")) {
4550                throw new SecurityException(
4551                        "Must be called from an activity that is declared in the android package");
4552            }
4553            if (sourceRecord.app == null) {
4554                throw new SecurityException("Called without a process attached to activity");
4555            }
4556            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4557                // This is still okay, as long as this activity is running under the
4558                // uid of the original calling activity.
4559                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4560                    throw new SecurityException(
4561                            "Calling activity in uid " + sourceRecord.app.uid
4562                                    + " must be system uid or original calling uid "
4563                                    + sourceRecord.launchedFromUid);
4564                }
4565            }
4566            if (ignoreTargetSecurity) {
4567                if (intent.getComponent() == null) {
4568                    throw new SecurityException(
4569                            "Component must be specified with ignoreTargetSecurity");
4570                }
4571                if (intent.getSelector() != null) {
4572                    throw new SecurityException(
4573                            "Selector not allowed with ignoreTargetSecurity");
4574                }
4575            }
4576            targetUid = sourceRecord.launchedFromUid;
4577            targetPackage = sourceRecord.launchedFromPackage;
4578        }
4579
4580        if (userId == UserHandle.USER_NULL) {
4581            userId = UserHandle.getUserId(sourceRecord.app.uid);
4582        }
4583
4584        // TODO: Switch to user app stacks here.
4585        try {
4586            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4587                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4588                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4589            return ret;
4590        } catch (SecurityException e) {
4591            // XXX need to figure out how to propagate to original app.
4592            // A SecurityException here is generally actually a fault of the original
4593            // calling activity (such as a fairly granting permissions), so propagate it
4594            // back to them.
4595            /*
4596            StringBuilder msg = new StringBuilder();
4597            msg.append("While launching");
4598            msg.append(intent.toString());
4599            msg.append(": ");
4600            msg.append(e.getMessage());
4601            */
4602            throw e;
4603        }
4604    }
4605
4606    @Override
4607    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4608            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4609            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4610        enforceNotIsolatedCaller("startActivityAndWait");
4611        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4612                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4613        WaitResult res = new WaitResult();
4614        // TODO: Switch to user app stacks here.
4615        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4616                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4617                bOptions, false, userId, null, null);
4618        return res;
4619    }
4620
4621    @Override
4622    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4623            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4624            int startFlags, Configuration config, Bundle bOptions, int userId) {
4625        enforceNotIsolatedCaller("startActivityWithConfig");
4626        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4627                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4628        // TODO: Switch to user app stacks here.
4629        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4630                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4631                null, null, config, bOptions, false, userId, null, null);
4632        return ret;
4633    }
4634
4635    @Override
4636    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4637            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4638            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4639            throws TransactionTooLargeException {
4640        enforceNotIsolatedCaller("startActivityIntentSender");
4641        // Refuse possible leaked file descriptors
4642        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4643            throw new IllegalArgumentException("File descriptors passed in Intent");
4644        }
4645
4646        IIntentSender sender = intent.getTarget();
4647        if (!(sender instanceof PendingIntentRecord)) {
4648            throw new IllegalArgumentException("Bad PendingIntent object");
4649        }
4650
4651        PendingIntentRecord pir = (PendingIntentRecord)sender;
4652
4653        synchronized (this) {
4654            // If this is coming from the currently resumed activity, it is
4655            // effectively saying that app switches are allowed at this point.
4656            final ActivityStack stack = getFocusedStack();
4657            if (stack.mResumedActivity != null &&
4658                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4659                mAppSwitchesAllowedTime = 0;
4660            }
4661        }
4662        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4663                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4664        return ret;
4665    }
4666
4667    @Override
4668    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4669            Intent intent, String resolvedType, IVoiceInteractionSession session,
4670            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4671            Bundle bOptions, int userId) {
4672        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4673                != PackageManager.PERMISSION_GRANTED) {
4674            String msg = "Permission Denial: startVoiceActivity() from pid="
4675                    + Binder.getCallingPid()
4676                    + ", uid=" + Binder.getCallingUid()
4677                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4678            Slog.w(TAG, msg);
4679            throw new SecurityException(msg);
4680        }
4681        if (session == null || interactor == null) {
4682            throw new NullPointerException("null session or interactor");
4683        }
4684        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4685                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4686        // TODO: Switch to user app stacks here.
4687        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4688                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4689                null, bOptions, false, userId, null, null);
4690    }
4691
4692    @Override
4693    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4694            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4695        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4696                != PackageManager.PERMISSION_GRANTED) {
4697            final String msg = "Permission Denial: startAssistantActivity() from pid="
4698                    + Binder.getCallingPid()
4699                    + ", uid=" + Binder.getCallingUid()
4700                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4701            Slog.w(TAG, msg);
4702            throw new SecurityException(msg);
4703        }
4704        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4705                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4706        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4707                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4708                userId, null, null);
4709    }
4710
4711    @Override
4712    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4713            throws RemoteException {
4714        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4715        synchronized (this) {
4716            ActivityRecord activity = getFocusedStack().topActivity();
4717            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4718                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4719            }
4720            if (mRunningVoice != null || activity.task.voiceSession != null
4721                    || activity.voiceSession != null) {
4722                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4723                return;
4724            }
4725            if (activity.pendingVoiceInteractionStart) {
4726                Slog.w(TAG, "Pending start of voice interaction already.");
4727                return;
4728            }
4729            activity.pendingVoiceInteractionStart = true;
4730        }
4731        LocalServices.getService(VoiceInteractionManagerInternal.class)
4732                .startLocalVoiceInteraction(callingActivity, options);
4733    }
4734
4735    @Override
4736    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4737        LocalServices.getService(VoiceInteractionManagerInternal.class)
4738                .stopLocalVoiceInteraction(callingActivity);
4739    }
4740
4741    @Override
4742    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4743        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4744                .supportsLocalVoiceInteraction();
4745    }
4746
4747    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4748            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4749        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4750        if (activityToCallback == null) return;
4751        activityToCallback.setVoiceSessionLocked(voiceSession);
4752
4753        // Inform the activity
4754        try {
4755            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4756                    voiceInteractor);
4757            long token = Binder.clearCallingIdentity();
4758            try {
4759                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4760            } finally {
4761                Binder.restoreCallingIdentity(token);
4762            }
4763            // TODO: VI Should we cache the activity so that it's easier to find later
4764            // rather than scan through all the stacks and activities?
4765        } catch (RemoteException re) {
4766            activityToCallback.clearVoiceSessionLocked();
4767            // TODO: VI Should this terminate the voice session?
4768        }
4769    }
4770
4771    @Override
4772    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4773        synchronized (this) {
4774            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4775                if (keepAwake) {
4776                    mVoiceWakeLock.acquire();
4777                } else {
4778                    mVoiceWakeLock.release();
4779                }
4780            }
4781        }
4782    }
4783
4784    @Override
4785    public boolean startNextMatchingActivity(IBinder callingActivity,
4786            Intent intent, Bundle bOptions) {
4787        // Refuse possible leaked file descriptors
4788        if (intent != null && intent.hasFileDescriptors() == true) {
4789            throw new IllegalArgumentException("File descriptors passed in Intent");
4790        }
4791        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4792
4793        synchronized (this) {
4794            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4795            if (r == null) {
4796                ActivityOptions.abort(options);
4797                return false;
4798            }
4799            if (r.app == null || r.app.thread == null) {
4800                // The caller is not running...  d'oh!
4801                ActivityOptions.abort(options);
4802                return false;
4803            }
4804            intent = new Intent(intent);
4805            // The caller is not allowed to change the data.
4806            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4807            // And we are resetting to find the next component...
4808            intent.setComponent(null);
4809
4810            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4811
4812            ActivityInfo aInfo = null;
4813            try {
4814                List<ResolveInfo> resolves =
4815                    AppGlobals.getPackageManager().queryIntentActivities(
4816                            intent, r.resolvedType,
4817                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4818                            UserHandle.getCallingUserId()).getList();
4819
4820                // Look for the original activity in the list...
4821                final int N = resolves != null ? resolves.size() : 0;
4822                for (int i=0; i<N; i++) {
4823                    ResolveInfo rInfo = resolves.get(i);
4824                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4825                            && rInfo.activityInfo.name.equals(r.info.name)) {
4826                        // We found the current one...  the next matching is
4827                        // after it.
4828                        i++;
4829                        if (i<N) {
4830                            aInfo = resolves.get(i).activityInfo;
4831                        }
4832                        if (debug) {
4833                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4834                                    + "/" + r.info.name);
4835                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4836                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4837                        }
4838                        break;
4839                    }
4840                }
4841            } catch (RemoteException e) {
4842            }
4843
4844            if (aInfo == null) {
4845                // Nobody who is next!
4846                ActivityOptions.abort(options);
4847                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4848                return false;
4849            }
4850
4851            intent.setComponent(new ComponentName(
4852                    aInfo.applicationInfo.packageName, aInfo.name));
4853            intent.setFlags(intent.getFlags()&~(
4854                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4855                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4856                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4857                    Intent.FLAG_ACTIVITY_NEW_TASK));
4858
4859            // Okay now we need to start the new activity, replacing the
4860            // currently running activity.  This is a little tricky because
4861            // we want to start the new one as if the current one is finished,
4862            // but not finish the current one first so that there is no flicker.
4863            // And thus...
4864            final boolean wasFinishing = r.finishing;
4865            r.finishing = true;
4866
4867            // Propagate reply information over to the new activity.
4868            final ActivityRecord resultTo = r.resultTo;
4869            final String resultWho = r.resultWho;
4870            final int requestCode = r.requestCode;
4871            r.resultTo = null;
4872            if (resultTo != null) {
4873                resultTo.removeResultsLocked(r, resultWho, requestCode);
4874            }
4875
4876            final long origId = Binder.clearCallingIdentity();
4877            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4878                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4879                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4880                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4881                    false, false, null, null, null);
4882            Binder.restoreCallingIdentity(origId);
4883
4884            r.finishing = wasFinishing;
4885            if (res != ActivityManager.START_SUCCESS) {
4886                return false;
4887            }
4888            return true;
4889        }
4890    }
4891
4892    @Override
4893    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4894        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4895            String msg = "Permission Denial: startActivityFromRecents called without " +
4896                    START_TASKS_FROM_RECENTS;
4897            Slog.w(TAG, msg);
4898            throw new SecurityException(msg);
4899        }
4900        final long origId = Binder.clearCallingIdentity();
4901        try {
4902            synchronized (this) {
4903                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4904            }
4905        } finally {
4906            Binder.restoreCallingIdentity(origId);
4907        }
4908    }
4909
4910    final int startActivityInPackage(int uid, String callingPackage,
4911            Intent intent, String resolvedType, IBinder resultTo,
4912            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4913            IActivityContainer container, TaskRecord inTask) {
4914
4915        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4916                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4917
4918        // TODO: Switch to user app stacks here.
4919        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4920                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4921                null, null, null, bOptions, false, userId, container, inTask);
4922        return ret;
4923    }
4924
4925    @Override
4926    public final int startActivities(IApplicationThread caller, String callingPackage,
4927            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4928            int userId) {
4929        enforceNotIsolatedCaller("startActivities");
4930        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4931                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4932        // TODO: Switch to user app stacks here.
4933        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4934                resolvedTypes, resultTo, bOptions, userId);
4935        return ret;
4936    }
4937
4938    final int startActivitiesInPackage(int uid, String callingPackage,
4939            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4940            Bundle bOptions, int userId) {
4941
4942        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4943                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4944        // TODO: Switch to user app stacks here.
4945        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4946                resultTo, bOptions, userId);
4947        return ret;
4948    }
4949
4950    @Override
4951    public void reportActivityFullyDrawn(IBinder token) {
4952        synchronized (this) {
4953            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4954            if (r == null) {
4955                return;
4956            }
4957            r.reportFullyDrawnLocked();
4958        }
4959    }
4960
4961    @Override
4962    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4963        synchronized (this) {
4964            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4965            if (r == null) {
4966                return;
4967            }
4968            final long origId = Binder.clearCallingIdentity();
4969            try {
4970                r.setRequestedOrientation(requestedOrientation);
4971            } finally {
4972                Binder.restoreCallingIdentity(origId);
4973            }
4974        }
4975    }
4976
4977    @Override
4978    public int getRequestedOrientation(IBinder token) {
4979        synchronized (this) {
4980            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4981            if (r == null) {
4982                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4983            }
4984            return r.getRequestedOrientation();
4985        }
4986    }
4987
4988    @Override
4989    public final void requestActivityRelaunch(IBinder token) {
4990        synchronized(this) {
4991            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4992            if (r == null) {
4993                return;
4994            }
4995            final long origId = Binder.clearCallingIdentity();
4996            try {
4997                r.forceNewConfig = true;
4998                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4999                        false /* preserveWindow */);
5000            } finally {
5001                Binder.restoreCallingIdentity(origId);
5002            }
5003        }
5004    }
5005
5006    /**
5007     * This is the internal entry point for handling Activity.finish().
5008     *
5009     * @param token The Binder token referencing the Activity we want to finish.
5010     * @param resultCode Result code, if any, from this Activity.
5011     * @param resultData Result data (Intent), if any, from this Activity.
5012     * @param finishTask Whether to finish the task associated with this Activity.
5013     *
5014     * @return Returns true if the activity successfully finished, or false if it is still running.
5015     */
5016    @Override
5017    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5018            int finishTask) {
5019        // Refuse possible leaked file descriptors
5020        if (resultData != null && resultData.hasFileDescriptors() == true) {
5021            throw new IllegalArgumentException("File descriptors passed in Intent");
5022        }
5023
5024        synchronized(this) {
5025            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5026            if (r == null) {
5027                return true;
5028            }
5029            // Keep track of the root activity of the task before we finish it
5030            TaskRecord tr = r.task;
5031            ActivityRecord rootR = tr.getRootActivity();
5032            if (rootR == null) {
5033                Slog.w(TAG, "Finishing task with all activities already finished");
5034            }
5035            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5036            // finish.
5037            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5038                    mStackSupervisor.isLastLockedTask(tr)) {
5039                Slog.i(TAG, "Not finishing task in lock task mode");
5040                mStackSupervisor.showLockTaskToast();
5041                return false;
5042            }
5043            if (mController != null) {
5044                // Find the first activity that is not finishing.
5045                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5046                if (next != null) {
5047                    // ask watcher if this is allowed
5048                    boolean resumeOK = true;
5049                    try {
5050                        resumeOK = mController.activityResuming(next.packageName);
5051                    } catch (RemoteException e) {
5052                        mController = null;
5053                        Watchdog.getInstance().setActivityController(null);
5054                    }
5055
5056                    if (!resumeOK) {
5057                        Slog.i(TAG, "Not finishing activity because controller resumed");
5058                        return false;
5059                    }
5060                }
5061            }
5062            final long origId = Binder.clearCallingIdentity();
5063            try {
5064                boolean res;
5065                final boolean finishWithRootActivity =
5066                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5067                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5068                        || (finishWithRootActivity && r == rootR)) {
5069                    // If requested, remove the task that is associated to this activity only if it
5070                    // was the root activity in the task. The result code and data is ignored
5071                    // because we don't support returning them across task boundaries. Also, to
5072                    // keep backwards compatibility we remove the task from recents when finishing
5073                    // task with root activity.
5074                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5075                    if (!res) {
5076                        Slog.i(TAG, "Removing task failed to finish activity");
5077                    }
5078                } else {
5079                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5080                            resultData, "app-request", true);
5081                    if (!res) {
5082                        Slog.i(TAG, "Failed to finish by app-request");
5083                    }
5084                }
5085                return res;
5086            } finally {
5087                Binder.restoreCallingIdentity(origId);
5088            }
5089        }
5090    }
5091
5092    @Override
5093    public final void finishHeavyWeightApp() {
5094        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5095                != PackageManager.PERMISSION_GRANTED) {
5096            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5097                    + Binder.getCallingPid()
5098                    + ", uid=" + Binder.getCallingUid()
5099                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5100            Slog.w(TAG, msg);
5101            throw new SecurityException(msg);
5102        }
5103
5104        synchronized(this) {
5105            if (mHeavyWeightProcess == null) {
5106                return;
5107            }
5108
5109            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5110            for (int i = 0; i < activities.size(); i++) {
5111                ActivityRecord r = activities.get(i);
5112                if (!r.finishing && r.isInStackLocked()) {
5113                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5114                            null, "finish-heavy", true);
5115                }
5116            }
5117
5118            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5119                    mHeavyWeightProcess.userId, 0));
5120            mHeavyWeightProcess = null;
5121        }
5122    }
5123
5124    @Override
5125    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5126            String message) {
5127        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5128                != PackageManager.PERMISSION_GRANTED) {
5129            String msg = "Permission Denial: crashApplication() from pid="
5130                    + Binder.getCallingPid()
5131                    + ", uid=" + Binder.getCallingUid()
5132                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5133            Slog.w(TAG, msg);
5134            throw new SecurityException(msg);
5135        }
5136
5137        synchronized(this) {
5138            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5139        }
5140    }
5141
5142    @Override
5143    public final void finishSubActivity(IBinder token, String resultWho,
5144            int requestCode) {
5145        synchronized(this) {
5146            final long origId = Binder.clearCallingIdentity();
5147            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5148            if (r != null) {
5149                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5150            }
5151            Binder.restoreCallingIdentity(origId);
5152        }
5153    }
5154
5155    @Override
5156    public boolean finishActivityAffinity(IBinder token) {
5157        synchronized(this) {
5158            final long origId = Binder.clearCallingIdentity();
5159            try {
5160                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5161                if (r == null) {
5162                    return false;
5163                }
5164
5165                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5166                // can finish.
5167                final TaskRecord task = r.task;
5168                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5169                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5170                    mStackSupervisor.showLockTaskToast();
5171                    return false;
5172                }
5173                return task.getStack().finishActivityAffinityLocked(r);
5174            } finally {
5175                Binder.restoreCallingIdentity(origId);
5176            }
5177        }
5178    }
5179
5180    @Override
5181    public void finishVoiceTask(IVoiceInteractionSession session) {
5182        synchronized (this) {
5183            final long origId = Binder.clearCallingIdentity();
5184            try {
5185                // TODO: VI Consider treating local voice interactions and voice tasks
5186                // differently here
5187                mStackSupervisor.finishVoiceTask(session);
5188            } finally {
5189                Binder.restoreCallingIdentity(origId);
5190            }
5191        }
5192
5193    }
5194
5195    @Override
5196    public boolean releaseActivityInstance(IBinder token) {
5197        synchronized(this) {
5198            final long origId = Binder.clearCallingIdentity();
5199            try {
5200                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5201                if (r == null) {
5202                    return false;
5203                }
5204                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5205            } finally {
5206                Binder.restoreCallingIdentity(origId);
5207            }
5208        }
5209    }
5210
5211    @Override
5212    public void releaseSomeActivities(IApplicationThread appInt) {
5213        synchronized(this) {
5214            final long origId = Binder.clearCallingIdentity();
5215            try {
5216                ProcessRecord app = getRecordForAppLocked(appInt);
5217                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5218            } finally {
5219                Binder.restoreCallingIdentity(origId);
5220            }
5221        }
5222    }
5223
5224    @Override
5225    public boolean willActivityBeVisible(IBinder token) {
5226        synchronized(this) {
5227            ActivityStack stack = ActivityRecord.getStackLocked(token);
5228            if (stack != null) {
5229                return stack.willActivityBeVisibleLocked(token);
5230            }
5231            return false;
5232        }
5233    }
5234
5235    @Override
5236    public void overridePendingTransition(IBinder token, String packageName,
5237            int enterAnim, int exitAnim) {
5238        synchronized(this) {
5239            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5240            if (self == null) {
5241                return;
5242            }
5243
5244            final long origId = Binder.clearCallingIdentity();
5245
5246            if (self.state == ActivityState.RESUMED
5247                    || self.state == ActivityState.PAUSING) {
5248                mWindowManager.overridePendingAppTransition(packageName,
5249                        enterAnim, exitAnim, null);
5250            }
5251
5252            Binder.restoreCallingIdentity(origId);
5253        }
5254    }
5255
5256    /**
5257     * Main function for removing an existing process from the activity manager
5258     * as a result of that process going away.  Clears out all connections
5259     * to the process.
5260     */
5261    private final void handleAppDiedLocked(ProcessRecord app,
5262            boolean restarting, boolean allowRestart) {
5263        int pid = app.pid;
5264        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5265                false /*replacingPid*/);
5266        if (!kept && !restarting) {
5267            removeLruProcessLocked(app);
5268            if (pid > 0) {
5269                ProcessList.remove(pid);
5270            }
5271        }
5272
5273        if (mProfileProc == app) {
5274            clearProfilerLocked();
5275        }
5276
5277        // Remove this application's activities from active lists.
5278        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5279
5280        app.activities.clear();
5281
5282        if (app.instr != null) {
5283            Slog.w(TAG, "Crash of app " + app.processName
5284                  + " running instrumentation " + app.instr.mClass);
5285            Bundle info = new Bundle();
5286            info.putString("shortMsg", "Process crashed.");
5287            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5288        }
5289
5290        mWindowManager.deferSurfaceLayout();
5291        try {
5292            if (!restarting && hasVisibleActivities
5293                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5294                // If there was nothing to resume, and we are not already restarting this process, but
5295                // there is a visible activity that is hosted by the process...  then make sure all
5296                // visible activities are running, taking care of restarting this process.
5297                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5298            }
5299        } finally {
5300            mWindowManager.continueSurfaceLayout();
5301        }
5302    }
5303
5304    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5305        IBinder threadBinder = thread.asBinder();
5306        // Find the application record.
5307        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5308            ProcessRecord rec = mLruProcesses.get(i);
5309            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5310                return i;
5311            }
5312        }
5313        return -1;
5314    }
5315
5316    final ProcessRecord getRecordForAppLocked(
5317            IApplicationThread thread) {
5318        if (thread == null) {
5319            return null;
5320        }
5321
5322        int appIndex = getLRURecordIndexForAppLocked(thread);
5323        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5324    }
5325
5326    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5327        // If there are no longer any background processes running,
5328        // and the app that died was not running instrumentation,
5329        // then tell everyone we are now low on memory.
5330        boolean haveBg = false;
5331        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5332            ProcessRecord rec = mLruProcesses.get(i);
5333            if (rec.thread != null
5334                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5335                haveBg = true;
5336                break;
5337            }
5338        }
5339
5340        if (!haveBg) {
5341            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5342            if (doReport) {
5343                long now = SystemClock.uptimeMillis();
5344                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5345                    doReport = false;
5346                } else {
5347                    mLastMemUsageReportTime = now;
5348                }
5349            }
5350            final ArrayList<ProcessMemInfo> memInfos
5351                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5352            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5353            long now = SystemClock.uptimeMillis();
5354            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5355                ProcessRecord rec = mLruProcesses.get(i);
5356                if (rec == dyingProc || rec.thread == null) {
5357                    continue;
5358                }
5359                if (doReport) {
5360                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5361                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5362                }
5363                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5364                    // The low memory report is overriding any current
5365                    // state for a GC request.  Make sure to do
5366                    // heavy/important/visible/foreground processes first.
5367                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5368                        rec.lastRequestedGc = 0;
5369                    } else {
5370                        rec.lastRequestedGc = rec.lastLowMemory;
5371                    }
5372                    rec.reportLowMemory = true;
5373                    rec.lastLowMemory = now;
5374                    mProcessesToGc.remove(rec);
5375                    addProcessToGcListLocked(rec);
5376                }
5377            }
5378            if (doReport) {
5379                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5380                mHandler.sendMessage(msg);
5381            }
5382            scheduleAppGcsLocked();
5383        }
5384    }
5385
5386    final void appDiedLocked(ProcessRecord app) {
5387       appDiedLocked(app, app.pid, app.thread, false);
5388    }
5389
5390    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5391            boolean fromBinderDied) {
5392        // First check if this ProcessRecord is actually active for the pid.
5393        synchronized (mPidsSelfLocked) {
5394            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5395            if (curProc != app) {
5396                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5397                return;
5398            }
5399        }
5400
5401        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5402        synchronized (stats) {
5403            stats.noteProcessDiedLocked(app.info.uid, pid);
5404        }
5405
5406        if (!app.killed) {
5407            if (!fromBinderDied) {
5408                Process.killProcessQuiet(pid);
5409            }
5410            killProcessGroup(app.uid, pid);
5411            app.killed = true;
5412        }
5413
5414        // Clean up already done if the process has been re-started.
5415        if (app.pid == pid && app.thread != null &&
5416                app.thread.asBinder() == thread.asBinder()) {
5417            boolean doLowMem = app.instr == null;
5418            boolean doOomAdj = doLowMem;
5419            if (!app.killedByAm) {
5420                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5421                        + ") has died");
5422                mAllowLowerMemLevel = true;
5423            } else {
5424                // Note that we always want to do oom adj to update our state with the
5425                // new number of procs.
5426                mAllowLowerMemLevel = false;
5427                doLowMem = false;
5428            }
5429            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5430            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5431                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5432            handleAppDiedLocked(app, false, true);
5433
5434            if (doOomAdj) {
5435                updateOomAdjLocked();
5436            }
5437            if (doLowMem) {
5438                doLowMemReportIfNeededLocked(app);
5439            }
5440        } else if (app.pid != pid) {
5441            // A new process has already been started.
5442            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5443                    + ") has died and restarted (pid " + app.pid + ").");
5444            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5445        } else if (DEBUG_PROCESSES) {
5446            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5447                    + thread.asBinder());
5448        }
5449    }
5450
5451    /**
5452     * If a stack trace dump file is configured, dump process stack traces.
5453     * @param clearTraces causes the dump file to be erased prior to the new
5454     *    traces being written, if true; when false, the new traces will be
5455     *    appended to any existing file content.
5456     * @param firstPids of dalvik VM processes to dump stack traces for first
5457     * @param lastPids of dalvik VM processes to dump stack traces for last
5458     * @param nativeProcs optional list of native process names to dump stack crawls
5459     * @return file containing stack traces, or null if no dump file is configured
5460     */
5461    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5462            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5463        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5464        if (tracesPath == null || tracesPath.length() == 0) {
5465            return null;
5466        }
5467
5468        File tracesFile = new File(tracesPath);
5469        try {
5470            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5471            tracesFile.createNewFile();
5472            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5473        } catch (IOException e) {
5474            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5475            return null;
5476        }
5477
5478        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5479        return tracesFile;
5480    }
5481
5482    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5483            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5484        // Use a FileObserver to detect when traces finish writing.
5485        // The order of traces is considered important to maintain for legibility.
5486        final boolean[] closed = new boolean[1];
5487        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5488            @Override
5489            public synchronized void onEvent(int event, String path) { closed[0] = true; notify(); }
5490        };
5491
5492        try {
5493            observer.startWatching();
5494
5495            // First collect all of the stacks of the most important pids.
5496            if (firstPids != null) {
5497                try {
5498                    int num = firstPids.size();
5499                    for (int i = 0; i < num; i++) {
5500                        synchronized (observer) {
5501                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5502                                    + firstPids.get(i));
5503                            final long sime = SystemClock.elapsedRealtime();
5504                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5505                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5506                            if (!closed[0]) Slog.w(TAG, "Didn't see close of " + tracesPath);
5507                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5508                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5509                        }
5510                    }
5511                } catch (InterruptedException e) {
5512                    Slog.wtf(TAG, e);
5513                }
5514            }
5515
5516            // Next collect the stacks of the native pids
5517            if (nativeProcs != null) {
5518                int[] pids = Process.getPidsForCommands(nativeProcs);
5519                if (pids != null) {
5520                    for (int pid : pids) {
5521                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5522                        final long sime = SystemClock.elapsedRealtime();
5523
5524                        Debug.dumpNativeBacktraceToFileTimeout(pid, tracesPath, 10);
5525                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5526                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5527                    }
5528                }
5529            }
5530
5531            // Lastly, measure CPU usage.
5532            if (processCpuTracker != null) {
5533                processCpuTracker.init();
5534                System.gc();
5535                processCpuTracker.update();
5536                try {
5537                    synchronized (processCpuTracker) {
5538                        processCpuTracker.wait(500); // measure over 1/2 second.
5539                    }
5540                } catch (InterruptedException e) {
5541                }
5542                processCpuTracker.update();
5543
5544                // We'll take the stack crawls of just the top apps using CPU.
5545                final int N = processCpuTracker.countWorkingStats();
5546                int numProcs = 0;
5547                for (int i=0; i<N && numProcs<5; i++) {
5548                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5549                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5550                        numProcs++;
5551                        try {
5552                            synchronized (observer) {
5553                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5554                                        + stats.pid);
5555                                final long stime = SystemClock.elapsedRealtime();
5556                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5557                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5558                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5559                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5560                            }
5561                        } catch (InterruptedException e) {
5562                            Slog.wtf(TAG, e);
5563                        }
5564                    } else if (DEBUG_ANR) {
5565                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5566                                + stats.pid);
5567                    }
5568                }
5569            }
5570        } finally {
5571            observer.stopWatching();
5572        }
5573    }
5574
5575    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5576        if (true || IS_USER_BUILD) {
5577            return;
5578        }
5579        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5580        if (tracesPath == null || tracesPath.length() == 0) {
5581            return;
5582        }
5583
5584        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5585        StrictMode.allowThreadDiskWrites();
5586        try {
5587            final File tracesFile = new File(tracesPath);
5588            final File tracesDir = tracesFile.getParentFile();
5589            final File tracesTmp = new File(tracesDir, "__tmp__");
5590            try {
5591                if (tracesFile.exists()) {
5592                    tracesTmp.delete();
5593                    tracesFile.renameTo(tracesTmp);
5594                }
5595                StringBuilder sb = new StringBuilder();
5596                Time tobj = new Time();
5597                tobj.set(System.currentTimeMillis());
5598                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5599                sb.append(": ");
5600                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5601                sb.append(" since ");
5602                sb.append(msg);
5603                FileOutputStream fos = new FileOutputStream(tracesFile);
5604                fos.write(sb.toString().getBytes());
5605                if (app == null) {
5606                    fos.write("\n*** No application process!".getBytes());
5607                }
5608                fos.close();
5609                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5610            } catch (IOException e) {
5611                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5612                return;
5613            }
5614
5615            if (app != null) {
5616                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5617                firstPids.add(app.pid);
5618                dumpStackTraces(tracesPath, firstPids, null, null, null);
5619            }
5620
5621            File lastTracesFile = null;
5622            File curTracesFile = null;
5623            for (int i=9; i>=0; i--) {
5624                String name = String.format(Locale.US, "slow%02d.txt", i);
5625                curTracesFile = new File(tracesDir, name);
5626                if (curTracesFile.exists()) {
5627                    if (lastTracesFile != null) {
5628                        curTracesFile.renameTo(lastTracesFile);
5629                    } else {
5630                        curTracesFile.delete();
5631                    }
5632                }
5633                lastTracesFile = curTracesFile;
5634            }
5635            tracesFile.renameTo(curTracesFile);
5636            if (tracesTmp.exists()) {
5637                tracesTmp.renameTo(tracesFile);
5638            }
5639        } finally {
5640            StrictMode.setThreadPolicy(oldPolicy);
5641        }
5642    }
5643
5644    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5645        if (!mLaunchWarningShown) {
5646            mLaunchWarningShown = true;
5647            mUiHandler.post(new Runnable() {
5648                @Override
5649                public void run() {
5650                    synchronized (ActivityManagerService.this) {
5651                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5652                        d.show();
5653                        mUiHandler.postDelayed(new Runnable() {
5654                            @Override
5655                            public void run() {
5656                                synchronized (ActivityManagerService.this) {
5657                                    d.dismiss();
5658                                    mLaunchWarningShown = false;
5659                                }
5660                            }
5661                        }, 4000);
5662                    }
5663                }
5664            });
5665        }
5666    }
5667
5668    @Override
5669    public boolean clearApplicationUserData(final String packageName,
5670            final IPackageDataObserver observer, int userId) {
5671        enforceNotIsolatedCaller("clearApplicationUserData");
5672        int uid = Binder.getCallingUid();
5673        int pid = Binder.getCallingPid();
5674        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5675                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5676
5677
5678        long callingId = Binder.clearCallingIdentity();
5679        try {
5680            IPackageManager pm = AppGlobals.getPackageManager();
5681            int pkgUid = -1;
5682            synchronized(this) {
5683                if (getPackageManagerInternalLocked().isPackageDataProtected(
5684                        userId, packageName)) {
5685                    throw new SecurityException(
5686                            "Cannot clear data for a protected package: " + packageName);
5687                }
5688
5689                try {
5690                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5691                } catch (RemoteException e) {
5692                }
5693                if (pkgUid == -1) {
5694                    Slog.w(TAG, "Invalid packageName: " + packageName);
5695                    if (observer != null) {
5696                        try {
5697                            observer.onRemoveCompleted(packageName, false);
5698                        } catch (RemoteException e) {
5699                            Slog.i(TAG, "Observer no longer exists.");
5700                        }
5701                    }
5702                    return false;
5703                }
5704                if (uid == pkgUid || checkComponentPermission(
5705                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5706                        pid, uid, -1, true)
5707                        == PackageManager.PERMISSION_GRANTED) {
5708                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5709                } else {
5710                    throw new SecurityException("PID " + pid + " does not have permission "
5711                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5712                                    + " of package " + packageName);
5713                }
5714
5715                // Remove all tasks match the cleared application package and user
5716                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5717                    final TaskRecord tr = mRecentTasks.get(i);
5718                    final String taskPackageName =
5719                            tr.getBaseIntent().getComponent().getPackageName();
5720                    if (tr.userId != userId) continue;
5721                    if (!taskPackageName.equals(packageName)) continue;
5722                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5723                }
5724            }
5725
5726            final int pkgUidF = pkgUid;
5727            final int userIdF = userId;
5728            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5729                @Override
5730                public void onRemoveCompleted(String packageName, boolean succeeded)
5731                        throws RemoteException {
5732                    synchronized (ActivityManagerService.this) {
5733                        finishForceStopPackageLocked(packageName, pkgUidF);
5734                    }
5735
5736                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5737                            Uri.fromParts("package", packageName, null));
5738                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5739                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5740                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5741                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5742                            null, null, 0, null, null, null, null, false, false, userIdF);
5743
5744                    if (observer != null) {
5745                        observer.onRemoveCompleted(packageName, succeeded);
5746                    }
5747                }
5748            };
5749
5750            try {
5751                // Clear application user data
5752                pm.clearApplicationUserData(packageName, localObserver, userId);
5753
5754                synchronized(this) {
5755                    // Remove all permissions granted from/to this package
5756                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5757                }
5758
5759                // Reset notification settings.
5760                INotificationManager inm = NotificationManager.getService();
5761                inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5762            } catch (RemoteException e) {
5763            }
5764        } finally {
5765            Binder.restoreCallingIdentity(callingId);
5766        }
5767        return true;
5768    }
5769
5770    @Override
5771    public void killBackgroundProcesses(final String packageName, int userId) {
5772        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5773                != PackageManager.PERMISSION_GRANTED &&
5774                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5775                        != PackageManager.PERMISSION_GRANTED) {
5776            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5777                    + Binder.getCallingPid()
5778                    + ", uid=" + Binder.getCallingUid()
5779                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5780            Slog.w(TAG, msg);
5781            throw new SecurityException(msg);
5782        }
5783
5784        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5785                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5786        long callingId = Binder.clearCallingIdentity();
5787        try {
5788            IPackageManager pm = AppGlobals.getPackageManager();
5789            synchronized(this) {
5790                int appId = -1;
5791                try {
5792                    appId = UserHandle.getAppId(
5793                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5794                } catch (RemoteException e) {
5795                }
5796                if (appId == -1) {
5797                    Slog.w(TAG, "Invalid packageName: " + packageName);
5798                    return;
5799                }
5800                killPackageProcessesLocked(packageName, appId, userId,
5801                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5802            }
5803        } finally {
5804            Binder.restoreCallingIdentity(callingId);
5805        }
5806    }
5807
5808    @Override
5809    public void killAllBackgroundProcesses() {
5810        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5811                != PackageManager.PERMISSION_GRANTED) {
5812            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5813                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5814                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5815            Slog.w(TAG, msg);
5816            throw new SecurityException(msg);
5817        }
5818
5819        final long callingId = Binder.clearCallingIdentity();
5820        try {
5821            synchronized (this) {
5822                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5823                final int NP = mProcessNames.getMap().size();
5824                for (int ip = 0; ip < NP; ip++) {
5825                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5826                    final int NA = apps.size();
5827                    for (int ia = 0; ia < NA; ia++) {
5828                        final ProcessRecord app = apps.valueAt(ia);
5829                        if (app.persistent) {
5830                            // We don't kill persistent processes.
5831                            continue;
5832                        }
5833                        if (app.removed) {
5834                            procs.add(app);
5835                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5836                            app.removed = true;
5837                            procs.add(app);
5838                        }
5839                    }
5840                }
5841
5842                final int N = procs.size();
5843                for (int i = 0; i < N; i++) {
5844                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5845                }
5846
5847                mAllowLowerMemLevel = true;
5848
5849                updateOomAdjLocked();
5850                doLowMemReportIfNeededLocked(null);
5851            }
5852        } finally {
5853            Binder.restoreCallingIdentity(callingId);
5854        }
5855    }
5856
5857    /**
5858     * Kills all background processes, except those matching any of the
5859     * specified properties.
5860     *
5861     * @param minTargetSdk the target SDK version at or above which to preserve
5862     *                     processes, or {@code -1} to ignore the target SDK
5863     * @param maxProcState the process state at or below which to preserve
5864     *                     processes, or {@code -1} to ignore the process state
5865     */
5866    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5867        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5868                != PackageManager.PERMISSION_GRANTED) {
5869            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5870                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5871                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5872            Slog.w(TAG, msg);
5873            throw new SecurityException(msg);
5874        }
5875
5876        final long callingId = Binder.clearCallingIdentity();
5877        try {
5878            synchronized (this) {
5879                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5880                final int NP = mProcessNames.getMap().size();
5881                for (int ip = 0; ip < NP; ip++) {
5882                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5883                    final int NA = apps.size();
5884                    for (int ia = 0; ia < NA; ia++) {
5885                        final ProcessRecord app = apps.valueAt(ia);
5886                        if (app.removed) {
5887                            procs.add(app);
5888                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5889                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5890                            app.removed = true;
5891                            procs.add(app);
5892                        }
5893                    }
5894                }
5895
5896                final int N = procs.size();
5897                for (int i = 0; i < N; i++) {
5898                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5899                }
5900            }
5901        } finally {
5902            Binder.restoreCallingIdentity(callingId);
5903        }
5904    }
5905
5906    @Override
5907    public void forceStopPackage(final String packageName, int userId) {
5908        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5909                != PackageManager.PERMISSION_GRANTED) {
5910            String msg = "Permission Denial: forceStopPackage() from pid="
5911                    + Binder.getCallingPid()
5912                    + ", uid=" + Binder.getCallingUid()
5913                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5914            Slog.w(TAG, msg);
5915            throw new SecurityException(msg);
5916        }
5917        final int callingPid = Binder.getCallingPid();
5918        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5919                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5920        long callingId = Binder.clearCallingIdentity();
5921        try {
5922            IPackageManager pm = AppGlobals.getPackageManager();
5923            synchronized(this) {
5924                int[] users = userId == UserHandle.USER_ALL
5925                        ? mUserController.getUsers() : new int[] { userId };
5926                for (int user : users) {
5927                    int pkgUid = -1;
5928                    try {
5929                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5930                                user);
5931                    } catch (RemoteException e) {
5932                    }
5933                    if (pkgUid == -1) {
5934                        Slog.w(TAG, "Invalid packageName: " + packageName);
5935                        continue;
5936                    }
5937                    try {
5938                        pm.setPackageStoppedState(packageName, true, user);
5939                    } catch (RemoteException e) {
5940                    } catch (IllegalArgumentException e) {
5941                        Slog.w(TAG, "Failed trying to unstop package "
5942                                + packageName + ": " + e);
5943                    }
5944                    if (mUserController.isUserRunningLocked(user, 0)) {
5945                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5946                        finishForceStopPackageLocked(packageName, pkgUid);
5947                    }
5948                }
5949            }
5950        } finally {
5951            Binder.restoreCallingIdentity(callingId);
5952        }
5953    }
5954
5955    @Override
5956    public void addPackageDependency(String packageName) {
5957        synchronized (this) {
5958            int callingPid = Binder.getCallingPid();
5959            if (callingPid == Process.myPid()) {
5960                //  Yeah, um, no.
5961                return;
5962            }
5963            ProcessRecord proc;
5964            synchronized (mPidsSelfLocked) {
5965                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5966            }
5967            if (proc != null) {
5968                if (proc.pkgDeps == null) {
5969                    proc.pkgDeps = new ArraySet<String>(1);
5970                }
5971                proc.pkgDeps.add(packageName);
5972            }
5973        }
5974    }
5975
5976    /*
5977     * The pkg name and app id have to be specified.
5978     */
5979    @Override
5980    public void killApplication(String pkg, int appId, int userId, String reason) {
5981        if (pkg == null) {
5982            return;
5983        }
5984        // Make sure the uid is valid.
5985        if (appId < 0) {
5986            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5987            return;
5988        }
5989        int callerUid = Binder.getCallingUid();
5990        // Only the system server can kill an application
5991        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5992            // Post an aysnc message to kill the application
5993            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5994            msg.arg1 = appId;
5995            msg.arg2 = userId;
5996            Bundle bundle = new Bundle();
5997            bundle.putString("pkg", pkg);
5998            bundle.putString("reason", reason);
5999            msg.obj = bundle;
6000            mHandler.sendMessage(msg);
6001        } else {
6002            throw new SecurityException(callerUid + " cannot kill pkg: " +
6003                    pkg);
6004        }
6005    }
6006
6007    @Override
6008    public void closeSystemDialogs(String reason) {
6009        enforceNotIsolatedCaller("closeSystemDialogs");
6010
6011        final int pid = Binder.getCallingPid();
6012        final int uid = Binder.getCallingUid();
6013        final long origId = Binder.clearCallingIdentity();
6014        try {
6015            synchronized (this) {
6016                // Only allow this from foreground processes, so that background
6017                // applications can't abuse it to prevent system UI from being shown.
6018                if (uid >= Process.FIRST_APPLICATION_UID) {
6019                    ProcessRecord proc;
6020                    synchronized (mPidsSelfLocked) {
6021                        proc = mPidsSelfLocked.get(pid);
6022                    }
6023                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6024                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6025                                + " from background process " + proc);
6026                        return;
6027                    }
6028                }
6029                closeSystemDialogsLocked(reason);
6030            }
6031        } finally {
6032            Binder.restoreCallingIdentity(origId);
6033        }
6034    }
6035
6036    void closeSystemDialogsLocked(String reason) {
6037        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6038        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6039                | Intent.FLAG_RECEIVER_FOREGROUND);
6040        if (reason != null) {
6041            intent.putExtra("reason", reason);
6042        }
6043        mWindowManager.closeSystemDialogs(reason);
6044
6045        mStackSupervisor.closeSystemDialogsLocked();
6046
6047        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6048                AppOpsManager.OP_NONE, null, false, false,
6049                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
6050    }
6051
6052    @Override
6053    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6054        enforceNotIsolatedCaller("getProcessMemoryInfo");
6055        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6056        for (int i=pids.length-1; i>=0; i--) {
6057            ProcessRecord proc;
6058            int oomAdj;
6059            synchronized (this) {
6060                synchronized (mPidsSelfLocked) {
6061                    proc = mPidsSelfLocked.get(pids[i]);
6062                    oomAdj = proc != null ? proc.setAdj : 0;
6063                }
6064            }
6065            infos[i] = new Debug.MemoryInfo();
6066            Debug.getMemoryInfo(pids[i], infos[i]);
6067            if (proc != null) {
6068                synchronized (this) {
6069                    if (proc.thread != null && proc.setAdj == oomAdj) {
6070                        // Record this for posterity if the process has been stable.
6071                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6072                                infos[i].getTotalUss(), false, proc.pkgList);
6073                    }
6074                }
6075            }
6076        }
6077        return infos;
6078    }
6079
6080    @Override
6081    public long[] getProcessPss(int[] pids) {
6082        enforceNotIsolatedCaller("getProcessPss");
6083        long[] pss = new long[pids.length];
6084        for (int i=pids.length-1; i>=0; i--) {
6085            ProcessRecord proc;
6086            int oomAdj;
6087            synchronized (this) {
6088                synchronized (mPidsSelfLocked) {
6089                    proc = mPidsSelfLocked.get(pids[i]);
6090                    oomAdj = proc != null ? proc.setAdj : 0;
6091                }
6092            }
6093            long[] tmpUss = new long[1];
6094            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6095            if (proc != null) {
6096                synchronized (this) {
6097                    if (proc.thread != null && proc.setAdj == oomAdj) {
6098                        // Record this for posterity if the process has been stable.
6099                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6100                    }
6101                }
6102            }
6103        }
6104        return pss;
6105    }
6106
6107    @Override
6108    public void killApplicationProcess(String processName, int uid) {
6109        if (processName == null) {
6110            return;
6111        }
6112
6113        int callerUid = Binder.getCallingUid();
6114        // Only the system server can kill an application
6115        if (callerUid == Process.SYSTEM_UID) {
6116            synchronized (this) {
6117                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6118                if (app != null && app.thread != null) {
6119                    try {
6120                        app.thread.scheduleSuicide();
6121                    } catch (RemoteException e) {
6122                        // If the other end already died, then our work here is done.
6123                    }
6124                } else {
6125                    Slog.w(TAG, "Process/uid not found attempting kill of "
6126                            + processName + " / " + uid);
6127                }
6128            }
6129        } else {
6130            throw new SecurityException(callerUid + " cannot kill app process: " +
6131                    processName);
6132        }
6133    }
6134
6135    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6136        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6137                false, true, false, false, UserHandle.getUserId(uid), reason);
6138    }
6139
6140    private void finishForceStopPackageLocked(final String packageName, int uid) {
6141        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6142                Uri.fromParts("package", packageName, null));
6143        if (!mProcessesReady) {
6144            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6145                    | Intent.FLAG_RECEIVER_FOREGROUND);
6146        }
6147        intent.putExtra(Intent.EXTRA_UID, uid);
6148        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6149        broadcastIntentLocked(null, null, intent,
6150                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6151                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
6152    }
6153
6154
6155    private final boolean killPackageProcessesLocked(String packageName, int appId,
6156            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6157            boolean doit, boolean evenPersistent, String reason) {
6158        ArrayList<ProcessRecord> procs = new ArrayList<>();
6159
6160        // Remove all processes this package may have touched: all with the
6161        // same UID (except for the system or root user), and all whose name
6162        // matches the package name.
6163        final int NP = mProcessNames.getMap().size();
6164        for (int ip=0; ip<NP; ip++) {
6165            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6166            final int NA = apps.size();
6167            for (int ia=0; ia<NA; ia++) {
6168                ProcessRecord app = apps.valueAt(ia);
6169                if (app.persistent && !evenPersistent) {
6170                    // we don't kill persistent processes
6171                    continue;
6172                }
6173                if (app.removed) {
6174                    if (doit) {
6175                        procs.add(app);
6176                    }
6177                    continue;
6178                }
6179
6180                // Skip process if it doesn't meet our oom adj requirement.
6181                if (app.setAdj < minOomAdj) {
6182                    continue;
6183                }
6184
6185                // If no package is specified, we call all processes under the
6186                // give user id.
6187                if (packageName == null) {
6188                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6189                        continue;
6190                    }
6191                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6192                        continue;
6193                    }
6194                // Package has been specified, we want to hit all processes
6195                // that match it.  We need to qualify this by the processes
6196                // that are running under the specified app and user ID.
6197                } else {
6198                    final boolean isDep = app.pkgDeps != null
6199                            && app.pkgDeps.contains(packageName);
6200                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6201                        continue;
6202                    }
6203                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6204                        continue;
6205                    }
6206                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6207                        continue;
6208                    }
6209                }
6210
6211                // Process has passed all conditions, kill it!
6212                if (!doit) {
6213                    return true;
6214                }
6215                app.removed = true;
6216                procs.add(app);
6217            }
6218        }
6219
6220        int N = procs.size();
6221        for (int i=0; i<N; i++) {
6222            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6223        }
6224        updateOomAdjLocked();
6225        return N > 0;
6226    }
6227
6228    private void cleanupDisabledPackageComponentsLocked(
6229            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6230
6231        Set<String> disabledClasses = null;
6232        boolean packageDisabled = false;
6233        IPackageManager pm = AppGlobals.getPackageManager();
6234
6235        if (changedClasses == null) {
6236            // Nothing changed...
6237            return;
6238        }
6239
6240        // Determine enable/disable state of the package and its components.
6241        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6242        for (int i = changedClasses.length - 1; i >= 0; i--) {
6243            final String changedClass = changedClasses[i];
6244
6245            if (changedClass.equals(packageName)) {
6246                try {
6247                    // Entire package setting changed
6248                    enabled = pm.getApplicationEnabledSetting(packageName,
6249                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6250                } catch (Exception e) {
6251                    // No such package/component; probably racing with uninstall.  In any
6252                    // event it means we have nothing further to do here.
6253                    return;
6254                }
6255                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6256                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6257                if (packageDisabled) {
6258                    // Entire package is disabled.
6259                    // No need to continue to check component states.
6260                    disabledClasses = null;
6261                    break;
6262                }
6263            } else {
6264                try {
6265                    enabled = pm.getComponentEnabledSetting(
6266                            new ComponentName(packageName, changedClass),
6267                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6268                } catch (Exception e) {
6269                    // As above, probably racing with uninstall.
6270                    return;
6271                }
6272                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6273                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6274                    if (disabledClasses == null) {
6275                        disabledClasses = new ArraySet<>(changedClasses.length);
6276                    }
6277                    disabledClasses.add(changedClass);
6278                }
6279            }
6280        }
6281
6282        if (!packageDisabled && disabledClasses == null) {
6283            // Nothing to do here...
6284            return;
6285        }
6286
6287        // Clean-up disabled activities.
6288        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6289                packageName, disabledClasses, true, false, userId) && mBooted) {
6290            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6291            mStackSupervisor.scheduleIdleLocked();
6292        }
6293
6294        // Clean-up disabled tasks
6295        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6296
6297        // Clean-up disabled services.
6298        mServices.bringDownDisabledPackageServicesLocked(
6299                packageName, disabledClasses, userId, false, killProcess, true);
6300
6301        // Clean-up disabled providers.
6302        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6303        mProviderMap.collectPackageProvidersLocked(
6304                packageName, disabledClasses, true, false, userId, providers);
6305        for (int i = providers.size() - 1; i >= 0; i--) {
6306            removeDyingProviderLocked(null, providers.get(i), true);
6307        }
6308
6309        // Clean-up disabled broadcast receivers.
6310        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6311            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6312                    packageName, disabledClasses, userId, true);
6313        }
6314
6315    }
6316
6317    final boolean clearBroadcastQueueForUserLocked(int userId) {
6318        boolean didSomething = false;
6319        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6320            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6321                    null, null, userId, true);
6322        }
6323        return didSomething;
6324    }
6325
6326    final boolean forceStopPackageLocked(String packageName, int appId,
6327            boolean callerWillRestart, boolean purgeCache, boolean doit,
6328            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6329        int i;
6330
6331        if (userId == UserHandle.USER_ALL && packageName == null) {
6332            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6333        }
6334
6335        if (appId < 0 && packageName != null) {
6336            try {
6337                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6338                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6339            } catch (RemoteException e) {
6340            }
6341        }
6342
6343        if (doit) {
6344            if (packageName != null) {
6345                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6346                        + " user=" + userId + ": " + reason);
6347            } else {
6348                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6349            }
6350
6351            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6352        }
6353
6354        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6355                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6356                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6357
6358        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6359
6360        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6361                packageName, null, doit, evenPersistent, userId)) {
6362            if (!doit) {
6363                return true;
6364            }
6365            didSomething = true;
6366        }
6367
6368        if (mServices.bringDownDisabledPackageServicesLocked(
6369                packageName, null, userId, evenPersistent, true, doit)) {
6370            if (!doit) {
6371                return true;
6372            }
6373            didSomething = true;
6374        }
6375
6376        if (packageName == null) {
6377            // Remove all sticky broadcasts from this user.
6378            mStickyBroadcasts.remove(userId);
6379        }
6380
6381        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6382        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6383                userId, providers)) {
6384            if (!doit) {
6385                return true;
6386            }
6387            didSomething = true;
6388        }
6389        for (i = providers.size() - 1; i >= 0; i--) {
6390            removeDyingProviderLocked(null, providers.get(i), true);
6391        }
6392
6393        // Remove transient permissions granted from/to this package/user
6394        removeUriPermissionsForPackageLocked(packageName, userId, false);
6395
6396        if (doit) {
6397            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6398                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6399                        packageName, null, userId, doit);
6400            }
6401        }
6402
6403        if (packageName == null || uninstalling) {
6404            // Remove pending intents.  For now we only do this when force
6405            // stopping users, because we have some problems when doing this
6406            // for packages -- app widgets are not currently cleaned up for
6407            // such packages, so they can be left with bad pending intents.
6408            if (mIntentSenderRecords.size() > 0) {
6409                Iterator<WeakReference<PendingIntentRecord>> it
6410                        = mIntentSenderRecords.values().iterator();
6411                while (it.hasNext()) {
6412                    WeakReference<PendingIntentRecord> wpir = it.next();
6413                    if (wpir == null) {
6414                        it.remove();
6415                        continue;
6416                    }
6417                    PendingIntentRecord pir = wpir.get();
6418                    if (pir == null) {
6419                        it.remove();
6420                        continue;
6421                    }
6422                    if (packageName == null) {
6423                        // Stopping user, remove all objects for the user.
6424                        if (pir.key.userId != userId) {
6425                            // Not the same user, skip it.
6426                            continue;
6427                        }
6428                    } else {
6429                        if (UserHandle.getAppId(pir.uid) != appId) {
6430                            // Different app id, skip it.
6431                            continue;
6432                        }
6433                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6434                            // Different user, skip it.
6435                            continue;
6436                        }
6437                        if (!pir.key.packageName.equals(packageName)) {
6438                            // Different package, skip it.
6439                            continue;
6440                        }
6441                    }
6442                    if (!doit) {
6443                        return true;
6444                    }
6445                    didSomething = true;
6446                    it.remove();
6447                    pir.canceled = true;
6448                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6449                        pir.key.activity.pendingResults.remove(pir.ref);
6450                    }
6451                }
6452            }
6453        }
6454
6455        if (doit) {
6456            if (purgeCache && packageName != null) {
6457                AttributeCache ac = AttributeCache.instance();
6458                if (ac != null) {
6459                    ac.removePackage(packageName);
6460                }
6461            }
6462            if (mBooted) {
6463                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6464                mStackSupervisor.scheduleIdleLocked();
6465            }
6466        }
6467
6468        return didSomething;
6469    }
6470
6471    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6472        return removeProcessNameLocked(name, uid, null);
6473    }
6474
6475    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6476            final ProcessRecord expecting) {
6477        ProcessRecord old = mProcessNames.get(name, uid);
6478        // Only actually remove when the currently recorded value matches the
6479        // record that we expected; if it doesn't match then we raced with a
6480        // newly created process and we don't want to destroy the new one.
6481        if ((expecting == null) || (old == expecting)) {
6482            mProcessNames.remove(name, uid);
6483        }
6484        if (old != null && old.uidRecord != null) {
6485            old.uidRecord.numProcs--;
6486            if (old.uidRecord.numProcs == 0) {
6487                // No more processes using this uid, tell clients it is gone.
6488                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6489                        "No more processes in " + old.uidRecord);
6490                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6491                mActiveUids.remove(uid);
6492                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6493            }
6494            old.uidRecord = null;
6495        }
6496        mIsolatedProcesses.remove(uid);
6497        return old;
6498    }
6499
6500    private final void addProcessNameLocked(ProcessRecord proc) {
6501        // We shouldn't already have a process under this name, but just in case we
6502        // need to clean up whatever may be there now.
6503        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6504        if (old == proc && proc.persistent) {
6505            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6506            Slog.w(TAG, "Re-adding persistent process " + proc);
6507        } else if (old != null) {
6508            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6509        }
6510        UidRecord uidRec = mActiveUids.get(proc.uid);
6511        if (uidRec == null) {
6512            uidRec = new UidRecord(proc.uid);
6513            // This is the first appearance of the uid, report it now!
6514            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6515                    "Creating new process uid: " + uidRec);
6516            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0) {
6517                uidRec.setWhitelist = uidRec.curWhitelist = true;
6518            }
6519            mActiveUids.put(proc.uid, uidRec);
6520            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6521            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6522        }
6523        proc.uidRecord = uidRec;
6524
6525        // Reset render thread tid if it was already set, so new process can set it again.
6526        proc.renderThreadTid = 0;
6527        uidRec.numProcs++;
6528        mProcessNames.put(proc.processName, proc.uid, proc);
6529        if (proc.isolated) {
6530            mIsolatedProcesses.put(proc.uid, proc);
6531        }
6532    }
6533
6534    boolean removeProcessLocked(ProcessRecord app,
6535            boolean callerWillRestart, boolean allowRestart, String reason) {
6536        final String name = app.processName;
6537        final int uid = app.uid;
6538        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6539            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6540
6541        ProcessRecord old = mProcessNames.get(name, uid);
6542        if (old != app) {
6543            // This process is no longer active, so nothing to do.
6544            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6545            return false;
6546        }
6547        removeProcessNameLocked(name, uid);
6548        if (mHeavyWeightProcess == app) {
6549            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6550                    mHeavyWeightProcess.userId, 0));
6551            mHeavyWeightProcess = null;
6552        }
6553        boolean needRestart = false;
6554        if (app.pid > 0 && app.pid != MY_PID) {
6555            int pid = app.pid;
6556            synchronized (mPidsSelfLocked) {
6557                mPidsSelfLocked.remove(pid);
6558                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6559            }
6560            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6561            if (app.isolated) {
6562                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6563            }
6564            boolean willRestart = false;
6565            if (app.persistent && !app.isolated) {
6566                if (!callerWillRestart) {
6567                    willRestart = true;
6568                } else {
6569                    needRestart = true;
6570                }
6571            }
6572            app.kill(reason, true);
6573            handleAppDiedLocked(app, willRestart, allowRestart);
6574            if (willRestart) {
6575                removeLruProcessLocked(app);
6576                addAppLocked(app.info, null, false, null /* ABI override */);
6577            }
6578        } else {
6579            mRemovedProcesses.add(app);
6580        }
6581
6582        return needRestart;
6583    }
6584
6585    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6586        cleanupAppInLaunchingProvidersLocked(app, true);
6587        removeProcessLocked(app, false, true, "timeout publishing content providers");
6588    }
6589
6590    private final void processStartTimedOutLocked(ProcessRecord app) {
6591        final int pid = app.pid;
6592        boolean gone = false;
6593        synchronized (mPidsSelfLocked) {
6594            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6595            if (knownApp != null && knownApp.thread == null) {
6596                mPidsSelfLocked.remove(pid);
6597                gone = true;
6598            }
6599        }
6600
6601        if (gone) {
6602            Slog.w(TAG, "Process " + app + " failed to attach");
6603            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6604                    pid, app.uid, app.processName);
6605            removeProcessNameLocked(app.processName, app.uid);
6606            if (mHeavyWeightProcess == app) {
6607                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6608                        mHeavyWeightProcess.userId, 0));
6609                mHeavyWeightProcess = null;
6610            }
6611            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6612            if (app.isolated) {
6613                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6614            }
6615            // Take care of any launching providers waiting for this process.
6616            cleanupAppInLaunchingProvidersLocked(app, true);
6617            // Take care of any services that are waiting for the process.
6618            mServices.processStartTimedOutLocked(app);
6619            app.kill("start timeout", true);
6620            removeLruProcessLocked(app);
6621            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6622                Slog.w(TAG, "Unattached app died before backup, skipping");
6623                mHandler.post(new Runnable() {
6624                @Override
6625                    public void run(){
6626                        try {
6627                            IBackupManager bm = IBackupManager.Stub.asInterface(
6628                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6629                            bm.agentDisconnected(app.info.packageName);
6630                        } catch (RemoteException e) {
6631                            // Can't happen; the backup manager is local
6632                        }
6633                    }
6634                });
6635            }
6636            if (isPendingBroadcastProcessLocked(pid)) {
6637                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6638                skipPendingBroadcastLocked(pid);
6639            }
6640        } else {
6641            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6642        }
6643    }
6644
6645    private final boolean attachApplicationLocked(IApplicationThread thread,
6646            int pid) {
6647
6648        // Find the application record that is being attached...  either via
6649        // the pid if we are running in multiple processes, or just pull the
6650        // next app record if we are emulating process with anonymous threads.
6651        ProcessRecord app;
6652        long startTime = SystemClock.uptimeMillis();
6653        if (pid != MY_PID && pid >= 0) {
6654            synchronized (mPidsSelfLocked) {
6655                app = mPidsSelfLocked.get(pid);
6656            }
6657        } else {
6658            app = null;
6659        }
6660
6661        if (app == null) {
6662            Slog.w(TAG, "No pending application record for pid " + pid
6663                    + " (IApplicationThread " + thread + "); dropping process");
6664            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6665            if (pid > 0 && pid != MY_PID) {
6666                Process.killProcessQuiet(pid);
6667                //TODO: killProcessGroup(app.info.uid, pid);
6668            } else {
6669                try {
6670                    thread.scheduleExit();
6671                } catch (Exception e) {
6672                    // Ignore exceptions.
6673                }
6674            }
6675            return false;
6676        }
6677
6678        // If this application record is still attached to a previous
6679        // process, clean it up now.
6680        if (app.thread != null) {
6681            handleAppDiedLocked(app, true, true);
6682        }
6683
6684        // Tell the process all about itself.
6685
6686        if (DEBUG_ALL) Slog.v(
6687                TAG, "Binding process pid " + pid + " to record " + app);
6688
6689        final String processName = app.processName;
6690        try {
6691            AppDeathRecipient adr = new AppDeathRecipient(
6692                    app, pid, thread);
6693            thread.asBinder().linkToDeath(adr, 0);
6694            app.deathRecipient = adr;
6695        } catch (RemoteException e) {
6696            app.resetPackageList(mProcessStats);
6697            startProcessLocked(app, "link fail", processName);
6698            return false;
6699        }
6700
6701        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6702
6703        app.makeActive(thread, mProcessStats);
6704        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6705        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6706        app.forcingToForeground = null;
6707        updateProcessForegroundLocked(app, false, false);
6708        app.hasShownUi = false;
6709        app.debugging = false;
6710        app.cached = false;
6711        app.killedByAm = false;
6712        app.killed = false;
6713
6714
6715        // We carefully use the same state that PackageManager uses for
6716        // filtering, since we use this flag to decide if we need to install
6717        // providers when user is unlocked later
6718        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6719
6720        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6721
6722        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6723        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6724
6725        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6726            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6727            msg.obj = app;
6728            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6729        }
6730
6731        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6732
6733        if (!normalMode) {
6734            Slog.i(TAG, "Launching preboot mode app: " + app);
6735        }
6736
6737        if (DEBUG_ALL) Slog.v(
6738            TAG, "New app record " + app
6739            + " thread=" + thread.asBinder() + " pid=" + pid);
6740        try {
6741            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6742            if (mDebugApp != null && mDebugApp.equals(processName)) {
6743                testMode = mWaitForDebugger
6744                    ? ApplicationThreadConstants.DEBUG_WAIT
6745                    : ApplicationThreadConstants.DEBUG_ON;
6746                app.debugging = true;
6747                if (mDebugTransient) {
6748                    mDebugApp = mOrigDebugApp;
6749                    mWaitForDebugger = mOrigWaitForDebugger;
6750                }
6751            }
6752            String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6753            ParcelFileDescriptor profileFd = null;
6754            int samplingInterval = 0;
6755            boolean profileAutoStop = false;
6756            boolean profileStreamingOutput = false;
6757            if (mProfileApp != null && mProfileApp.equals(processName)) {
6758                mProfileProc = app;
6759                profileFile = mProfileFile;
6760                profileFd = mProfileFd;
6761                samplingInterval = mSamplingInterval;
6762                profileAutoStop = mAutoStopProfiler;
6763                profileStreamingOutput = mStreamingOutput;
6764            }
6765            boolean enableTrackAllocation = false;
6766            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6767                enableTrackAllocation = true;
6768                mTrackAllocationApp = null;
6769            }
6770
6771            // If the app is being launched for restore or full backup, set it up specially
6772            boolean isRestrictedBackupMode = false;
6773            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6774                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6775                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6776                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6777                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6778            }
6779
6780            if (app.instr != null) {
6781                notifyPackageUse(app.instr.mClass.getPackageName(),
6782                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6783            }
6784            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6785                    + processName + " with config " + getGlobalConfiguration());
6786            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6787            app.compat = compatibilityInfoForPackageLocked(appInfo);
6788            if (profileFd != null) {
6789                profileFd = profileFd.dup();
6790            }
6791            ProfilerInfo profilerInfo = profileFile == null ? null
6792                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6793                                       profileStreamingOutput);
6794
6795            // We deprecated Build.SERIAL and it is not accessible to
6796            // apps that target the v2 security sandbox. Since access to
6797            // the serial is now behind a permission we push down the value.
6798            String buildSerial = Build.UNKNOWN;
6799            if (appInfo.targetSandboxVersion != 2) {
6800                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6801                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6802                        .getSerial();
6803            }
6804
6805            // Check if this is a secondary process that should be incorporated into some
6806            // currently active instrumentation.  (Note we do this AFTER all of the profiling
6807            // stuff above because profiling can currently happen only in the primary
6808            // instrumentation process.)
6809            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6810                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6811                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6812                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6813                        if (aInstr.mTargetProcesses.length == 0) {
6814                            // This is the wildcard mode, where every process brought up for
6815                            // the target instrumentation should be included.
6816                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6817                                app.instr = aInstr;
6818                                aInstr.mRunningProcesses.add(app);
6819                            }
6820                        } else {
6821                            for (String proc : aInstr.mTargetProcesses) {
6822                                if (proc.equals(app.processName)) {
6823                                    app.instr = aInstr;
6824                                    aInstr.mRunningProcesses.add(app);
6825                                    break;
6826                                }
6827                            }
6828                        }
6829                    }
6830                }
6831            }
6832
6833            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6834            if (app.instr != null) {
6835                thread.bindApplication(processName, appInfo, providers,
6836                        app.instr.mClass,
6837                        profilerInfo, app.instr.mArguments,
6838                        app.instr.mWatcher,
6839                        app.instr.mUiAutomationConnection, testMode,
6840                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6841                        isRestrictedBackupMode || !normalMode, app.persistent,
6842                        new Configuration(getGlobalConfiguration()), app.compat,
6843                        getCommonServicesLocked(app.isolated),
6844                        mCoreSettingsObserver.getCoreSettingsLocked(),
6845                        buildSerial);
6846            } else {
6847                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6848                        null, null, null, testMode,
6849                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6850                        isRestrictedBackupMode || !normalMode, app.persistent,
6851                        new Configuration(getGlobalConfiguration()), app.compat,
6852                        getCommonServicesLocked(app.isolated),
6853                        mCoreSettingsObserver.getCoreSettingsLocked(),
6854                        buildSerial);
6855            }
6856
6857            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6858            updateLruProcessLocked(app, false, null);
6859            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6860            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6861        } catch (Exception e) {
6862            // todo: Yikes!  What should we do?  For now we will try to
6863            // start another process, but that could easily get us in
6864            // an infinite loop of restarting processes...
6865            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6866
6867            app.resetPackageList(mProcessStats);
6868            app.unlinkDeathRecipient();
6869            startProcessLocked(app, "bind fail", processName);
6870            return false;
6871        }
6872
6873        // Remove this record from the list of starting applications.
6874        mPersistentStartingProcesses.remove(app);
6875        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6876                "Attach application locked removing on hold: " + app);
6877        mProcessesOnHold.remove(app);
6878
6879        boolean badApp = false;
6880        boolean didSomething = false;
6881
6882        // See if the top visible activity is waiting to run in this process...
6883        if (normalMode) {
6884            try {
6885                if (mStackSupervisor.attachApplicationLocked(app)) {
6886                    didSomething = true;
6887                }
6888            } catch (Exception e) {
6889                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6890                badApp = true;
6891            }
6892        }
6893
6894        // Find any services that should be running in this process...
6895        if (!badApp) {
6896            try {
6897                didSomething |= mServices.attachApplicationLocked(app, processName);
6898                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6899            } catch (Exception e) {
6900                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6901                badApp = true;
6902            }
6903        }
6904
6905        // Check if a next-broadcast receiver is in this process...
6906        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6907            try {
6908                didSomething |= sendPendingBroadcastsLocked(app);
6909                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6910            } catch (Exception e) {
6911                // If the app died trying to launch the receiver we declare it 'bad'
6912                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6913                badApp = true;
6914            }
6915        }
6916
6917        // Check whether the next backup agent is in this process...
6918        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6919            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6920                    "New app is backup target, launching agent for " + app);
6921            notifyPackageUse(mBackupTarget.appInfo.packageName,
6922                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6923            try {
6924                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6925                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6926                        mBackupTarget.backupMode);
6927            } catch (Exception e) {
6928                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6929                badApp = true;
6930            }
6931        }
6932
6933        if (badApp) {
6934            app.kill("error during init", true);
6935            handleAppDiedLocked(app, false, true);
6936            return false;
6937        }
6938
6939        if (!didSomething) {
6940            updateOomAdjLocked();
6941            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6942        }
6943
6944        return true;
6945    }
6946
6947    @Override
6948    public final void attachApplication(IApplicationThread thread) {
6949        synchronized (this) {
6950            int callingPid = Binder.getCallingPid();
6951            final long origId = Binder.clearCallingIdentity();
6952            attachApplicationLocked(thread, callingPid);
6953            Binder.restoreCallingIdentity(origId);
6954        }
6955    }
6956
6957    @Override
6958    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6959        final long origId = Binder.clearCallingIdentity();
6960        synchronized (this) {
6961            ActivityStack stack = ActivityRecord.getStackLocked(token);
6962            if (stack != null) {
6963                ActivityRecord r =
6964                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
6965                                false /* processPausingActivities */, config);
6966                if (stopProfiling) {
6967                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6968                        try {
6969                            mProfileFd.close();
6970                        } catch (IOException e) {
6971                        }
6972                        clearProfilerLocked();
6973                    }
6974                }
6975            }
6976        }
6977        Binder.restoreCallingIdentity(origId);
6978    }
6979
6980    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6981        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6982                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6983    }
6984
6985    void enableScreenAfterBoot() {
6986        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6987                SystemClock.uptimeMillis());
6988        mWindowManager.enableScreenAfterBoot();
6989
6990        synchronized (this) {
6991            updateEventDispatchingLocked();
6992        }
6993    }
6994
6995    @Override
6996    public void showBootMessage(final CharSequence msg, final boolean always) {
6997        if (Binder.getCallingUid() != Process.myUid()) {
6998            throw new SecurityException();
6999        }
7000        mWindowManager.showBootMessage(msg, always);
7001    }
7002
7003    @Override
7004    public void keyguardGoingAway(int flags) {
7005        enforceNotIsolatedCaller("keyguardGoingAway");
7006        final long token = Binder.clearCallingIdentity();
7007        try {
7008            synchronized (this) {
7009                mKeyguardController.keyguardGoingAway(flags);
7010            }
7011        } finally {
7012            Binder.restoreCallingIdentity(token);
7013        }
7014    }
7015
7016    /**
7017     * @return whther the keyguard is currently locked.
7018     */
7019    boolean isKeyguardLocked() {
7020        return mKeyguardController.isKeyguardLocked();
7021    }
7022
7023    final void finishBooting() {
7024        synchronized (this) {
7025            if (!mBootAnimationComplete) {
7026                mCallFinishBooting = true;
7027                return;
7028            }
7029            mCallFinishBooting = false;
7030        }
7031
7032        ArraySet<String> completedIsas = new ArraySet<String>();
7033        for (String abi : Build.SUPPORTED_ABIS) {
7034            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
7035            final String instructionSet = VMRuntime.getInstructionSet(abi);
7036            if (!completedIsas.contains(instructionSet)) {
7037                try {
7038                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7039                } catch (InstallerException e) {
7040                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7041                            e.getMessage() +")");
7042                }
7043                completedIsas.add(instructionSet);
7044            }
7045        }
7046
7047        IntentFilter pkgFilter = new IntentFilter();
7048        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7049        pkgFilter.addDataScheme("package");
7050        mContext.registerReceiver(new BroadcastReceiver() {
7051            @Override
7052            public void onReceive(Context context, Intent intent) {
7053                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7054                if (pkgs != null) {
7055                    for (String pkg : pkgs) {
7056                        synchronized (ActivityManagerService.this) {
7057                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7058                                    0, "query restart")) {
7059                                setResultCode(Activity.RESULT_OK);
7060                                return;
7061                            }
7062                        }
7063                    }
7064                }
7065            }
7066        }, pkgFilter);
7067
7068        IntentFilter dumpheapFilter = new IntentFilter();
7069        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7070        mContext.registerReceiver(new BroadcastReceiver() {
7071            @Override
7072            public void onReceive(Context context, Intent intent) {
7073                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7074                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7075                } else {
7076                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7077                }
7078            }
7079        }, dumpheapFilter);
7080
7081        // Let system services know.
7082        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7083
7084        synchronized (this) {
7085            // Ensure that any processes we had put on hold are now started
7086            // up.
7087            final int NP = mProcessesOnHold.size();
7088            if (NP > 0) {
7089                ArrayList<ProcessRecord> procs =
7090                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7091                for (int ip=0; ip<NP; ip++) {
7092                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7093                            + procs.get(ip));
7094                    startProcessLocked(procs.get(ip), "on-hold", null);
7095                }
7096            }
7097
7098            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7099                // Start looking for apps that are abusing wake locks.
7100                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7101                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7102                // Tell anyone interested that we are done booting!
7103                SystemProperties.set("sys.boot_completed", "1");
7104
7105                // And trigger dev.bootcomplete if we are not showing encryption progress
7106                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7107                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7108                    SystemProperties.set("dev.bootcomplete", "1");
7109                }
7110                mUserController.sendBootCompletedLocked(
7111                        new IIntentReceiver.Stub() {
7112                            @Override
7113                            public void performReceive(Intent intent, int resultCode,
7114                                    String data, Bundle extras, boolean ordered,
7115                                    boolean sticky, int sendingUser) {
7116                                synchronized (ActivityManagerService.this) {
7117                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7118                                            true, false);
7119                                }
7120                            }
7121                        });
7122                scheduleStartProfilesLocked();
7123            }
7124        }
7125    }
7126
7127    @Override
7128    public void bootAnimationComplete() {
7129        final boolean callFinishBooting;
7130        synchronized (this) {
7131            callFinishBooting = mCallFinishBooting;
7132            mBootAnimationComplete = true;
7133        }
7134        if (callFinishBooting) {
7135            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7136            finishBooting();
7137            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7138        }
7139    }
7140
7141    final void ensureBootCompleted() {
7142        boolean booting;
7143        boolean enableScreen;
7144        synchronized (this) {
7145            booting = mBooting;
7146            mBooting = false;
7147            enableScreen = !mBooted;
7148            mBooted = true;
7149        }
7150
7151        if (booting) {
7152            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7153            finishBooting();
7154            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7155        }
7156
7157        if (enableScreen) {
7158            enableScreenAfterBoot();
7159        }
7160    }
7161
7162    @Override
7163    public final void activityResumed(IBinder token) {
7164        final long origId = Binder.clearCallingIdentity();
7165        synchronized(this) {
7166            ActivityRecord.activityResumedLocked(token);
7167            mWindowManager.notifyAppResumedFinished(token);
7168        }
7169        Binder.restoreCallingIdentity(origId);
7170    }
7171
7172    @Override
7173    public final void activityPaused(IBinder token) {
7174        final long origId = Binder.clearCallingIdentity();
7175        synchronized(this) {
7176            ActivityStack stack = ActivityRecord.getStackLocked(token);
7177            if (stack != null) {
7178                stack.activityPausedLocked(token, false);
7179            }
7180        }
7181        Binder.restoreCallingIdentity(origId);
7182    }
7183
7184    @Override
7185    public final void activityStopped(IBinder token, Bundle icicle,
7186            PersistableBundle persistentState, CharSequence description) {
7187        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7188
7189        // Refuse possible leaked file descriptors
7190        if (icicle != null && icicle.hasFileDescriptors()) {
7191            throw new IllegalArgumentException("File descriptors passed in Bundle");
7192        }
7193
7194        final long origId = Binder.clearCallingIdentity();
7195
7196        synchronized (this) {
7197            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7198            if (r != null) {
7199                r.activityStoppedLocked(icicle, persistentState, description);
7200            }
7201        }
7202
7203        trimApplications();
7204
7205        Binder.restoreCallingIdentity(origId);
7206    }
7207
7208    @Override
7209    public final void activityDestroyed(IBinder token) {
7210        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7211        synchronized (this) {
7212            ActivityStack stack = ActivityRecord.getStackLocked(token);
7213            if (stack != null) {
7214                stack.activityDestroyedLocked(token, "activityDestroyed");
7215            }
7216        }
7217    }
7218
7219    @Override
7220    public final void activityRelaunched(IBinder token) {
7221        final long origId = Binder.clearCallingIdentity();
7222        synchronized (this) {
7223            mStackSupervisor.activityRelaunchedLocked(token);
7224        }
7225        Binder.restoreCallingIdentity(origId);
7226    }
7227
7228    @Override
7229    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7230            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7231        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7232                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7233        synchronized (this) {
7234            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7235            if (record == null) {
7236                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7237                        + "found for: " + token);
7238            }
7239            record.setSizeConfigurations(horizontalSizeConfiguration,
7240                    verticalSizeConfigurations, smallestSizeConfigurations);
7241        }
7242    }
7243
7244    @Override
7245    public final void backgroundResourcesReleased(IBinder token) {
7246        final long origId = Binder.clearCallingIdentity();
7247        try {
7248            synchronized (this) {
7249                ActivityStack stack = ActivityRecord.getStackLocked(token);
7250                if (stack != null) {
7251                    stack.backgroundResourcesReleased();
7252                }
7253            }
7254        } finally {
7255            Binder.restoreCallingIdentity(origId);
7256        }
7257    }
7258
7259    @Override
7260    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7261        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7262    }
7263
7264    @Override
7265    public final void notifyEnterAnimationComplete(IBinder token) {
7266        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7267    }
7268
7269    @Override
7270    public String getCallingPackage(IBinder token) {
7271        synchronized (this) {
7272            ActivityRecord r = getCallingRecordLocked(token);
7273            return r != null ? r.info.packageName : null;
7274        }
7275    }
7276
7277    @Override
7278    public ComponentName getCallingActivity(IBinder token) {
7279        synchronized (this) {
7280            ActivityRecord r = getCallingRecordLocked(token);
7281            return r != null ? r.intent.getComponent() : null;
7282        }
7283    }
7284
7285    private ActivityRecord getCallingRecordLocked(IBinder token) {
7286        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7287        if (r == null) {
7288            return null;
7289        }
7290        return r.resultTo;
7291    }
7292
7293    @Override
7294    public ComponentName getActivityClassForToken(IBinder token) {
7295        synchronized(this) {
7296            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7297            if (r == null) {
7298                return null;
7299            }
7300            return r.intent.getComponent();
7301        }
7302    }
7303
7304    @Override
7305    public String getPackageForToken(IBinder token) {
7306        synchronized(this) {
7307            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7308            if (r == null) {
7309                return null;
7310            }
7311            return r.packageName;
7312        }
7313    }
7314
7315    @Override
7316    public boolean isRootVoiceInteraction(IBinder token) {
7317        synchronized(this) {
7318            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7319            if (r == null) {
7320                return false;
7321            }
7322            return r.rootVoiceInteraction;
7323        }
7324    }
7325
7326    @Override
7327    public IIntentSender getIntentSender(int type,
7328            String packageName, IBinder token, String resultWho,
7329            int requestCode, Intent[] intents, String[] resolvedTypes,
7330            int flags, Bundle bOptions, int userId) {
7331        enforceNotIsolatedCaller("getIntentSender");
7332        // Refuse possible leaked file descriptors
7333        if (intents != null) {
7334            if (intents.length < 1) {
7335                throw new IllegalArgumentException("Intents array length must be >= 1");
7336            }
7337            for (int i=0; i<intents.length; i++) {
7338                Intent intent = intents[i];
7339                if (intent != null) {
7340                    if (intent.hasFileDescriptors()) {
7341                        throw new IllegalArgumentException("File descriptors passed in Intent");
7342                    }
7343                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7344                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7345                        throw new IllegalArgumentException(
7346                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7347                    }
7348                    intents[i] = new Intent(intent);
7349                }
7350            }
7351            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7352                throw new IllegalArgumentException(
7353                        "Intent array length does not match resolvedTypes length");
7354            }
7355        }
7356        if (bOptions != null) {
7357            if (bOptions.hasFileDescriptors()) {
7358                throw new IllegalArgumentException("File descriptors passed in options");
7359            }
7360        }
7361
7362        synchronized(this) {
7363            int callingUid = Binder.getCallingUid();
7364            int origUserId = userId;
7365            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7366                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7367                    ALLOW_NON_FULL, "getIntentSender", null);
7368            if (origUserId == UserHandle.USER_CURRENT) {
7369                // We don't want to evaluate this until the pending intent is
7370                // actually executed.  However, we do want to always do the
7371                // security checking for it above.
7372                userId = UserHandle.USER_CURRENT;
7373            }
7374            try {
7375                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7376                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7377                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7378                    if (!UserHandle.isSameApp(callingUid, uid)) {
7379                        String msg = "Permission Denial: getIntentSender() from pid="
7380                            + Binder.getCallingPid()
7381                            + ", uid=" + Binder.getCallingUid()
7382                            + ", (need uid=" + uid + ")"
7383                            + " is not allowed to send as package " + packageName;
7384                        Slog.w(TAG, msg);
7385                        throw new SecurityException(msg);
7386                    }
7387                }
7388
7389                return getIntentSenderLocked(type, packageName, callingUid, userId,
7390                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7391
7392            } catch (RemoteException e) {
7393                throw new SecurityException(e);
7394            }
7395        }
7396    }
7397
7398    IIntentSender getIntentSenderLocked(int type, String packageName,
7399            int callingUid, int userId, IBinder token, String resultWho,
7400            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7401            Bundle bOptions) {
7402        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7403        ActivityRecord activity = null;
7404        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7405            activity = ActivityRecord.isInStackLocked(token);
7406            if (activity == null) {
7407                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7408                return null;
7409            }
7410            if (activity.finishing) {
7411                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7412                return null;
7413            }
7414        }
7415
7416        // We're going to be splicing together extras before sending, so we're
7417        // okay poking into any contained extras.
7418        if (intents != null) {
7419            for (int i = 0; i < intents.length; i++) {
7420                intents[i].setDefusable(true);
7421            }
7422        }
7423        Bundle.setDefusable(bOptions, true);
7424
7425        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7426        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7427        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7428        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7429                |PendingIntent.FLAG_UPDATE_CURRENT);
7430
7431        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7432                type, packageName, activity, resultWho,
7433                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7434        WeakReference<PendingIntentRecord> ref;
7435        ref = mIntentSenderRecords.get(key);
7436        PendingIntentRecord rec = ref != null ? ref.get() : null;
7437        if (rec != null) {
7438            if (!cancelCurrent) {
7439                if (updateCurrent) {
7440                    if (rec.key.requestIntent != null) {
7441                        rec.key.requestIntent.replaceExtras(intents != null ?
7442                                intents[intents.length - 1] : null);
7443                    }
7444                    if (intents != null) {
7445                        intents[intents.length-1] = rec.key.requestIntent;
7446                        rec.key.allIntents = intents;
7447                        rec.key.allResolvedTypes = resolvedTypes;
7448                    } else {
7449                        rec.key.allIntents = null;
7450                        rec.key.allResolvedTypes = null;
7451                    }
7452                }
7453                return rec;
7454            }
7455            rec.canceled = true;
7456            mIntentSenderRecords.remove(key);
7457        }
7458        if (noCreate) {
7459            return rec;
7460        }
7461        rec = new PendingIntentRecord(this, key, callingUid);
7462        mIntentSenderRecords.put(key, rec.ref);
7463        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7464            if (activity.pendingResults == null) {
7465                activity.pendingResults
7466                        = new HashSet<WeakReference<PendingIntentRecord>>();
7467            }
7468            activity.pendingResults.add(rec.ref);
7469        }
7470        return rec;
7471    }
7472
7473    @Override
7474    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7475            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7476        if (target instanceof PendingIntentRecord) {
7477            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7478                    finishedReceiver, requiredPermission, options);
7479        } else {
7480            if (intent == null) {
7481                // Weird case: someone has given us their own custom IIntentSender, and now
7482                // they have someone else trying to send to it but of course this isn't
7483                // really a PendingIntent, so there is no base Intent, and the caller isn't
7484                // supplying an Intent... but we never want to dispatch a null Intent to
7485                // a receiver, so um...  let's make something up.
7486                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7487                intent = new Intent(Intent.ACTION_MAIN);
7488            }
7489            try {
7490                target.send(code, intent, resolvedType, null, requiredPermission, options);
7491            } catch (RemoteException e) {
7492            }
7493            // Platform code can rely on getting a result back when the send is done, but if
7494            // this intent sender is from outside of the system we can't rely on it doing that.
7495            // So instead we don't give it the result receiver, and instead just directly
7496            // report the finish immediately.
7497            if (finishedReceiver != null) {
7498                try {
7499                    finishedReceiver.performReceive(intent, 0,
7500                            null, null, false, false, UserHandle.getCallingUserId());
7501                } catch (RemoteException e) {
7502                }
7503            }
7504            return 0;
7505        }
7506    }
7507
7508    /**
7509     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7510     */
7511    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7512        if (DEBUG_WHITELISTS) {
7513            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7514                    + targetUid + ", " + duration + ")");
7515        }
7516
7517        if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
7518                != PackageManager.PERMISSION_GRANTED) {
7519            synchronized (mPidsSelfLocked) {
7520                final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7521                if (pr == null) {
7522                    Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid "
7523                            + callerPid);
7524                    return;
7525                }
7526                if (!pr.whitelistManager) {
7527                    if (DEBUG_WHITELISTS) {
7528                        Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid
7529                                + ": pid " + callerPid + " is not allowed");
7530                    }
7531                    return;
7532                }
7533            }
7534        }
7535
7536        final long token = Binder.clearCallingIdentity();
7537        try {
7538            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7539                    true, "pe from uid:" + callerUid);
7540        } finally {
7541            Binder.restoreCallingIdentity(token);
7542        }
7543    }
7544
7545    @Override
7546    public void cancelIntentSender(IIntentSender sender) {
7547        if (!(sender instanceof PendingIntentRecord)) {
7548            return;
7549        }
7550        synchronized(this) {
7551            PendingIntentRecord rec = (PendingIntentRecord)sender;
7552            try {
7553                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7554                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7555                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7556                    String msg = "Permission Denial: cancelIntentSender() from pid="
7557                        + Binder.getCallingPid()
7558                        + ", uid=" + Binder.getCallingUid()
7559                        + " is not allowed to cancel packges "
7560                        + rec.key.packageName;
7561                    Slog.w(TAG, msg);
7562                    throw new SecurityException(msg);
7563                }
7564            } catch (RemoteException e) {
7565                throw new SecurityException(e);
7566            }
7567            cancelIntentSenderLocked(rec, true);
7568        }
7569    }
7570
7571    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7572        rec.canceled = true;
7573        mIntentSenderRecords.remove(rec.key);
7574        if (cleanActivity && rec.key.activity != null) {
7575            rec.key.activity.pendingResults.remove(rec.ref);
7576        }
7577    }
7578
7579    @Override
7580    public String getPackageForIntentSender(IIntentSender pendingResult) {
7581        if (!(pendingResult instanceof PendingIntentRecord)) {
7582            return null;
7583        }
7584        try {
7585            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7586            return res.key.packageName;
7587        } catch (ClassCastException e) {
7588        }
7589        return null;
7590    }
7591
7592    @Override
7593    public int getUidForIntentSender(IIntentSender sender) {
7594        if (sender instanceof PendingIntentRecord) {
7595            try {
7596                PendingIntentRecord res = (PendingIntentRecord)sender;
7597                return res.uid;
7598            } catch (ClassCastException e) {
7599            }
7600        }
7601        return -1;
7602    }
7603
7604    @Override
7605    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7606        if (!(pendingResult instanceof PendingIntentRecord)) {
7607            return false;
7608        }
7609        try {
7610            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7611            if (res.key.allIntents == null) {
7612                return false;
7613            }
7614            for (int i=0; i<res.key.allIntents.length; i++) {
7615                Intent intent = res.key.allIntents[i];
7616                if (intent.getPackage() != null && intent.getComponent() != null) {
7617                    return false;
7618                }
7619            }
7620            return true;
7621        } catch (ClassCastException e) {
7622        }
7623        return false;
7624    }
7625
7626    @Override
7627    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7628        if (!(pendingResult instanceof PendingIntentRecord)) {
7629            return false;
7630        }
7631        try {
7632            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7633            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7634                return true;
7635            }
7636            return false;
7637        } catch (ClassCastException e) {
7638        }
7639        return false;
7640    }
7641
7642    @Override
7643    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7644        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7645                "getIntentForIntentSender()");
7646        if (!(pendingResult instanceof PendingIntentRecord)) {
7647            return null;
7648        }
7649        try {
7650            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7651            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7652        } catch (ClassCastException e) {
7653        }
7654        return null;
7655    }
7656
7657    @Override
7658    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7659        if (!(pendingResult instanceof PendingIntentRecord)) {
7660            return null;
7661        }
7662        try {
7663            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7664            synchronized (this) {
7665                return getTagForIntentSenderLocked(res, prefix);
7666            }
7667        } catch (ClassCastException e) {
7668        }
7669        return null;
7670    }
7671
7672    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7673        final Intent intent = res.key.requestIntent;
7674        if (intent != null) {
7675            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7676                    || res.lastTagPrefix.equals(prefix))) {
7677                return res.lastTag;
7678            }
7679            res.lastTagPrefix = prefix;
7680            final StringBuilder sb = new StringBuilder(128);
7681            if (prefix != null) {
7682                sb.append(prefix);
7683            }
7684            if (intent.getAction() != null) {
7685                sb.append(intent.getAction());
7686            } else if (intent.getComponent() != null) {
7687                intent.getComponent().appendShortString(sb);
7688            } else {
7689                sb.append("?");
7690            }
7691            return res.lastTag = sb.toString();
7692        }
7693        return null;
7694    }
7695
7696    @Override
7697    public void setProcessLimit(int max) {
7698        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7699                "setProcessLimit()");
7700        synchronized (this) {
7701            mConstants.setOverrideMaxCachedProcesses(max);
7702        }
7703        trimApplications();
7704    }
7705
7706    @Override
7707    public int getProcessLimit() {
7708        synchronized (this) {
7709            return mConstants.getOverrideMaxCachedProcesses();
7710        }
7711    }
7712
7713    void foregroundTokenDied(ForegroundToken token) {
7714        synchronized (ActivityManagerService.this) {
7715            synchronized (mPidsSelfLocked) {
7716                ForegroundToken cur
7717                    = mForegroundProcesses.get(token.pid);
7718                if (cur != token) {
7719                    return;
7720                }
7721                mForegroundProcesses.remove(token.pid);
7722                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7723                if (pr == null) {
7724                    return;
7725                }
7726                pr.forcingToForeground = null;
7727                updateProcessForegroundLocked(pr, false, false);
7728            }
7729            updateOomAdjLocked();
7730        }
7731    }
7732
7733    @Override
7734    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7735        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7736                "setProcessForeground()");
7737        synchronized(this) {
7738            boolean changed = false;
7739
7740            synchronized (mPidsSelfLocked) {
7741                ProcessRecord pr = mPidsSelfLocked.get(pid);
7742                if (pr == null && isForeground) {
7743                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7744                    return;
7745                }
7746                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7747                if (oldToken != null) {
7748                    oldToken.token.unlinkToDeath(oldToken, 0);
7749                    mForegroundProcesses.remove(pid);
7750                    if (pr != null) {
7751                        pr.forcingToForeground = null;
7752                    }
7753                    changed = true;
7754                }
7755                if (isForeground && token != null) {
7756                    ForegroundToken newToken = new ForegroundToken() {
7757                        @Override
7758                        public void binderDied() {
7759                            foregroundTokenDied(this);
7760                        }
7761                    };
7762                    newToken.pid = pid;
7763                    newToken.token = token;
7764                    try {
7765                        token.linkToDeath(newToken, 0);
7766                        mForegroundProcesses.put(pid, newToken);
7767                        pr.forcingToForeground = token;
7768                        changed = true;
7769                    } catch (RemoteException e) {
7770                        // If the process died while doing this, we will later
7771                        // do the cleanup with the process death link.
7772                    }
7773                }
7774            }
7775
7776            if (changed) {
7777                updateOomAdjLocked();
7778            }
7779        }
7780    }
7781
7782    @Override
7783    public boolean isAppForeground(int uid) throws RemoteException {
7784        synchronized (this) {
7785            UidRecord uidRec = mActiveUids.get(uid);
7786            if (uidRec == null || uidRec.idle) {
7787                return false;
7788            }
7789            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7790        }
7791    }
7792
7793    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7794    // be guarded by permission checking.
7795    int getUidState(int uid) {
7796        synchronized (this) {
7797            UidRecord uidRec = mActiveUids.get(uid);
7798            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7799        }
7800    }
7801
7802    @Override
7803    public boolean isInMultiWindowMode(IBinder token) {
7804        final long origId = Binder.clearCallingIdentity();
7805        try {
7806            synchronized(this) {
7807                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7808                if (r == null) {
7809                    return false;
7810                }
7811                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7812                return !r.task.mFullscreen;
7813            }
7814        } finally {
7815            Binder.restoreCallingIdentity(origId);
7816        }
7817    }
7818
7819    @Override
7820    public boolean isInPictureInPictureMode(IBinder token) {
7821        final long origId = Binder.clearCallingIdentity();
7822        try {
7823            synchronized(this) {
7824                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7825                if (stack == null) {
7826                    return false;
7827                }
7828                return stack.mStackId == PINNED_STACK_ID;
7829            }
7830        } finally {
7831            Binder.restoreCallingIdentity(origId);
7832        }
7833    }
7834
7835    @Override
7836    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureArgs args) {
7837        final long origId = Binder.clearCallingIdentity();
7838        try {
7839            synchronized(this) {
7840                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7841                        "enterPictureInPictureMode", token, args);
7842
7843                // Activity supports picture-in-picture, now check that we can enter PiP at this
7844                // point, if it is
7845                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7846                        false /* noThrow */)) {
7847                    return false;
7848                }
7849
7850                final Runnable enterPipRunnable = () -> {
7851                    // Only update the saved args from the args that are set
7852                    r.pictureInPictureArgs.copyOnlySet(args);
7853                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
7854                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
7855                    final Rect bounds = mWindowManager.getPictureInPictureBounds(DEFAULT_DISPLAY,
7856                            aspectRatio);
7857                    mStackSupervisor.moveActivityToPinnedStackLocked(r, "enterPictureInPictureMode",
7858                            bounds, true /* moveHomeStackToFront */);
7859                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
7860                    stack.setPictureInPictureAspectRatio(aspectRatio);
7861                    stack.setPictureInPictureActions(actions);
7862
7863                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
7864                            r.supportsPictureInPictureWhilePausing);
7865                    logPictureInPictureArgs(args);
7866                };
7867
7868                if (isKeyguardLocked()) {
7869                    // If the keyguard is showing or occluded, then try and dismiss it before
7870                    // entering picture-in-picture (this will prompt the user to authenticate if the
7871                    // device is currently locked).
7872                    try {
7873                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7874                            @Override
7875                            public void onDismissError() throws RemoteException {
7876                                // Do nothing
7877                            }
7878
7879                            @Override
7880                            public void onDismissSucceeded() throws RemoteException {
7881                                mHandler.post(enterPipRunnable);
7882                            }
7883
7884                            @Override
7885                            public void onDismissCancelled() throws RemoteException {
7886                                // Do nothing
7887                            }
7888                        });
7889                    } catch (RemoteException e) {
7890                        // Local call
7891                    }
7892                } else {
7893                    // Enter picture in picture immediately otherwise
7894                    enterPipRunnable.run();
7895                }
7896                return true;
7897            }
7898        } finally {
7899            Binder.restoreCallingIdentity(origId);
7900        }
7901    }
7902
7903    @Override
7904    public void setPictureInPictureArgs(IBinder token, final PictureInPictureArgs args) {
7905        final long origId = Binder.clearCallingIdentity();
7906        try {
7907            synchronized(this) {
7908                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7909                        "setPictureInPictureArgs", token, args);
7910
7911                // Only update the saved args from the args that are set
7912                r.pictureInPictureArgs.copyOnlySet(args);
7913                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7914                    // If the activity is already in picture-in-picture, update the pinned stack now
7915                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
7916                    // be used the next time the activity enters PiP
7917                    final PinnedActivityStack stack = r.getStack();
7918                    if (!stack.isBoundsAnimatingToFullscreen()) {
7919                        stack.setPictureInPictureAspectRatio(
7920                                r.pictureInPictureArgs.getAspectRatio());
7921                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
7922                    }
7923                }
7924                logPictureInPictureArgs(args);
7925            }
7926        } finally {
7927            Binder.restoreCallingIdentity(origId);
7928        }
7929    }
7930
7931    private void logPictureInPictureArgs(PictureInPictureArgs args) {
7932        if (args.hasSetActions()) {
7933            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
7934                    args.getActions().size());
7935        }
7936        if (args.hasSetAspectRatio()) {
7937            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
7938            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, args.getAspectRatio());
7939            MetricsLogger.action(lm);
7940        }
7941    }
7942
7943    /**
7944     * Checks the state of the system and the activity associated with the given {@param token} to
7945     * verify that picture-in-picture is supported for that activity.
7946     *
7947     * @return the activity record for the given {@param token} if all the checks pass.
7948     */
7949    private ActivityRecord ensureValidPictureInPictureActivityArgsLocked(String caller,
7950            IBinder token, PictureInPictureArgs args) {
7951        if (!mSupportsPictureInPicture) {
7952            throw new IllegalStateException(caller
7953                    + ": Device doesn't support picture-in-picture mode.");
7954        }
7955
7956        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7957        if (r == null) {
7958            throw new IllegalStateException(caller
7959                    + ": Can't find activity for token=" + token);
7960        }
7961
7962        if (!r.supportsPictureInPicture()) {
7963            throw new IllegalStateException(caller
7964                    + ": Current activity does not support picture-in-picture.");
7965        }
7966
7967        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
7968            throw new IllegalStateException(caller
7969                    + ": Activities on the home, assistant, or recents stack not supported");
7970        }
7971
7972        if (args.hasSetAspectRatio()
7973                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
7974                        args.getAspectRatio())) {
7975            final float minAspectRatio = mContext.getResources().getFloat(
7976                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
7977            final float maxAspectRatio = mContext.getResources().getFloat(
7978                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
7979            throw new IllegalArgumentException(String.format(caller
7980                    + ": Aspect ratio is too extreme (must be between %f and %f).",
7981                            minAspectRatio, maxAspectRatio));
7982        }
7983
7984        if (args.hasSetActions()
7985                && args.getActions().size() > ActivityManager.getMaxNumPictureInPictureActions()) {
7986            throw new IllegalArgumentException(String.format(caller + ": Invalid number of"
7987                    + "picture-in-picture actions.  Only a maximum of %d actions allowed",
7988                            ActivityManager.getMaxNumPictureInPictureActions()));
7989        }
7990
7991        return r;
7992    }
7993
7994    // =========================================================
7995    // PROCESS INFO
7996    // =========================================================
7997
7998    static class ProcessInfoService extends IProcessInfoService.Stub {
7999        final ActivityManagerService mActivityManagerService;
8000        ProcessInfoService(ActivityManagerService activityManagerService) {
8001            mActivityManagerService = activityManagerService;
8002        }
8003
8004        @Override
8005        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8006            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8007                    /*in*/ pids, /*out*/ states, null);
8008        }
8009
8010        @Override
8011        public void getProcessStatesAndOomScoresFromPids(
8012                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8013            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8014                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8015        }
8016    }
8017
8018    /**
8019     * For each PID in the given input array, write the current process state
8020     * for that process into the states array, or -1 to indicate that no
8021     * process with the given PID exists. If scores array is provided, write
8022     * the oom score for the process into the scores array, with INVALID_ADJ
8023     * indicating the PID doesn't exist.
8024     */
8025    public void getProcessStatesAndOomScoresForPIDs(
8026            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8027        if (scores != null) {
8028            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8029                    "getProcessStatesAndOomScoresForPIDs()");
8030        }
8031
8032        if (pids == null) {
8033            throw new NullPointerException("pids");
8034        } else if (states == null) {
8035            throw new NullPointerException("states");
8036        } else if (pids.length != states.length) {
8037            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8038        } else if (scores != null && pids.length != scores.length) {
8039            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8040        }
8041
8042        synchronized (mPidsSelfLocked) {
8043            for (int i = 0; i < pids.length; i++) {
8044                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8045                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8046                        pr.curProcState;
8047                if (scores != null) {
8048                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8049                }
8050            }
8051        }
8052    }
8053
8054    // =========================================================
8055    // PERMISSIONS
8056    // =========================================================
8057
8058    static class PermissionController extends IPermissionController.Stub {
8059        ActivityManagerService mActivityManagerService;
8060        PermissionController(ActivityManagerService activityManagerService) {
8061            mActivityManagerService = activityManagerService;
8062        }
8063
8064        @Override
8065        public boolean checkPermission(String permission, int pid, int uid) {
8066            return mActivityManagerService.checkPermission(permission, pid,
8067                    uid) == PackageManager.PERMISSION_GRANTED;
8068        }
8069
8070        @Override
8071        public String[] getPackagesForUid(int uid) {
8072            return mActivityManagerService.mContext.getPackageManager()
8073                    .getPackagesForUid(uid);
8074        }
8075
8076        @Override
8077        public boolean isRuntimePermission(String permission) {
8078            try {
8079                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8080                        .getPermissionInfo(permission, 0);
8081                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8082                        == PermissionInfo.PROTECTION_DANGEROUS;
8083            } catch (NameNotFoundException nnfe) {
8084                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8085            }
8086            return false;
8087        }
8088    }
8089
8090    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8091        @Override
8092        public int checkComponentPermission(String permission, int pid, int uid,
8093                int owningUid, boolean exported) {
8094            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8095                    owningUid, exported);
8096        }
8097
8098        @Override
8099        public Object getAMSLock() {
8100            return ActivityManagerService.this;
8101        }
8102    }
8103
8104    /**
8105     * This can be called with or without the global lock held.
8106     */
8107    int checkComponentPermission(String permission, int pid, int uid,
8108            int owningUid, boolean exported) {
8109        if (pid == MY_PID) {
8110            return PackageManager.PERMISSION_GRANTED;
8111        }
8112        return ActivityManager.checkComponentPermission(permission, uid,
8113                owningUid, exported);
8114    }
8115
8116    /**
8117     * As the only public entry point for permissions checking, this method
8118     * can enforce the semantic that requesting a check on a null global
8119     * permission is automatically denied.  (Internally a null permission
8120     * string is used when calling {@link #checkComponentPermission} in cases
8121     * when only uid-based security is needed.)
8122     *
8123     * This can be called with or without the global lock held.
8124     */
8125    @Override
8126    public int checkPermission(String permission, int pid, int uid) {
8127        if (permission == null) {
8128            return PackageManager.PERMISSION_DENIED;
8129        }
8130        return checkComponentPermission(permission, pid, uid, -1, true);
8131    }
8132
8133    @Override
8134    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8135        if (permission == null) {
8136            return PackageManager.PERMISSION_DENIED;
8137        }
8138
8139        // We might be performing an operation on behalf of an indirect binder
8140        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8141        // client identity accordingly before proceeding.
8142        Identity tlsIdentity = sCallerIdentity.get();
8143        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8144            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8145                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8146            uid = tlsIdentity.uid;
8147            pid = tlsIdentity.pid;
8148        }
8149
8150        return checkComponentPermission(permission, pid, uid, -1, true);
8151    }
8152
8153    /**
8154     * Binder IPC calls go through the public entry point.
8155     * This can be called with or without the global lock held.
8156     */
8157    int checkCallingPermission(String permission) {
8158        return checkPermission(permission,
8159                Binder.getCallingPid(),
8160                UserHandle.getAppId(Binder.getCallingUid()));
8161    }
8162
8163    /**
8164     * This can be called with or without the global lock held.
8165     */
8166    void enforceCallingPermission(String permission, String func) {
8167        if (checkCallingPermission(permission)
8168                == PackageManager.PERMISSION_GRANTED) {
8169            return;
8170        }
8171
8172        String msg = "Permission Denial: " + func + " from pid="
8173                + Binder.getCallingPid()
8174                + ", uid=" + Binder.getCallingUid()
8175                + " requires " + permission;
8176        Slog.w(TAG, msg);
8177        throw new SecurityException(msg);
8178    }
8179
8180    /**
8181     * Determine if UID is holding permissions required to access {@link Uri} in
8182     * the given {@link ProviderInfo}. Final permission checking is always done
8183     * in {@link ContentProvider}.
8184     */
8185    private final boolean checkHoldingPermissionsLocked(
8186            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8187        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8188                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8189        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8190            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8191                    != PERMISSION_GRANTED) {
8192                return false;
8193            }
8194        }
8195        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8196    }
8197
8198    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8199            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8200        if (pi.applicationInfo.uid == uid) {
8201            return true;
8202        } else if (!pi.exported) {
8203            return false;
8204        }
8205
8206        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8207        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8208        try {
8209            // check if target holds top-level <provider> permissions
8210            if (!readMet && pi.readPermission != null && considerUidPermissions
8211                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8212                readMet = true;
8213            }
8214            if (!writeMet && pi.writePermission != null && considerUidPermissions
8215                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8216                writeMet = true;
8217            }
8218
8219            // track if unprotected read/write is allowed; any denied
8220            // <path-permission> below removes this ability
8221            boolean allowDefaultRead = pi.readPermission == null;
8222            boolean allowDefaultWrite = pi.writePermission == null;
8223
8224            // check if target holds any <path-permission> that match uri
8225            final PathPermission[] pps = pi.pathPermissions;
8226            if (pps != null) {
8227                final String path = grantUri.uri.getPath();
8228                int i = pps.length;
8229                while (i > 0 && (!readMet || !writeMet)) {
8230                    i--;
8231                    PathPermission pp = pps[i];
8232                    if (pp.match(path)) {
8233                        if (!readMet) {
8234                            final String pprperm = pp.getReadPermission();
8235                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8236                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8237                                    + ": match=" + pp.match(path)
8238                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8239                            if (pprperm != null) {
8240                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8241                                        == PERMISSION_GRANTED) {
8242                                    readMet = true;
8243                                } else {
8244                                    allowDefaultRead = false;
8245                                }
8246                            }
8247                        }
8248                        if (!writeMet) {
8249                            final String ppwperm = pp.getWritePermission();
8250                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8251                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8252                                    + ": match=" + pp.match(path)
8253                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8254                            if (ppwperm != null) {
8255                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8256                                        == PERMISSION_GRANTED) {
8257                                    writeMet = true;
8258                                } else {
8259                                    allowDefaultWrite = false;
8260                                }
8261                            }
8262                        }
8263                    }
8264                }
8265            }
8266
8267            // grant unprotected <provider> read/write, if not blocked by
8268            // <path-permission> above
8269            if (allowDefaultRead) readMet = true;
8270            if (allowDefaultWrite) writeMet = true;
8271
8272        } catch (RemoteException e) {
8273            return false;
8274        }
8275
8276        return readMet && writeMet;
8277    }
8278
8279    public boolean isAppStartModeDisabled(int uid, String packageName) {
8280        synchronized (this) {
8281            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8282                    == ActivityManager.APP_START_MODE_DISABLED;
8283        }
8284    }
8285
8286    // Unified app-op and target sdk check
8287    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8288        // Apps that target O+ are always subject to background check
8289        if (mConstants.ENFORCE_BG_CHECK && packageTargetSdk >= Build.VERSION_CODES.O) {
8290            if (DEBUG_BACKGROUND_CHECK) {
8291                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8292            }
8293            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8294        }
8295        // ...and legacy apps get an AppOp check
8296        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8297                uid, packageName);
8298        if (DEBUG_BACKGROUND_CHECK) {
8299            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8300        }
8301        switch (appop) {
8302            case AppOpsManager.MODE_ALLOWED:
8303                return ActivityManager.APP_START_MODE_NORMAL;
8304            case AppOpsManager.MODE_IGNORED:
8305                return ActivityManager.APP_START_MODE_DELAYED;
8306            default:
8307                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8308        }
8309    }
8310
8311    // Service launch is available to apps with run-in-background exemptions but
8312    // some other background operations are not.  If we're doing a check
8313    // of service-launch policy, allow those callers to proceed unrestricted.
8314    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8315        // Persistent app?
8316        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8317            if (DEBUG_BACKGROUND_CHECK) {
8318                Slog.i(TAG, "App " + uid + "/" + packageName
8319                        + " is persistent; not restricted in background");
8320            }
8321            return ActivityManager.APP_START_MODE_NORMAL;
8322        }
8323
8324        // Non-persistent but background whitelisted?
8325        if (uidOnBackgroundWhitelist(uid)) {
8326            if (DEBUG_BACKGROUND_CHECK) {
8327                Slog.i(TAG, "App " + uid + "/" + packageName
8328                        + " on background whitelist; not restricted in background");
8329            }
8330            return ActivityManager.APP_START_MODE_NORMAL;
8331        }
8332
8333        // Is this app on the battery whitelist?
8334        if (isOnDeviceIdleWhitelistLocked(uid)) {
8335            if (DEBUG_BACKGROUND_CHECK) {
8336                Slog.i(TAG, "App " + uid + "/" + packageName
8337                        + " on idle whitelist; not restricted in background");
8338            }
8339            return ActivityManager.APP_START_MODE_NORMAL;
8340        }
8341
8342        // None of the service-policy criteria apply, so we apply the common criteria
8343        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8344    }
8345
8346    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8347            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8348        UidRecord uidRec = mActiveUids.get(uid);
8349        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8350                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8351                + (uidRec != null ? uidRec.idle : false));
8352        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8353            boolean ephemeral;
8354            if (uidRec == null) {
8355                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8356                        UserHandle.getUserId(uid), packageName);
8357            } else {
8358                ephemeral = uidRec.ephemeral;
8359            }
8360
8361            if (ephemeral) {
8362                // We are hard-core about ephemeral apps not running in the background.
8363                return ActivityManager.APP_START_MODE_DISABLED;
8364            } else {
8365                if (disabledOnly) {
8366                    // The caller is only interested in whether app starts are completely
8367                    // disabled for the given package (that is, it is an instant app).  So
8368                    // we don't need to go further, which is all just seeing if we should
8369                    // apply a "delayed" mode for a regular app.
8370                    return ActivityManager.APP_START_MODE_NORMAL;
8371                }
8372                final int startMode = (alwaysRestrict)
8373                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8374                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8375                                packageTargetSdk);
8376                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8377                        + " pkg=" + packageName + " startMode=" + startMode
8378                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8379                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8380                    // This is an old app that has been forced into a "compatible as possible"
8381                    // mode of background check.  To increase compatibility, we will allow other
8382                    // foreground apps to cause its services to start.
8383                    if (callingPid >= 0) {
8384                        ProcessRecord proc;
8385                        synchronized (mPidsSelfLocked) {
8386                            proc = mPidsSelfLocked.get(callingPid);
8387                        }
8388                        if (proc != null && proc.curProcState
8389                                < ActivityManager.PROCESS_STATE_RECEIVER) {
8390                            // Whoever is instigating this is in the foreground, so we will allow it
8391                            // to go through.
8392                            return ActivityManager.APP_START_MODE_NORMAL;
8393                        }
8394                    }
8395                }
8396                return startMode;
8397            }
8398        }
8399        return ActivityManager.APP_START_MODE_NORMAL;
8400    }
8401
8402    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8403        final int appId = UserHandle.getAppId(uid);
8404        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8405                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0;
8406    }
8407
8408    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8409        ProviderInfo pi = null;
8410        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8411        if (cpr != null) {
8412            pi = cpr.info;
8413        } else {
8414            try {
8415                pi = AppGlobals.getPackageManager().resolveContentProvider(
8416                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8417                        userHandle);
8418            } catch (RemoteException ex) {
8419            }
8420        }
8421        return pi;
8422    }
8423
8424    void grantEphemeralAccessLocked(int userId, Intent intent,
8425            int targetAppId, int ephemeralAppId) {
8426        getPackageManagerInternalLocked().
8427                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8428    }
8429
8430    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8431        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8432        if (targetUris != null) {
8433            return targetUris.get(grantUri);
8434        }
8435        return null;
8436    }
8437
8438    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8439            String targetPkg, int targetUid, GrantUri grantUri) {
8440        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8441        if (targetUris == null) {
8442            targetUris = Maps.newArrayMap();
8443            mGrantedUriPermissions.put(targetUid, targetUris);
8444        }
8445
8446        UriPermission perm = targetUris.get(grantUri);
8447        if (perm == null) {
8448            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8449            targetUris.put(grantUri, perm);
8450        }
8451
8452        return perm;
8453    }
8454
8455    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8456            final int modeFlags) {
8457        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8458        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8459                : UriPermission.STRENGTH_OWNED;
8460
8461        // Root gets to do everything.
8462        if (uid == 0) {
8463            return true;
8464        }
8465
8466        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8467        if (perms == null) return false;
8468
8469        // First look for exact match
8470        final UriPermission exactPerm = perms.get(grantUri);
8471        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8472            return true;
8473        }
8474
8475        // No exact match, look for prefixes
8476        final int N = perms.size();
8477        for (int i = 0; i < N; i++) {
8478            final UriPermission perm = perms.valueAt(i);
8479            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8480                    && perm.getStrength(modeFlags) >= minStrength) {
8481                return true;
8482            }
8483        }
8484
8485        return false;
8486    }
8487
8488    /**
8489     * @param uri This uri must NOT contain an embedded userId.
8490     * @param userId The userId in which the uri is to be resolved.
8491     */
8492    @Override
8493    public int checkUriPermission(Uri uri, int pid, int uid,
8494            final int modeFlags, int userId, IBinder callerToken) {
8495        enforceNotIsolatedCaller("checkUriPermission");
8496
8497        // Another redirected-binder-call permissions check as in
8498        // {@link checkPermissionWithToken}.
8499        Identity tlsIdentity = sCallerIdentity.get();
8500        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8501            uid = tlsIdentity.uid;
8502            pid = tlsIdentity.pid;
8503        }
8504
8505        // Our own process gets to do everything.
8506        if (pid == MY_PID) {
8507            return PackageManager.PERMISSION_GRANTED;
8508        }
8509        synchronized (this) {
8510            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8511                    ? PackageManager.PERMISSION_GRANTED
8512                    : PackageManager.PERMISSION_DENIED;
8513        }
8514    }
8515
8516    /**
8517     * Check if the targetPkg can be granted permission to access uri by
8518     * the callingUid using the given modeFlags.  Throws a security exception
8519     * if callingUid is not allowed to do this.  Returns the uid of the target
8520     * if the URI permission grant should be performed; returns -1 if it is not
8521     * needed (for example targetPkg already has permission to access the URI).
8522     * If you already know the uid of the target, you can supply it in
8523     * lastTargetUid else set that to -1.
8524     */
8525    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8526            final int modeFlags, int lastTargetUid) {
8527        if (!Intent.isAccessUriMode(modeFlags)) {
8528            return -1;
8529        }
8530
8531        if (targetPkg != null) {
8532            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8533                    "Checking grant " + targetPkg + " permission to " + grantUri);
8534        }
8535
8536        final IPackageManager pm = AppGlobals.getPackageManager();
8537
8538        // If this is not a content: uri, we can't do anything with it.
8539        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8540            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8541                    "Can't grant URI permission for non-content URI: " + grantUri);
8542            return -1;
8543        }
8544
8545        final String authority = grantUri.uri.getAuthority();
8546        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8547                MATCH_DEBUG_TRIAGED_MISSING);
8548        if (pi == null) {
8549            Slog.w(TAG, "No content provider found for permission check: " +
8550                    grantUri.uri.toSafeString());
8551            return -1;
8552        }
8553
8554        int targetUid = lastTargetUid;
8555        if (targetUid < 0 && targetPkg != null) {
8556            try {
8557                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8558                        UserHandle.getUserId(callingUid));
8559                if (targetUid < 0) {
8560                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8561                            "Can't grant URI permission no uid for: " + targetPkg);
8562                    return -1;
8563                }
8564            } catch (RemoteException ex) {
8565                return -1;
8566            }
8567        }
8568
8569        // If we're extending a persistable grant, then we always need to create
8570        // the grant data structure so that take/release APIs work
8571        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8572            return targetUid;
8573        }
8574
8575        if (targetUid >= 0) {
8576            // First...  does the target actually need this permission?
8577            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8578                // No need to grant the target this permission.
8579                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8580                        "Target " + targetPkg + " already has full permission to " + grantUri);
8581                return -1;
8582            }
8583        } else {
8584            // First...  there is no target package, so can anyone access it?
8585            boolean allowed = pi.exported;
8586            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8587                if (pi.readPermission != null) {
8588                    allowed = false;
8589                }
8590            }
8591            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8592                if (pi.writePermission != null) {
8593                    allowed = false;
8594                }
8595            }
8596            if (allowed) {
8597                return -1;
8598            }
8599        }
8600
8601        /* There is a special cross user grant if:
8602         * - The target is on another user.
8603         * - Apps on the current user can access the uri without any uid permissions.
8604         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8605         * grant uri permissions.
8606         */
8607        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8608                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8609                modeFlags, false /*without considering the uid permissions*/);
8610
8611        // Second...  is the provider allowing granting of URI permissions?
8612        if (!specialCrossUserGrant) {
8613            if (!pi.grantUriPermissions) {
8614                throw new SecurityException("Provider " + pi.packageName
8615                        + "/" + pi.name
8616                        + " does not allow granting of Uri permissions (uri "
8617                        + grantUri + ")");
8618            }
8619            if (pi.uriPermissionPatterns != null) {
8620                final int N = pi.uriPermissionPatterns.length;
8621                boolean allowed = false;
8622                for (int i=0; i<N; i++) {
8623                    if (pi.uriPermissionPatterns[i] != null
8624                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8625                        allowed = true;
8626                        break;
8627                    }
8628                }
8629                if (!allowed) {
8630                    throw new SecurityException("Provider " + pi.packageName
8631                            + "/" + pi.name
8632                            + " does not allow granting of permission to path of Uri "
8633                            + grantUri);
8634                }
8635            }
8636        }
8637
8638        // Third...  does the caller itself have permission to access
8639        // this uri?
8640        final int callingAppId = UserHandle.getAppId(callingUid);
8641        if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8642            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8643                // Exempted authority for cropping user photos in Settings app
8644            } else {
8645                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8646                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8647                return -1;
8648            }
8649        }
8650        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8651            // Require they hold a strong enough Uri permission
8652            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8653                throw new SecurityException("Uid " + callingUid
8654                        + " does not have permission to uri " + grantUri);
8655            }
8656        }
8657        return targetUid;
8658    }
8659
8660    /**
8661     * @param uri This uri must NOT contain an embedded userId.
8662     * @param userId The userId in which the uri is to be resolved.
8663     */
8664    @Override
8665    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8666            final int modeFlags, int userId) {
8667        enforceNotIsolatedCaller("checkGrantUriPermission");
8668        synchronized(this) {
8669            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8670                    new GrantUri(userId, uri, false), modeFlags, -1);
8671        }
8672    }
8673
8674    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8675            final int modeFlags, UriPermissionOwner owner) {
8676        if (!Intent.isAccessUriMode(modeFlags)) {
8677            return;
8678        }
8679
8680        // So here we are: the caller has the assumed permission
8681        // to the uri, and the target doesn't.  Let's now give this to
8682        // the target.
8683
8684        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8685                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8686
8687        final String authority = grantUri.uri.getAuthority();
8688        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8689                MATCH_DEBUG_TRIAGED_MISSING);
8690        if (pi == null) {
8691            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8692            return;
8693        }
8694
8695        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8696            grantUri.prefix = true;
8697        }
8698        final UriPermission perm = findOrCreateUriPermissionLocked(
8699                pi.packageName, targetPkg, targetUid, grantUri);
8700        perm.grantModes(modeFlags, owner);
8701    }
8702
8703    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8704            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8705        if (targetPkg == null) {
8706            throw new NullPointerException("targetPkg");
8707        }
8708        int targetUid;
8709        final IPackageManager pm = AppGlobals.getPackageManager();
8710        try {
8711            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8712        } catch (RemoteException ex) {
8713            return;
8714        }
8715
8716        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8717                targetUid);
8718        if (targetUid < 0) {
8719            return;
8720        }
8721
8722        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8723                owner);
8724    }
8725
8726    static class NeededUriGrants extends ArrayList<GrantUri> {
8727        final String targetPkg;
8728        final int targetUid;
8729        final int flags;
8730
8731        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8732            this.targetPkg = targetPkg;
8733            this.targetUid = targetUid;
8734            this.flags = flags;
8735        }
8736    }
8737
8738    /**
8739     * Like checkGrantUriPermissionLocked, but takes an Intent.
8740     */
8741    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8742            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8743        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8744                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8745                + " clip=" + (intent != null ? intent.getClipData() : null)
8746                + " from " + intent + "; flags=0x"
8747                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8748
8749        if (targetPkg == null) {
8750            throw new NullPointerException("targetPkg");
8751        }
8752
8753        if (intent == null) {
8754            return null;
8755        }
8756        Uri data = intent.getData();
8757        ClipData clip = intent.getClipData();
8758        if (data == null && clip == null) {
8759            return null;
8760        }
8761        // Default userId for uris in the intent (if they don't specify it themselves)
8762        int contentUserHint = intent.getContentUserHint();
8763        if (contentUserHint == UserHandle.USER_CURRENT) {
8764            contentUserHint = UserHandle.getUserId(callingUid);
8765        }
8766        final IPackageManager pm = AppGlobals.getPackageManager();
8767        int targetUid;
8768        if (needed != null) {
8769            targetUid = needed.targetUid;
8770        } else {
8771            try {
8772                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8773                        targetUserId);
8774            } catch (RemoteException ex) {
8775                return null;
8776            }
8777            if (targetUid < 0) {
8778                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8779                        "Can't grant URI permission no uid for: " + targetPkg
8780                        + " on user " + targetUserId);
8781                return null;
8782            }
8783        }
8784        if (data != null) {
8785            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8786            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8787                    targetUid);
8788            if (targetUid > 0) {
8789                if (needed == null) {
8790                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8791                }
8792                needed.add(grantUri);
8793            }
8794        }
8795        if (clip != null) {
8796            for (int i=0; i<clip.getItemCount(); i++) {
8797                Uri uri = clip.getItemAt(i).getUri();
8798                if (uri != null) {
8799                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8800                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8801                            targetUid);
8802                    if (targetUid > 0) {
8803                        if (needed == null) {
8804                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8805                        }
8806                        needed.add(grantUri);
8807                    }
8808                } else {
8809                    Intent clipIntent = clip.getItemAt(i).getIntent();
8810                    if (clipIntent != null) {
8811                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8812                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8813                        if (newNeeded != null) {
8814                            needed = newNeeded;
8815                        }
8816                    }
8817                }
8818            }
8819        }
8820
8821        return needed;
8822    }
8823
8824    /**
8825     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8826     */
8827    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8828            UriPermissionOwner owner) {
8829        if (needed != null) {
8830            for (int i=0; i<needed.size(); i++) {
8831                GrantUri grantUri = needed.get(i);
8832                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8833                        grantUri, needed.flags, owner);
8834            }
8835        }
8836    }
8837
8838    void grantUriPermissionFromIntentLocked(int callingUid,
8839            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8840        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8841                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8842        if (needed == null) {
8843            return;
8844        }
8845
8846        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8847    }
8848
8849    /**
8850     * @param uri This uri must NOT contain an embedded userId.
8851     * @param userId The userId in which the uri is to be resolved.
8852     */
8853    @Override
8854    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8855            final int modeFlags, int userId) {
8856        enforceNotIsolatedCaller("grantUriPermission");
8857        GrantUri grantUri = new GrantUri(userId, uri, false);
8858        synchronized(this) {
8859            final ProcessRecord r = getRecordForAppLocked(caller);
8860            if (r == null) {
8861                throw new SecurityException("Unable to find app for caller "
8862                        + caller
8863                        + " when granting permission to uri " + grantUri);
8864            }
8865            if (targetPkg == null) {
8866                throw new IllegalArgumentException("null target");
8867            }
8868            if (grantUri == null) {
8869                throw new IllegalArgumentException("null uri");
8870            }
8871
8872            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8873                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8874                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8875                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8876
8877            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8878                    UserHandle.getUserId(r.uid));
8879        }
8880    }
8881
8882    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8883        if (perm.modeFlags == 0) {
8884            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8885                    perm.targetUid);
8886            if (perms != null) {
8887                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8888                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8889
8890                perms.remove(perm.uri);
8891                if (perms.isEmpty()) {
8892                    mGrantedUriPermissions.remove(perm.targetUid);
8893                }
8894            }
8895        }
8896    }
8897
8898    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8899        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8900                "Revoking all granted permissions to " + grantUri);
8901
8902        final IPackageManager pm = AppGlobals.getPackageManager();
8903        final String authority = grantUri.uri.getAuthority();
8904        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8905                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8906        if (pi == null) {
8907            Slog.w(TAG, "No content provider found for permission revoke: "
8908                    + grantUri.toSafeString());
8909            return;
8910        }
8911
8912        // Does the caller have this permission on the URI?
8913        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8914            // If they don't have direct access to the URI, then revoke any
8915            // ownerless URI permissions that have been granted to them.
8916            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8917            if (perms != null) {
8918                boolean persistChanged = false;
8919                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8920                    final UriPermission perm = it.next();
8921                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8922                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8923                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8924                                "Revoking non-owned " + perm.targetUid
8925                                + " permission to " + perm.uri);
8926                        persistChanged |= perm.revokeModes(
8927                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8928                        if (perm.modeFlags == 0) {
8929                            it.remove();
8930                        }
8931                    }
8932                }
8933                if (perms.isEmpty()) {
8934                    mGrantedUriPermissions.remove(callingUid);
8935                }
8936                if (persistChanged) {
8937                    schedulePersistUriGrants();
8938                }
8939            }
8940            return;
8941        }
8942
8943        boolean persistChanged = false;
8944
8945        // Go through all of the permissions and remove any that match.
8946        int N = mGrantedUriPermissions.size();
8947        for (int i = 0; i < N; i++) {
8948            final int targetUid = mGrantedUriPermissions.keyAt(i);
8949            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8950
8951            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8952                final UriPermission perm = it.next();
8953                if (perm.uri.sourceUserId == grantUri.sourceUserId
8954                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8955                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8956                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8957                    persistChanged |= perm.revokeModes(
8958                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8959                    if (perm.modeFlags == 0) {
8960                        it.remove();
8961                    }
8962                }
8963            }
8964
8965            if (perms.isEmpty()) {
8966                mGrantedUriPermissions.remove(targetUid);
8967                N--;
8968                i--;
8969            }
8970        }
8971
8972        if (persistChanged) {
8973            schedulePersistUriGrants();
8974        }
8975    }
8976
8977    /**
8978     * @param uri This uri must NOT contain an embedded userId.
8979     * @param userId The userId in which the uri is to be resolved.
8980     */
8981    @Override
8982    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8983            int userId) {
8984        enforceNotIsolatedCaller("revokeUriPermission");
8985        synchronized(this) {
8986            final ProcessRecord r = getRecordForAppLocked(caller);
8987            if (r == null) {
8988                throw new SecurityException("Unable to find app for caller "
8989                        + caller
8990                        + " when revoking permission to uri " + uri);
8991            }
8992            if (uri == null) {
8993                Slog.w(TAG, "revokeUriPermission: null uri");
8994                return;
8995            }
8996
8997            if (!Intent.isAccessUriMode(modeFlags)) {
8998                return;
8999            }
9000
9001            final String authority = uri.getAuthority();
9002            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9003                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9004            if (pi == null) {
9005                Slog.w(TAG, "No content provider found for permission revoke: "
9006                        + uri.toSafeString());
9007                return;
9008            }
9009
9010            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
9011        }
9012    }
9013
9014    /**
9015     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9016     * given package.
9017     *
9018     * @param packageName Package name to match, or {@code null} to apply to all
9019     *            packages.
9020     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9021     *            to all users.
9022     * @param persistable If persistable grants should be removed.
9023     */
9024    private void removeUriPermissionsForPackageLocked(
9025            String packageName, int userHandle, boolean persistable) {
9026        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9027            throw new IllegalArgumentException("Must narrow by either package or user");
9028        }
9029
9030        boolean persistChanged = false;
9031
9032        int N = mGrantedUriPermissions.size();
9033        for (int i = 0; i < N; i++) {
9034            final int targetUid = mGrantedUriPermissions.keyAt(i);
9035            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9036
9037            // Only inspect grants matching user
9038            if (userHandle == UserHandle.USER_ALL
9039                    || userHandle == UserHandle.getUserId(targetUid)) {
9040                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9041                    final UriPermission perm = it.next();
9042
9043                    // Only inspect grants matching package
9044                    if (packageName == null || perm.sourcePkg.equals(packageName)
9045                            || perm.targetPkg.equals(packageName)) {
9046                        // Hacky solution as part of fixing a security bug; ignore
9047                        // grants associated with DownloadManager so we don't have
9048                        // to immediately launch it to regrant the permissions
9049                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9050                                && !persistable) continue;
9051
9052                        persistChanged |= perm.revokeModes(persistable
9053                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9054
9055                        // Only remove when no modes remain; any persisted grants
9056                        // will keep this alive.
9057                        if (perm.modeFlags == 0) {
9058                            it.remove();
9059                        }
9060                    }
9061                }
9062
9063                if (perms.isEmpty()) {
9064                    mGrantedUriPermissions.remove(targetUid);
9065                    N--;
9066                    i--;
9067                }
9068            }
9069        }
9070
9071        if (persistChanged) {
9072            schedulePersistUriGrants();
9073        }
9074    }
9075
9076    @Override
9077    public IBinder newUriPermissionOwner(String name) {
9078        enforceNotIsolatedCaller("newUriPermissionOwner");
9079        synchronized(this) {
9080            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9081            return owner.getExternalTokenLocked();
9082        }
9083    }
9084
9085    @Override
9086    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9087        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9088        synchronized(this) {
9089            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9090            if (r == null) {
9091                throw new IllegalArgumentException("Activity does not exist; token="
9092                        + activityToken);
9093            }
9094            return r.getUriPermissionsLocked().getExternalTokenLocked();
9095        }
9096    }
9097    /**
9098     * @param uri This uri must NOT contain an embedded userId.
9099     * @param sourceUserId The userId in which the uri is to be resolved.
9100     * @param targetUserId The userId of the app that receives the grant.
9101     */
9102    @Override
9103    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9104            final int modeFlags, int sourceUserId, int targetUserId) {
9105        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9106                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9107                "grantUriPermissionFromOwner", null);
9108        synchronized(this) {
9109            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9110            if (owner == null) {
9111                throw new IllegalArgumentException("Unknown owner: " + token);
9112            }
9113            if (fromUid != Binder.getCallingUid()) {
9114                if (Binder.getCallingUid() != Process.myUid()) {
9115                    // Only system code can grant URI permissions on behalf
9116                    // of other users.
9117                    throw new SecurityException("nice try");
9118                }
9119            }
9120            if (targetPkg == null) {
9121                throw new IllegalArgumentException("null target");
9122            }
9123            if (uri == null) {
9124                throw new IllegalArgumentException("null uri");
9125            }
9126
9127            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9128                    modeFlags, owner, targetUserId);
9129        }
9130    }
9131
9132    /**
9133     * @param uri This uri must NOT contain an embedded userId.
9134     * @param userId The userId in which the uri is to be resolved.
9135     */
9136    @Override
9137    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9138        synchronized(this) {
9139            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9140            if (owner == null) {
9141                throw new IllegalArgumentException("Unknown owner: " + token);
9142            }
9143
9144            if (uri == null) {
9145                owner.removeUriPermissionsLocked(mode);
9146            } else {
9147                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9148                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9149            }
9150        }
9151    }
9152
9153    private void schedulePersistUriGrants() {
9154        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9155            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9156                    10 * DateUtils.SECOND_IN_MILLIS);
9157        }
9158    }
9159
9160    private void writeGrantedUriPermissions() {
9161        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9162
9163        // Snapshot permissions so we can persist without lock
9164        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9165        synchronized (this) {
9166            final int size = mGrantedUriPermissions.size();
9167            for (int i = 0; i < size; i++) {
9168                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9169                for (UriPermission perm : perms.values()) {
9170                    if (perm.persistedModeFlags != 0) {
9171                        persist.add(perm.snapshot());
9172                    }
9173                }
9174            }
9175        }
9176
9177        FileOutputStream fos = null;
9178        try {
9179            fos = mGrantFile.startWrite();
9180
9181            XmlSerializer out = new FastXmlSerializer();
9182            out.setOutput(fos, StandardCharsets.UTF_8.name());
9183            out.startDocument(null, true);
9184            out.startTag(null, TAG_URI_GRANTS);
9185            for (UriPermission.Snapshot perm : persist) {
9186                out.startTag(null, TAG_URI_GRANT);
9187                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9188                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9189                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9190                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9191                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9192                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9193                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9194                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9195                out.endTag(null, TAG_URI_GRANT);
9196            }
9197            out.endTag(null, TAG_URI_GRANTS);
9198            out.endDocument();
9199
9200            mGrantFile.finishWrite(fos);
9201        } catch (IOException e) {
9202            if (fos != null) {
9203                mGrantFile.failWrite(fos);
9204            }
9205        }
9206    }
9207
9208    private void readGrantedUriPermissionsLocked() {
9209        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9210
9211        final long now = System.currentTimeMillis();
9212
9213        FileInputStream fis = null;
9214        try {
9215            fis = mGrantFile.openRead();
9216            final XmlPullParser in = Xml.newPullParser();
9217            in.setInput(fis, StandardCharsets.UTF_8.name());
9218
9219            int type;
9220            while ((type = in.next()) != END_DOCUMENT) {
9221                final String tag = in.getName();
9222                if (type == START_TAG) {
9223                    if (TAG_URI_GRANT.equals(tag)) {
9224                        final int sourceUserId;
9225                        final int targetUserId;
9226                        final int userHandle = readIntAttribute(in,
9227                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9228                        if (userHandle != UserHandle.USER_NULL) {
9229                            // For backwards compatibility.
9230                            sourceUserId = userHandle;
9231                            targetUserId = userHandle;
9232                        } else {
9233                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9234                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9235                        }
9236                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9237                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9238                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9239                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9240                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9241                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9242
9243                        // Sanity check that provider still belongs to source package
9244                        // Both direct boot aware and unaware packages are fine as we
9245                        // will do filtering at query time to avoid multiple parsing.
9246                        final ProviderInfo pi = getProviderInfoLocked(
9247                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9248                                        | MATCH_DIRECT_BOOT_UNAWARE);
9249                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9250                            int targetUid = -1;
9251                            try {
9252                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9253                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9254                            } catch (RemoteException e) {
9255                            }
9256                            if (targetUid != -1) {
9257                                final UriPermission perm = findOrCreateUriPermissionLocked(
9258                                        sourcePkg, targetPkg, targetUid,
9259                                        new GrantUri(sourceUserId, uri, prefix));
9260                                perm.initPersistedModes(modeFlags, createdTime);
9261                            }
9262                        } else {
9263                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9264                                    + " but instead found " + pi);
9265                        }
9266                    }
9267                }
9268            }
9269        } catch (FileNotFoundException e) {
9270            // Missing grants is okay
9271        } catch (IOException e) {
9272            Slog.wtf(TAG, "Failed reading Uri grants", e);
9273        } catch (XmlPullParserException e) {
9274            Slog.wtf(TAG, "Failed reading Uri grants", e);
9275        } finally {
9276            IoUtils.closeQuietly(fis);
9277        }
9278    }
9279
9280    /**
9281     * @param uri This uri must NOT contain an embedded userId.
9282     * @param userId The userId in which the uri is to be resolved.
9283     */
9284    @Override
9285    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9286        enforceNotIsolatedCaller("takePersistableUriPermission");
9287
9288        Preconditions.checkFlagsArgument(modeFlags,
9289                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9290
9291        synchronized (this) {
9292            final int callingUid = Binder.getCallingUid();
9293            boolean persistChanged = false;
9294            GrantUri grantUri = new GrantUri(userId, uri, false);
9295
9296            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9297                    new GrantUri(userId, uri, false));
9298            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9299                    new GrantUri(userId, uri, true));
9300
9301            final boolean exactValid = (exactPerm != null)
9302                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9303            final boolean prefixValid = (prefixPerm != null)
9304                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9305
9306            if (!(exactValid || prefixValid)) {
9307                throw new SecurityException("No persistable permission grants found for UID "
9308                        + callingUid + " and Uri " + grantUri.toSafeString());
9309            }
9310
9311            if (exactValid) {
9312                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9313            }
9314            if (prefixValid) {
9315                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9316            }
9317
9318            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9319
9320            if (persistChanged) {
9321                schedulePersistUriGrants();
9322            }
9323        }
9324    }
9325
9326    /**
9327     * @param uri This uri must NOT contain an embedded userId.
9328     * @param userId The userId in which the uri is to be resolved.
9329     */
9330    @Override
9331    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9332        enforceNotIsolatedCaller("releasePersistableUriPermission");
9333
9334        Preconditions.checkFlagsArgument(modeFlags,
9335                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9336
9337        synchronized (this) {
9338            final int callingUid = Binder.getCallingUid();
9339            boolean persistChanged = false;
9340
9341            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9342                    new GrantUri(userId, uri, false));
9343            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9344                    new GrantUri(userId, uri, true));
9345            if (exactPerm == null && prefixPerm == null) {
9346                throw new SecurityException("No permission grants found for UID " + callingUid
9347                        + " and Uri " + uri.toSafeString());
9348            }
9349
9350            if (exactPerm != null) {
9351                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9352                removeUriPermissionIfNeededLocked(exactPerm);
9353            }
9354            if (prefixPerm != null) {
9355                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9356                removeUriPermissionIfNeededLocked(prefixPerm);
9357            }
9358
9359            if (persistChanged) {
9360                schedulePersistUriGrants();
9361            }
9362        }
9363    }
9364
9365    /**
9366     * Prune any older {@link UriPermission} for the given UID until outstanding
9367     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9368     *
9369     * @return if any mutations occured that require persisting.
9370     */
9371    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9372        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9373        if (perms == null) return false;
9374        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9375
9376        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9377        for (UriPermission perm : perms.values()) {
9378            if (perm.persistedModeFlags != 0) {
9379                persisted.add(perm);
9380            }
9381        }
9382
9383        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9384        if (trimCount <= 0) return false;
9385
9386        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9387        for (int i = 0; i < trimCount; i++) {
9388            final UriPermission perm = persisted.get(i);
9389
9390            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9391                    "Trimming grant created at " + perm.persistedCreateTime);
9392
9393            perm.releasePersistableModes(~0);
9394            removeUriPermissionIfNeededLocked(perm);
9395        }
9396
9397        return true;
9398    }
9399
9400    @Override
9401    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9402            String packageName, boolean incoming) {
9403        enforceNotIsolatedCaller("getPersistedUriPermissions");
9404        Preconditions.checkNotNull(packageName, "packageName");
9405
9406        final int callingUid = Binder.getCallingUid();
9407        final int callingUserId = UserHandle.getUserId(callingUid);
9408        final IPackageManager pm = AppGlobals.getPackageManager();
9409        try {
9410            final int packageUid = pm.getPackageUid(packageName,
9411                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9412            if (packageUid != callingUid) {
9413                throw new SecurityException(
9414                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9415            }
9416        } catch (RemoteException e) {
9417            throw new SecurityException("Failed to verify package name ownership");
9418        }
9419
9420        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9421        synchronized (this) {
9422            if (incoming) {
9423                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9424                        callingUid);
9425                if (perms == null) {
9426                    Slog.w(TAG, "No permission grants found for " + packageName);
9427                } else {
9428                    for (UriPermission perm : perms.values()) {
9429                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9430                            result.add(perm.buildPersistedPublicApiObject());
9431                        }
9432                    }
9433                }
9434            } else {
9435                final int size = mGrantedUriPermissions.size();
9436                for (int i = 0; i < size; i++) {
9437                    final ArrayMap<GrantUri, UriPermission> perms =
9438                            mGrantedUriPermissions.valueAt(i);
9439                    for (UriPermission perm : perms.values()) {
9440                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9441                            result.add(perm.buildPersistedPublicApiObject());
9442                        }
9443                    }
9444                }
9445            }
9446        }
9447        return new ParceledListSlice<android.content.UriPermission>(result);
9448    }
9449
9450    @Override
9451    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9452            String packageName, int userId) {
9453        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9454                "getGrantedUriPermissions");
9455
9456        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9457        synchronized (this) {
9458            final int size = mGrantedUriPermissions.size();
9459            for (int i = 0; i < size; i++) {
9460                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9461                for (UriPermission perm : perms.values()) {
9462                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9463                            && perm.persistedModeFlags != 0) {
9464                        result.add(perm.buildPersistedPublicApiObject());
9465                    }
9466                }
9467            }
9468        }
9469        return new ParceledListSlice<android.content.UriPermission>(result);
9470    }
9471
9472    @Override
9473    public void clearGrantedUriPermissions(String packageName, int userId) {
9474        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9475                "clearGrantedUriPermissions");
9476        removeUriPermissionsForPackageLocked(packageName, userId, true);
9477    }
9478
9479    @Override
9480    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9481        synchronized (this) {
9482            ProcessRecord app =
9483                who != null ? getRecordForAppLocked(who) : null;
9484            if (app == null) return;
9485
9486            Message msg = Message.obtain();
9487            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9488            msg.obj = app;
9489            msg.arg1 = waiting ? 1 : 0;
9490            mUiHandler.sendMessage(msg);
9491        }
9492    }
9493
9494    @Override
9495    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9496        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9497        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9498        outInfo.availMem = Process.getFreeMemory();
9499        outInfo.totalMem = Process.getTotalMemory();
9500        outInfo.threshold = homeAppMem;
9501        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9502        outInfo.hiddenAppThreshold = cachedAppMem;
9503        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9504                ProcessList.SERVICE_ADJ);
9505        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9506                ProcessList.VISIBLE_APP_ADJ);
9507        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9508                ProcessList.FOREGROUND_APP_ADJ);
9509    }
9510
9511    // =========================================================
9512    // TASK MANAGEMENT
9513    // =========================================================
9514
9515    @Override
9516    public List<IBinder> getAppTasks(String callingPackage) {
9517        int callingUid = Binder.getCallingUid();
9518        long ident = Binder.clearCallingIdentity();
9519
9520        synchronized(this) {
9521            ArrayList<IBinder> list = new ArrayList<IBinder>();
9522            try {
9523                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9524
9525                final int N = mRecentTasks.size();
9526                for (int i = 0; i < N; i++) {
9527                    TaskRecord tr = mRecentTasks.get(i);
9528                    // Skip tasks that do not match the caller.  We don't need to verify
9529                    // callingPackage, because we are also limiting to callingUid and know
9530                    // that will limit to the correct security sandbox.
9531                    if (tr.effectiveUid != callingUid) {
9532                        continue;
9533                    }
9534                    Intent intent = tr.getBaseIntent();
9535                    if (intent == null ||
9536                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9537                        continue;
9538                    }
9539                    ActivityManager.RecentTaskInfo taskInfo =
9540                            createRecentTaskInfoFromTaskRecord(tr);
9541                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9542                    list.add(taskImpl.asBinder());
9543                }
9544            } finally {
9545                Binder.restoreCallingIdentity(ident);
9546            }
9547            return list;
9548        }
9549    }
9550
9551    @Override
9552    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9553        final int callingUid = Binder.getCallingUid();
9554        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9555
9556        synchronized(this) {
9557            if (DEBUG_ALL) Slog.v(
9558                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9559
9560            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9561                    callingUid);
9562
9563            // TODO: Improve with MRU list from all ActivityStacks.
9564            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9565        }
9566
9567        return list;
9568    }
9569
9570    /**
9571     * Creates a new RecentTaskInfo from a TaskRecord.
9572     */
9573    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9574        // Update the task description to reflect any changes in the task stack
9575        tr.updateTaskDescription();
9576
9577        // Compose the recent task info
9578        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9579        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9580        rti.persistentId = tr.taskId;
9581        rti.baseIntent = new Intent(tr.getBaseIntent());
9582        rti.origActivity = tr.origActivity;
9583        rti.realActivity = tr.realActivity;
9584        rti.description = tr.lastDescription;
9585        rti.stackId = tr.getStackId();
9586        rti.userId = tr.userId;
9587        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9588        rti.firstActiveTime = tr.firstActiveTime;
9589        rti.lastActiveTime = tr.lastActiveTime;
9590        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9591        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9592        rti.numActivities = 0;
9593        if (tr.mBounds != null) {
9594            rti.bounds = new Rect(tr.mBounds);
9595        }
9596        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9597        rti.resizeMode = tr.mResizeMode;
9598
9599        ActivityRecord base = null;
9600        ActivityRecord top = null;
9601        ActivityRecord tmp;
9602
9603        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9604            tmp = tr.mActivities.get(i);
9605            if (tmp.finishing) {
9606                continue;
9607            }
9608            base = tmp;
9609            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9610                top = base;
9611            }
9612            rti.numActivities++;
9613        }
9614
9615        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9616        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9617
9618        return rti;
9619    }
9620
9621    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9622        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9623                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9624        if (!allowed) {
9625            if (checkPermission(android.Manifest.permission.GET_TASKS,
9626                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9627                // Temporary compatibility: some existing apps on the system image may
9628                // still be requesting the old permission and not switched to the new
9629                // one; if so, we'll still allow them full access.  This means we need
9630                // to see if they are holding the old permission and are a system app.
9631                try {
9632                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9633                        allowed = true;
9634                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9635                                + " is using old GET_TASKS but privileged; allowing");
9636                    }
9637                } catch (RemoteException e) {
9638                }
9639            }
9640        }
9641        if (!allowed) {
9642            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9643                    + " does not hold REAL_GET_TASKS; limiting output");
9644        }
9645        return allowed;
9646    }
9647
9648    @Override
9649    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9650            int userId) {
9651        final int callingUid = Binder.getCallingUid();
9652        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9653                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9654
9655        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9656        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9657        synchronized (this) {
9658            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9659                    callingUid);
9660            final boolean detailed = checkCallingPermission(
9661                    android.Manifest.permission.GET_DETAILED_TASKS)
9662                    == PackageManager.PERMISSION_GRANTED;
9663
9664            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9665                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9666                return ParceledListSlice.emptyList();
9667            }
9668            mRecentTasks.loadUserRecentsLocked(userId);
9669
9670            final int recentsCount = mRecentTasks.size();
9671            ArrayList<ActivityManager.RecentTaskInfo> res =
9672                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9673
9674            final Set<Integer> includedUsers;
9675            if (includeProfiles) {
9676                includedUsers = mUserController.getProfileIds(userId);
9677            } else {
9678                includedUsers = new HashSet<>();
9679            }
9680            includedUsers.add(Integer.valueOf(userId));
9681
9682            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9683                TaskRecord tr = mRecentTasks.get(i);
9684                // Only add calling user or related users recent tasks
9685                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9686                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9687                    continue;
9688                }
9689
9690                if (tr.realActivitySuspended) {
9691                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9692                    continue;
9693                }
9694
9695                // Return the entry if desired by the caller.  We always return
9696                // the first entry, because callers always expect this to be the
9697                // foreground app.  We may filter others if the caller has
9698                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9699                // we should exclude the entry.
9700
9701                if (i == 0
9702                        || withExcluded
9703                        || (tr.intent == null)
9704                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9705                                == 0)) {
9706                    if (!allowed) {
9707                        // If the caller doesn't have the GET_TASKS permission, then only
9708                        // allow them to see a small subset of tasks -- their own and home.
9709                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9710                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9711                            continue;
9712                        }
9713                    }
9714                    final ActivityStack stack = tr.getStack();
9715                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9716                        if (stack != null && stack.isHomeOrRecentsStack()) {
9717                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9718                                    "Skipping, home or recents stack task: " + tr);
9719                            continue;
9720                        }
9721                    }
9722                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9723                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9724                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9725                                    "Skipping, top task in docked stack: " + tr);
9726                            continue;
9727                        }
9728                    }
9729                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9730                        if (stack != null && stack.isPinnedStack()) {
9731                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9732                                    "Skipping, pinned stack task: " + tr);
9733                            continue;
9734                        }
9735                    }
9736                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9737                        // Don't include auto remove tasks that are finished or finishing.
9738                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9739                                "Skipping, auto-remove without activity: " + tr);
9740                        continue;
9741                    }
9742                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9743                            && !tr.isAvailable) {
9744                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9745                                "Skipping, unavail real act: " + tr);
9746                        continue;
9747                    }
9748
9749                    if (!tr.mUserSetupComplete) {
9750                        // Don't include task launched while user is not done setting-up.
9751                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9752                                "Skipping, user setup not complete: " + tr);
9753                        continue;
9754                    }
9755
9756                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9757                    if (!detailed) {
9758                        rti.baseIntent.replaceExtras((Bundle)null);
9759                    }
9760
9761                    res.add(rti);
9762                    maxNum--;
9763                }
9764            }
9765            return new ParceledListSlice<>(res);
9766        }
9767    }
9768
9769    @Override
9770    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9771        synchronized (this) {
9772            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9773                    "getTaskThumbnail()");
9774            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9775                    id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9776            if (tr != null) {
9777                return tr.getTaskThumbnailLocked();
9778            }
9779        }
9780        return null;
9781    }
9782
9783    @Override
9784    public ActivityManager.TaskDescription getTaskDescription(int id) {
9785        synchronized (this) {
9786            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9787                    "getTaskDescription()");
9788            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9789                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9790            if (tr != null) {
9791                return tr.lastTaskDescription;
9792            }
9793        }
9794        return null;
9795    }
9796
9797    @Override
9798    public int addAppTask(IBinder activityToken, Intent intent,
9799            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9800        final int callingUid = Binder.getCallingUid();
9801        final long callingIdent = Binder.clearCallingIdentity();
9802
9803        try {
9804            synchronized (this) {
9805                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9806                if (r == null) {
9807                    throw new IllegalArgumentException("Activity does not exist; token="
9808                            + activityToken);
9809                }
9810                ComponentName comp = intent.getComponent();
9811                if (comp == null) {
9812                    throw new IllegalArgumentException("Intent " + intent
9813                            + " must specify explicit component");
9814                }
9815                if (thumbnail.getWidth() != mThumbnailWidth
9816                        || thumbnail.getHeight() != mThumbnailHeight) {
9817                    throw new IllegalArgumentException("Bad thumbnail size: got "
9818                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9819                            + mThumbnailWidth + "x" + mThumbnailHeight);
9820                }
9821                if (intent.getSelector() != null) {
9822                    intent.setSelector(null);
9823                }
9824                if (intent.getSourceBounds() != null) {
9825                    intent.setSourceBounds(null);
9826                }
9827                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9828                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9829                        // The caller has added this as an auto-remove task...  that makes no
9830                        // sense, so turn off auto-remove.
9831                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9832                    }
9833                }
9834                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9835                    mLastAddedTaskActivity = null;
9836                }
9837                ActivityInfo ainfo = mLastAddedTaskActivity;
9838                if (ainfo == null) {
9839                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9840                            comp, 0, UserHandle.getUserId(callingUid));
9841                    if (ainfo.applicationInfo.uid != callingUid) {
9842                        throw new SecurityException(
9843                                "Can't add task for another application: target uid="
9844                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9845                    }
9846                }
9847
9848                TaskRecord task = new TaskRecord(this,
9849                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9850                        ainfo, intent, description, new TaskThumbnailInfo());
9851
9852                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9853                if (trimIdx >= 0) {
9854                    // If this would have caused a trim, then we'll abort because that
9855                    // means it would be added at the end of the list but then just removed.
9856                    return INVALID_TASK_ID;
9857                }
9858
9859                final int N = mRecentTasks.size();
9860                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9861                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9862                    tr.removedFromRecents();
9863                }
9864
9865                task.inRecents = true;
9866                mRecentTasks.add(task);
9867                r.getStack().addTask(task, false, "addAppTask");
9868
9869                task.setLastThumbnailLocked(thumbnail);
9870                task.freeLastThumbnail();
9871                return task.taskId;
9872            }
9873        } finally {
9874            Binder.restoreCallingIdentity(callingIdent);
9875        }
9876    }
9877
9878    @Override
9879    public Point getAppTaskThumbnailSize() {
9880        synchronized (this) {
9881            return new Point(mThumbnailWidth,  mThumbnailHeight);
9882        }
9883    }
9884
9885    @Override
9886    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9887        synchronized (this) {
9888            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9889            if (r != null) {
9890                r.setTaskDescription(td);
9891                r.task.updateTaskDescription();
9892                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9893            }
9894        }
9895    }
9896
9897    @Override
9898    public void setTaskResizeable(int taskId, int resizeableMode) {
9899        synchronized (this) {
9900            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9901                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9902            if (task == null) {
9903                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9904                return;
9905            }
9906            task.setResizeMode(resizeableMode);
9907        }
9908    }
9909
9910    @Override
9911    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9912        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9913        long ident = Binder.clearCallingIdentity();
9914        try {
9915            synchronized (this) {
9916                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9917                if (task == null) {
9918                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9919                    return;
9920                }
9921                // Place the task in the right stack if it isn't there already based on
9922                // the requested bounds.
9923                // The stack transition logic is:
9924                // - a null bounds on a freeform task moves that task to fullscreen
9925                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9926                //   that task to freeform
9927                // - otherwise the task is not moved
9928                int stackId = task.getStackId();
9929                if (!StackId.isTaskResizeAllowed(stackId)) {
9930                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9931                }
9932                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9933                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9934                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9935                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9936                }
9937
9938                // Reparent the task to the right stack if necessary
9939                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9940                if (stackId != task.getStackId()) {
9941                    // Defer resume until the task is resized below
9942                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
9943                            DEFER_RESUME, "resizeTask");
9944                    preserveWindow = false;
9945                }
9946
9947                // After reparenting (which only resizes the task to the stack bounds), resize the
9948                // task to the actual bounds provided
9949                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
9950            }
9951        } finally {
9952            Binder.restoreCallingIdentity(ident);
9953        }
9954    }
9955
9956    @Override
9957    public Rect getTaskBounds(int taskId) {
9958        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9959        long ident = Binder.clearCallingIdentity();
9960        Rect rect = new Rect();
9961        try {
9962            synchronized (this) {
9963                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
9964                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9965                if (task == null) {
9966                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9967                    return rect;
9968                }
9969                if (task.getStack() != null) {
9970                    // Return the bounds from window manager since it will be adjusted for various
9971                    // things like the presense of a docked stack for tasks that aren't resizeable.
9972                    task.getWindowContainerBounds(rect);
9973                } else {
9974                    // Task isn't in window manager yet since it isn't associated with a stack.
9975                    // Return the persist value from activity manager
9976                    if (task.mBounds != null) {
9977                        rect.set(task.mBounds);
9978                    } else if (task.mLastNonFullscreenBounds != null) {
9979                        rect.set(task.mLastNonFullscreenBounds);
9980                    }
9981                }
9982            }
9983        } finally {
9984            Binder.restoreCallingIdentity(ident);
9985        }
9986        return rect;
9987    }
9988
9989    @Override
9990    public void cancelTaskWindowTransition(int taskId) {
9991        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
9992        final long ident = Binder.clearCallingIdentity();
9993        try {
9994            synchronized (this) {
9995                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
9996                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
9997                if (task == null) {
9998                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
9999                    return;
10000                }
10001                task.cancelWindowTransition();
10002            }
10003        } finally {
10004            Binder.restoreCallingIdentity(ident);
10005        }
10006    }
10007
10008    @Override
10009    public void cancelTaskThumbnailTransition(int taskId) {
10010        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10011        final long ident = Binder.clearCallingIdentity();
10012        try {
10013            synchronized (this) {
10014                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10015                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10016                if (task == null) {
10017                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10018                    return;
10019                }
10020                task.cancelThumbnailTransition();
10021            }
10022        } finally {
10023            Binder.restoreCallingIdentity(ident);
10024        }
10025    }
10026
10027    @Override
10028    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10029        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10030        final long ident = Binder.clearCallingIdentity();
10031        try {
10032            final TaskRecord task;
10033            synchronized (this) {
10034                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10035                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10036                if (task == null) {
10037                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10038                    return null;
10039                }
10040            }
10041            // Don't call this while holding the lock as this operation might hit the disk.
10042            return task.getSnapshot(reducedResolution);
10043        } finally {
10044            Binder.restoreCallingIdentity(ident);
10045        }
10046    }
10047
10048    @Override
10049    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10050        if (userId != UserHandle.getCallingUserId()) {
10051            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10052                    "getTaskDescriptionIcon");
10053        }
10054        final File passedIconFile = new File(filePath);
10055        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10056                passedIconFile.getName());
10057        if (!legitIconFile.getPath().equals(filePath)
10058                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10059            throw new IllegalArgumentException("Bad file path: " + filePath
10060                    + " passed for userId " + userId);
10061        }
10062        return mRecentTasks.getTaskDescriptionIcon(filePath);
10063    }
10064
10065    @Override
10066    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10067            throws RemoteException {
10068        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10069        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10070                activityOptions.getCustomInPlaceResId() == 0) {
10071            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10072                    "with valid animation");
10073        }
10074        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10075        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10076                activityOptions.getCustomInPlaceResId());
10077        mWindowManager.executeAppTransition();
10078    }
10079
10080    private void removeTasksByPackageNameLocked(String packageName, int userId) {
10081        // Remove all tasks with activities in the specified package from the list of recent tasks
10082        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10083            TaskRecord tr = mRecentTasks.get(i);
10084            if (tr.userId != userId) continue;
10085
10086            ComponentName cn = tr.intent.getComponent();
10087            if (cn != null && cn.getPackageName().equals(packageName)) {
10088                // If the package name matches, remove the task.
10089                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10090            }
10091        }
10092    }
10093
10094    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10095            int userId) {
10096
10097        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10098            TaskRecord tr = mRecentTasks.get(i);
10099            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10100                continue;
10101            }
10102
10103            ComponentName cn = tr.intent.getComponent();
10104            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10105                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10106            if (sameComponent) {
10107                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10108            }
10109        }
10110    }
10111
10112    @Override
10113    public void removeStack(int stackId) {
10114        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10115        if (StackId.isHomeOrRecentsStack(stackId)) {
10116            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10117        }
10118
10119        synchronized (this) {
10120            final long ident = Binder.clearCallingIdentity();
10121            try {
10122                mStackSupervisor.removeStackLocked(stackId);
10123            } finally {
10124                Binder.restoreCallingIdentity(ident);
10125            }
10126        }
10127    }
10128
10129    @Override
10130    public void moveStackToDisplay(int stackId, int displayId) {
10131        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
10132
10133        synchronized (this) {
10134            final long ident = Binder.clearCallingIdentity();
10135            try {
10136                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10137                        + " to displayId=" + displayId);
10138                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10139            } finally {
10140                Binder.restoreCallingIdentity(ident);
10141            }
10142        }
10143    }
10144
10145    @Override
10146    public boolean removeTask(int taskId) {
10147        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10148        synchronized (this) {
10149            final long ident = Binder.clearCallingIdentity();
10150            try {
10151                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10152            } finally {
10153                Binder.restoreCallingIdentity(ident);
10154            }
10155        }
10156    }
10157
10158    /**
10159     * TODO: Add mController hook
10160     */
10161    @Override
10162    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10163        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10164
10165        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10166        synchronized(this) {
10167            moveTaskToFrontLocked(taskId, flags, bOptions);
10168        }
10169    }
10170
10171    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
10172        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10173
10174        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10175                Binder.getCallingUid(), -1, -1, "Task to front")) {
10176            ActivityOptions.abort(options);
10177            return;
10178        }
10179        final long origId = Binder.clearCallingIdentity();
10180        try {
10181            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10182            if (task == null) {
10183                Slog.d(TAG, "Could not find task for id: "+ taskId);
10184                return;
10185            }
10186            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10187                mStackSupervisor.showLockTaskToast();
10188                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10189                return;
10190            }
10191            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10192            if (prev != null) {
10193                task.setTaskToReturnTo(prev);
10194            }
10195            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10196                    false /* forceNonResizable */);
10197
10198            final ActivityRecord topActivity = task.getTopActivity();
10199            if (topActivity != null) {
10200
10201                // We are reshowing a task, use a starting window to hide the initial draw delay
10202                // so the transition can start earlier.
10203                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10204                        true /* taskSwitch */);
10205            }
10206        } finally {
10207            Binder.restoreCallingIdentity(origId);
10208        }
10209        ActivityOptions.abort(options);
10210    }
10211
10212    /**
10213     * Attempts to move a task backwards in z-order (the order of activities within the task is
10214     * unchanged).
10215     *
10216     * There are several possible results of this call:
10217     * - if the task is locked, then we will show the lock toast
10218     * - if there is a task behind the provided task, then that task is made visible and resumed as
10219     *   this task is moved to the back
10220     * - otherwise, if there are no other tasks in the stack:
10221     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10222     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10223     *       (depending on whether it is visible)
10224     *     - otherwise, we simply return home and hide this task
10225     *
10226     * @param token A reference to the activity we wish to move
10227     * @param nonRoot If false then this only works if the activity is the root
10228     *                of a task; if true it will work for any activity in a task.
10229     * @return Returns true if the move completed, false if not.
10230     */
10231    @Override
10232    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10233        enforceNotIsolatedCaller("moveActivityTaskToBack");
10234        synchronized(this) {
10235            final long origId = Binder.clearCallingIdentity();
10236            try {
10237                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10238                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10239                if (task != null) {
10240                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10241                }
10242            } finally {
10243                Binder.restoreCallingIdentity(origId);
10244            }
10245        }
10246        return false;
10247    }
10248
10249    @Override
10250    public void moveTaskBackwards(int task) {
10251        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10252                "moveTaskBackwards()");
10253
10254        synchronized(this) {
10255            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10256                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10257                return;
10258            }
10259            final long origId = Binder.clearCallingIdentity();
10260            moveTaskBackwardsLocked(task);
10261            Binder.restoreCallingIdentity(origId);
10262        }
10263    }
10264
10265    private final void moveTaskBackwardsLocked(int task) {
10266        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10267    }
10268
10269    @Override
10270    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10271            IActivityContainerCallback callback) throws RemoteException {
10272        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10273        synchronized (this) {
10274            if (parentActivityToken == null) {
10275                throw new IllegalArgumentException("parent token must not be null");
10276            }
10277            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10278            if (r == null) {
10279                return null;
10280            }
10281            if (callback == null) {
10282                throw new IllegalArgumentException("callback must not be null");
10283            }
10284            return mStackSupervisor.createVirtualActivityContainer(r, callback);
10285        }
10286    }
10287
10288    @Override
10289    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10290        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10291        synchronized (this) {
10292            final int stackId = mStackSupervisor.getNextStackId();
10293            final ActivityStack stack =
10294                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10295            if (stack == null) {
10296                return null;
10297            }
10298            return stack.mActivityContainer;
10299        }
10300    }
10301
10302    @Override
10303    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10304        synchronized (this) {
10305            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10306            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10307                return stack.mActivityContainer.getDisplayId();
10308            }
10309            return DEFAULT_DISPLAY;
10310        }
10311    }
10312
10313    @Override
10314    public int getActivityStackId(IBinder token) throws RemoteException {
10315        synchronized (this) {
10316            ActivityStack stack = ActivityRecord.getStackLocked(token);
10317            if (stack == null) {
10318                return INVALID_STACK_ID;
10319            }
10320            return stack.mStackId;
10321        }
10322    }
10323
10324    @Override
10325    public void exitFreeformMode(IBinder token) throws RemoteException {
10326        synchronized (this) {
10327            long ident = Binder.clearCallingIdentity();
10328            try {
10329                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10330                if (r == null) {
10331                    throw new IllegalArgumentException(
10332                            "exitFreeformMode: No activity record matching token=" + token);
10333                }
10334
10335                final ActivityStack stack = r.getStack();
10336                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10337                    throw new IllegalStateException(
10338                            "exitFreeformMode: You can only go fullscreen from freeform.");
10339                }
10340
10341                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10342                r.task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT,
10343                        ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10344            } finally {
10345                Binder.restoreCallingIdentity(ident);
10346            }
10347        }
10348    }
10349
10350    @Override
10351    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10352        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10353        if (StackId.isHomeOrRecentsStack(stackId)) {
10354            throw new IllegalArgumentException(
10355                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10356        }
10357        synchronized (this) {
10358            long ident = Binder.clearCallingIdentity();
10359            try {
10360                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10361                if (task == null) {
10362                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10363                    return;
10364                }
10365
10366                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10367                        + " to stackId=" + stackId + " toTop=" + toTop);
10368                if (stackId == DOCKED_STACK_ID) {
10369                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10370                            null /* initialBounds */);
10371                }
10372                task.reparent(stackId, toTop,
10373                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10374            } finally {
10375                Binder.restoreCallingIdentity(ident);
10376            }
10377        }
10378    }
10379
10380    @Override
10381    public void swapDockedAndFullscreenStack() throws RemoteException {
10382        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10383        synchronized (this) {
10384            long ident = Binder.clearCallingIdentity();
10385            try {
10386                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10387                        FULLSCREEN_WORKSPACE_STACK_ID);
10388                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10389                        : null;
10390                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10391                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10392                        : null;
10393                if (topTask == null || tasks == null || tasks.size() == 0) {
10394                    Slog.w(TAG,
10395                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10396                    return;
10397                }
10398
10399                // TODO: App transition
10400                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10401
10402                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10403                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10404                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10405                final int size = tasks.size();
10406                for (int i = 0; i < size; i++) {
10407                    final int id = tasks.get(i).taskId;
10408                    if (id == topTask.taskId) {
10409                        continue;
10410                    }
10411
10412                    // Defer the resume until after all the tasks have been moved
10413                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10414                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10415                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10416                }
10417
10418                // Because we deferred the resume to avoid conflicts with stack switches while
10419                // resuming, we need to do it after all the tasks are moved.
10420                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10421                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10422
10423                mWindowManager.executeAppTransition();
10424            } finally {
10425                Binder.restoreCallingIdentity(ident);
10426            }
10427        }
10428    }
10429
10430    /**
10431     * Moves the input task to the docked stack.
10432     *
10433     * @param taskId Id of task to move.
10434     * @param createMode The mode the docked stack should be created in if it doesn't exist
10435     *                   already. See
10436     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10437     *                   and
10438     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10439     * @param toTop If the task and stack should be moved to the top.
10440     * @param animate Whether we should play an animation for the moving the task
10441     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10442     *                      docked stack. Pass {@code null} to use default bounds.
10443     */
10444    @Override
10445    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10446            Rect initialBounds) {
10447        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10448        synchronized (this) {
10449            long ident = Binder.clearCallingIdentity();
10450            try {
10451                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10452                if (task == null) {
10453                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10454                    return false;
10455                }
10456
10457                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10458                        + " to createMode=" + createMode + " toTop=" + toTop);
10459                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10460
10461                // Defer resuming until we move the home stack to the front below
10462                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10463                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10464                        "moveTaskToDockedStack");
10465                if (moved) {
10466                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10467                }
10468                return moved;
10469            } finally {
10470                Binder.restoreCallingIdentity(ident);
10471            }
10472        }
10473    }
10474
10475    /**
10476     * Moves the top activity in the input stackId to the pinned stack.
10477     *
10478     * @param stackId Id of stack to move the top activity to pinned stack.
10479     * @param bounds Bounds to use for pinned stack.
10480     *
10481     * @return True if the top activity of the input stack was successfully moved to the pinned
10482     *          stack.
10483     */
10484    @Override
10485    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10486        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10487        synchronized (this) {
10488            if (!mSupportsPictureInPicture) {
10489                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10490                        + "Device doesn't support picture-in-picture mode");
10491            }
10492
10493            long ident = Binder.clearCallingIdentity();
10494            try {
10495                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10496            } finally {
10497                Binder.restoreCallingIdentity(ident);
10498            }
10499        }
10500    }
10501
10502    @Override
10503    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10504            boolean preserveWindows, boolean animate, int animationDuration) {
10505        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10506        long ident = Binder.clearCallingIdentity();
10507        try {
10508            synchronized (this) {
10509                if (animate) {
10510                    if (stackId == PINNED_STACK_ID) {
10511                        final PinnedActivityStack pinnedStack =
10512                                mStackSupervisor.getStack(PINNED_STACK_ID);
10513                        pinnedStack.animateResizePinnedStack(bounds, animationDuration);
10514                    } else {
10515                        throw new IllegalArgumentException("Stack: " + stackId
10516                                + " doesn't support animated resize.");
10517                    }
10518                } else {
10519                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10520                            null /* tempTaskInsetBounds */, preserveWindows,
10521                            allowResizeInDockedMode, !DEFER_RESUME);
10522                }
10523            }
10524        } finally {
10525            Binder.restoreCallingIdentity(ident);
10526        }
10527    }
10528
10529    @Override
10530    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10531            Rect tempDockedTaskInsetBounds,
10532            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10533        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10534                "resizeDockedStack()");
10535        long ident = Binder.clearCallingIdentity();
10536        try {
10537            synchronized (this) {
10538                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10539                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10540                        PRESERVE_WINDOWS);
10541            }
10542        } finally {
10543            Binder.restoreCallingIdentity(ident);
10544        }
10545    }
10546
10547    @Override
10548    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10549        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10550                "resizePinnedStack()");
10551        final long ident = Binder.clearCallingIdentity();
10552        try {
10553            synchronized (this) {
10554                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10555            }
10556        } finally {
10557            Binder.restoreCallingIdentity(ident);
10558        }
10559    }
10560
10561    /**
10562     * Try to place task to provided position. The final position might be different depending on
10563     * current user and stacks state. The task will be moved to target stack if it's currently in
10564     * different stack.
10565     */
10566    @Override
10567    public void positionTaskInStack(int taskId, int stackId, int position) {
10568        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10569        if (StackId.isHomeOrRecentsStack(stackId)) {
10570            throw new IllegalArgumentException(
10571                    "positionTaskInStack: Attempt to change the position of task "
10572                    + taskId + " in/to home/recents stack");
10573        }
10574        synchronized (this) {
10575            long ident = Binder.clearCallingIdentity();
10576            try {
10577                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10578                        + taskId + " in stackId=" + stackId + " at position=" + position);
10579                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10580                if (task == null) {
10581                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10582                            + taskId);
10583                }
10584
10585                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10586                        !ON_TOP);
10587
10588                // TODO: Have the callers of this API call a separate reparent method if that is
10589                // what they intended to do vs. having this method also do reparenting.
10590                if (task.getStack() == stack) {
10591                    // Change position in current stack.
10592                    stack.positionChildAt(task, position);
10593                } else {
10594                    // Reparent to new stack.
10595                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10596                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10597                }
10598            } finally {
10599                Binder.restoreCallingIdentity(ident);
10600            }
10601        }
10602    }
10603
10604    @Override
10605    public List<StackInfo> getAllStackInfos() {
10606        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10607        long ident = Binder.clearCallingIdentity();
10608        try {
10609            synchronized (this) {
10610                return mStackSupervisor.getAllStackInfosLocked();
10611            }
10612        } finally {
10613            Binder.restoreCallingIdentity(ident);
10614        }
10615    }
10616
10617    @Override
10618    public StackInfo getStackInfo(int stackId) {
10619        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10620        long ident = Binder.clearCallingIdentity();
10621        try {
10622            synchronized (this) {
10623                return mStackSupervisor.getStackInfoLocked(stackId);
10624            }
10625        } finally {
10626            Binder.restoreCallingIdentity(ident);
10627        }
10628    }
10629
10630    @Override
10631    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10632        synchronized(this) {
10633            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10634        }
10635    }
10636
10637    @Override
10638    public void updateDeviceOwner(String packageName) {
10639        final int callingUid = Binder.getCallingUid();
10640        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10641            throw new SecurityException("updateDeviceOwner called from non-system process");
10642        }
10643        synchronized (this) {
10644            mDeviceOwnerName = packageName;
10645        }
10646    }
10647
10648    @Override
10649    public void updateLockTaskPackages(int userId, String[] packages) {
10650        final int callingUid = Binder.getCallingUid();
10651        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10652            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10653                    "updateLockTaskPackages()");
10654        }
10655        synchronized (this) {
10656            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10657                    Arrays.toString(packages));
10658            mLockTaskPackages.put(userId, packages);
10659            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10660        }
10661    }
10662
10663
10664    void startLockTaskModeLocked(TaskRecord task) {
10665        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10666        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10667            return;
10668        }
10669
10670        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10671        // is initiated by system after the pinning request was shown and locked mode is initiated
10672        // by an authorized app directly
10673        final int callingUid = Binder.getCallingUid();
10674        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10675        long ident = Binder.clearCallingIdentity();
10676        try {
10677            if (!isSystemInitiated) {
10678                task.mLockTaskUid = callingUid;
10679                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10680                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10681                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10682                    StatusBarManagerInternal statusBarManager =
10683                            LocalServices.getService(StatusBarManagerInternal.class);
10684                    if (statusBarManager != null) {
10685                        statusBarManager.showScreenPinningRequest(task.taskId);
10686                    }
10687                    return;
10688                }
10689
10690                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10691                if (stack == null || task != stack.topTask()) {
10692                    throw new IllegalArgumentException("Invalid task, not in foreground");
10693                }
10694            }
10695            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10696                    "Locking fully");
10697            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10698                    ActivityManager.LOCK_TASK_MODE_PINNED :
10699                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10700                    "startLockTask", true);
10701        } finally {
10702            Binder.restoreCallingIdentity(ident);
10703        }
10704    }
10705
10706    @Override
10707    public void startLockTaskModeById(int taskId) {
10708        synchronized (this) {
10709            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10710            if (task != null) {
10711                startLockTaskModeLocked(task);
10712            }
10713        }
10714    }
10715
10716    @Override
10717    public void startLockTaskModeByToken(IBinder token) {
10718        synchronized (this) {
10719            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10720            if (r == null) {
10721                return;
10722            }
10723            final TaskRecord task = r.task;
10724            if (task != null) {
10725                startLockTaskModeLocked(task);
10726            }
10727        }
10728    }
10729
10730    @Override
10731    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10732        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10733        // This makes inner call to look as if it was initiated by system.
10734        long ident = Binder.clearCallingIdentity();
10735        try {
10736            synchronized (this) {
10737                startLockTaskModeById(taskId);
10738            }
10739        } finally {
10740            Binder.restoreCallingIdentity(ident);
10741        }
10742    }
10743
10744    @Override
10745    public void stopLockTaskMode() {
10746        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10747        if (lockTask == null) {
10748            // Our work here is done.
10749            return;
10750        }
10751
10752        final int callingUid = Binder.getCallingUid();
10753        final int lockTaskUid = lockTask.mLockTaskUid;
10754        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10755        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10756            // Done.
10757            return;
10758        } else {
10759            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10760            // It is possible lockTaskMode was started by the system process because
10761            // android:lockTaskMode is set to a locking value in the application manifest
10762            // instead of the app calling startLockTaskMode. In this case
10763            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10764            // {@link TaskRecord.effectiveUid} instead. Also caller with
10765            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10766            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10767                    && callingUid != lockTaskUid
10768                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10769                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10770                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10771            }
10772        }
10773        long ident = Binder.clearCallingIdentity();
10774        try {
10775            Log.d(TAG, "stopLockTaskMode");
10776            // Stop lock task
10777            synchronized (this) {
10778                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10779                        "stopLockTask", true);
10780            }
10781            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10782            if (tm != null) {
10783                tm.showInCallScreen(false);
10784            }
10785        } finally {
10786            Binder.restoreCallingIdentity(ident);
10787        }
10788    }
10789
10790    /**
10791     * This API should be called by SystemUI only when user perform certain action to dismiss
10792     * lock task mode. We should only dismiss pinned lock task mode in this case.
10793     */
10794    @Override
10795    public void stopSystemLockTaskMode() throws RemoteException {
10796        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10797            stopLockTaskMode();
10798        } else {
10799            mStackSupervisor.showLockTaskToast();
10800        }
10801    }
10802
10803    @Override
10804    public boolean isInLockTaskMode() {
10805        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10806    }
10807
10808    @Override
10809    public int getLockTaskModeState() {
10810        synchronized (this) {
10811            return mStackSupervisor.getLockTaskModeState();
10812        }
10813    }
10814
10815    @Override
10816    public void showLockTaskEscapeMessage(IBinder token) {
10817        synchronized (this) {
10818            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10819            if (r == null) {
10820                return;
10821            }
10822            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10823        }
10824    }
10825
10826    @Override
10827    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
10828            throws RemoteException {
10829        synchronized (this) {
10830            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10831            if (r == null) {
10832                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
10833                        + token);
10834                return;
10835            }
10836            final long origId = Binder.clearCallingIdentity();
10837            try {
10838                r.setDisablePreviewScreenshots(disable);
10839            } finally {
10840                Binder.restoreCallingIdentity(origId);
10841            }
10842        }
10843    }
10844
10845    // =========================================================
10846    // CONTENT PROVIDERS
10847    // =========================================================
10848
10849    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10850        List<ProviderInfo> providers = null;
10851        try {
10852            providers = AppGlobals.getPackageManager()
10853                    .queryContentProviders(app.processName, app.uid,
10854                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10855                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
10856                    .getList();
10857        } catch (RemoteException ex) {
10858        }
10859        if (DEBUG_MU) Slog.v(TAG_MU,
10860                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10861        int userId = app.userId;
10862        if (providers != null) {
10863            int N = providers.size();
10864            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10865            for (int i=0; i<N; i++) {
10866                // TODO: keep logic in sync with installEncryptionUnawareProviders
10867                ProviderInfo cpi =
10868                    (ProviderInfo)providers.get(i);
10869                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10870                        cpi.name, cpi.flags);
10871                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10872                    // This is a singleton provider, but a user besides the
10873                    // default user is asking to initialize a process it runs
10874                    // in...  well, no, it doesn't actually run in this process,
10875                    // it runs in the process of the default user.  Get rid of it.
10876                    providers.remove(i);
10877                    N--;
10878                    i--;
10879                    continue;
10880                }
10881
10882                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10883                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10884                if (cpr == null) {
10885                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10886                    mProviderMap.putProviderByClass(comp, cpr);
10887                }
10888                if (DEBUG_MU) Slog.v(TAG_MU,
10889                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10890                app.pubProviders.put(cpi.name, cpr);
10891                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10892                    // Don't add this if it is a platform component that is marked
10893                    // to run in multiple processes, because this is actually
10894                    // part of the framework so doesn't make sense to track as a
10895                    // separate apk in the process.
10896                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10897                            mProcessStats);
10898                }
10899                notifyPackageUse(cpi.applicationInfo.packageName,
10900                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10901            }
10902        }
10903        return providers;
10904    }
10905
10906    /**
10907     * Check if the calling UID has a possible chance at accessing the provider
10908     * at the given authority and user.
10909     */
10910    public String checkContentProviderAccess(String authority, int userId) {
10911        if (userId == UserHandle.USER_ALL) {
10912            mContext.enforceCallingOrSelfPermission(
10913                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10914            userId = UserHandle.getCallingUserId();
10915        }
10916
10917        ProviderInfo cpi = null;
10918        try {
10919            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10920                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10921                            | PackageManager.MATCH_DISABLED_COMPONENTS
10922                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10923                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10924                    userId);
10925        } catch (RemoteException ignored) {
10926        }
10927        if (cpi == null) {
10928            return "Failed to find provider " + authority + " for user " + userId;
10929        }
10930
10931        ProcessRecord r = null;
10932        synchronized (mPidsSelfLocked) {
10933            r = mPidsSelfLocked.get(Binder.getCallingPid());
10934        }
10935        if (r == null) {
10936            return "Failed to find PID " + Binder.getCallingPid();
10937        }
10938
10939        synchronized (this) {
10940            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10941        }
10942    }
10943
10944    /**
10945     * Check if {@link ProcessRecord} has a possible chance at accessing the
10946     * given {@link ProviderInfo}. Final permission checking is always done
10947     * in {@link ContentProvider}.
10948     */
10949    private final String checkContentProviderPermissionLocked(
10950            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10951        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10952        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10953        boolean checkedGrants = false;
10954        if (checkUser) {
10955            // Looking for cross-user grants before enforcing the typical cross-users permissions
10956            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10957            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10958                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10959                    return null;
10960                }
10961                checkedGrants = true;
10962            }
10963            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10964                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10965            if (userId != tmpTargetUserId) {
10966                // When we actually went to determine the final targer user ID, this ended
10967                // up different than our initial check for the authority.  This is because
10968                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10969                // SELF.  So we need to re-check the grants again.
10970                checkedGrants = false;
10971            }
10972        }
10973        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10974                cpi.applicationInfo.uid, cpi.exported)
10975                == PackageManager.PERMISSION_GRANTED) {
10976            return null;
10977        }
10978        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10979                cpi.applicationInfo.uid, cpi.exported)
10980                == PackageManager.PERMISSION_GRANTED) {
10981            return null;
10982        }
10983
10984        PathPermission[] pps = cpi.pathPermissions;
10985        if (pps != null) {
10986            int i = pps.length;
10987            while (i > 0) {
10988                i--;
10989                PathPermission pp = pps[i];
10990                String pprperm = pp.getReadPermission();
10991                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10992                        cpi.applicationInfo.uid, cpi.exported)
10993                        == PackageManager.PERMISSION_GRANTED) {
10994                    return null;
10995                }
10996                String ppwperm = pp.getWritePermission();
10997                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10998                        cpi.applicationInfo.uid, cpi.exported)
10999                        == PackageManager.PERMISSION_GRANTED) {
11000                    return null;
11001                }
11002            }
11003        }
11004        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11005            return null;
11006        }
11007
11008        String msg;
11009        if (!cpi.exported) {
11010            msg = "Permission Denial: opening provider " + cpi.name
11011                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11012                    + ", uid=" + callingUid + ") that is not exported from uid "
11013                    + cpi.applicationInfo.uid;
11014        } else {
11015            msg = "Permission Denial: opening provider " + cpi.name
11016                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11017                    + ", uid=" + callingUid + ") requires "
11018                    + cpi.readPermission + " or " + cpi.writePermission;
11019        }
11020        Slog.w(TAG, msg);
11021        return msg;
11022    }
11023
11024    /**
11025     * Returns if the ContentProvider has granted a uri to callingUid
11026     */
11027    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11028        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11029        if (perms != null) {
11030            for (int i=perms.size()-1; i>=0; i--) {
11031                GrantUri grantUri = perms.keyAt(i);
11032                if (grantUri.sourceUserId == userId || !checkUser) {
11033                    if (matchesProvider(grantUri.uri, cpi)) {
11034                        return true;
11035                    }
11036                }
11037            }
11038        }
11039        return false;
11040    }
11041
11042    /**
11043     * Returns true if the uri authority is one of the authorities specified in the provider.
11044     */
11045    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11046        String uriAuth = uri.getAuthority();
11047        String cpiAuth = cpi.authority;
11048        if (cpiAuth.indexOf(';') == -1) {
11049            return cpiAuth.equals(uriAuth);
11050        }
11051        String[] cpiAuths = cpiAuth.split(";");
11052        int length = cpiAuths.length;
11053        for (int i = 0; i < length; i++) {
11054            if (cpiAuths[i].equals(uriAuth)) return true;
11055        }
11056        return false;
11057    }
11058
11059    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11060            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11061        if (r != null) {
11062            for (int i=0; i<r.conProviders.size(); i++) {
11063                ContentProviderConnection conn = r.conProviders.get(i);
11064                if (conn.provider == cpr) {
11065                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11066                            "Adding provider requested by "
11067                            + r.processName + " from process "
11068                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11069                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11070                    if (stable) {
11071                        conn.stableCount++;
11072                        conn.numStableIncs++;
11073                    } else {
11074                        conn.unstableCount++;
11075                        conn.numUnstableIncs++;
11076                    }
11077                    return conn;
11078                }
11079            }
11080            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11081            if (stable) {
11082                conn.stableCount = 1;
11083                conn.numStableIncs = 1;
11084            } else {
11085                conn.unstableCount = 1;
11086                conn.numUnstableIncs = 1;
11087            }
11088            cpr.connections.add(conn);
11089            r.conProviders.add(conn);
11090            startAssociationLocked(r.uid, r.processName, r.curProcState,
11091                    cpr.uid, cpr.name, cpr.info.processName);
11092            return conn;
11093        }
11094        cpr.addExternalProcessHandleLocked(externalProcessToken);
11095        return null;
11096    }
11097
11098    boolean decProviderCountLocked(ContentProviderConnection conn,
11099            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11100        if (conn != null) {
11101            cpr = conn.provider;
11102            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11103                    "Removing provider requested by "
11104                    + conn.client.processName + " from process "
11105                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11106                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11107            if (stable) {
11108                conn.stableCount--;
11109            } else {
11110                conn.unstableCount--;
11111            }
11112            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11113                cpr.connections.remove(conn);
11114                conn.client.conProviders.remove(conn);
11115                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11116                    // The client is more important than last activity -- note the time this
11117                    // is happening, so we keep the old provider process around a bit as last
11118                    // activity to avoid thrashing it.
11119                    if (cpr.proc != null) {
11120                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11121                    }
11122                }
11123                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11124                return true;
11125            }
11126            return false;
11127        }
11128        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11129        return false;
11130    }
11131
11132    private void checkTime(long startTime, String where) {
11133        long now = SystemClock.uptimeMillis();
11134        if ((now-startTime) > 50) {
11135            // If we are taking more than 50ms, log about it.
11136            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11137        }
11138    }
11139
11140    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11141            PROC_SPACE_TERM,
11142            PROC_SPACE_TERM|PROC_PARENS,
11143            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11144    };
11145
11146    private final long[] mProcessStateStatsLongs = new long[1];
11147
11148    boolean isProcessAliveLocked(ProcessRecord proc) {
11149        if (proc.procStatFile == null) {
11150            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11151        }
11152        mProcessStateStatsLongs[0] = 0;
11153        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11154                mProcessStateStatsLongs, null)) {
11155            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11156            return false;
11157        }
11158        final long state = mProcessStateStatsLongs[0];
11159        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11160                + (char)state);
11161        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11162    }
11163
11164    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11165            String name, IBinder token, boolean stable, int userId) {
11166        ContentProviderRecord cpr;
11167        ContentProviderConnection conn = null;
11168        ProviderInfo cpi = null;
11169
11170        synchronized(this) {
11171            long startTime = SystemClock.uptimeMillis();
11172
11173            ProcessRecord r = null;
11174            if (caller != null) {
11175                r = getRecordForAppLocked(caller);
11176                if (r == null) {
11177                    throw new SecurityException(
11178                            "Unable to find app for caller " + caller
11179                          + " (pid=" + Binder.getCallingPid()
11180                          + ") when getting content provider " + name);
11181                }
11182            }
11183
11184            boolean checkCrossUser = true;
11185
11186            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11187
11188            // First check if this content provider has been published...
11189            cpr = mProviderMap.getProviderByName(name, userId);
11190            // If that didn't work, check if it exists for user 0 and then
11191            // verify that it's a singleton provider before using it.
11192            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11193                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11194                if (cpr != null) {
11195                    cpi = cpr.info;
11196                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11197                            cpi.name, cpi.flags)
11198                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11199                        userId = UserHandle.USER_SYSTEM;
11200                        checkCrossUser = false;
11201                    } else {
11202                        cpr = null;
11203                        cpi = null;
11204                    }
11205                }
11206            }
11207
11208            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11209            if (providerRunning) {
11210                cpi = cpr.info;
11211                String msg;
11212                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11213                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11214                        != null) {
11215                    throw new SecurityException(msg);
11216                }
11217                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11218
11219                if (r != null && cpr.canRunHere(r)) {
11220                    // This provider has been published or is in the process
11221                    // of being published...  but it is also allowed to run
11222                    // in the caller's process, so don't make a connection
11223                    // and just let the caller instantiate its own instance.
11224                    ContentProviderHolder holder = cpr.newHolder(null);
11225                    // don't give caller the provider object, it needs
11226                    // to make its own.
11227                    holder.provider = null;
11228                    return holder;
11229                }
11230
11231                final long origId = Binder.clearCallingIdentity();
11232
11233                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11234
11235                // In this case the provider instance already exists, so we can
11236                // return it right away.
11237                conn = incProviderCountLocked(r, cpr, token, stable);
11238                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11239                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11240                        // If this is a perceptible app accessing the provider,
11241                        // make sure to count it as being accessed and thus
11242                        // back up on the LRU list.  This is good because
11243                        // content providers are often expensive to start.
11244                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11245                        updateLruProcessLocked(cpr.proc, false, null);
11246                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11247                    }
11248                }
11249
11250                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11251                final int verifiedAdj = cpr.proc.verifiedAdj;
11252                boolean success = updateOomAdjLocked(cpr.proc);
11253                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11254                // if the process has been successfully adjusted.  So to reduce races with
11255                // it, we will check whether the process still exists.  Note that this doesn't
11256                // completely get rid of races with LMK killing the process, but should make
11257                // them much smaller.
11258                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11259                    success = false;
11260                }
11261                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11262                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11263                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11264                // NOTE: there is still a race here where a signal could be
11265                // pending on the process even though we managed to update its
11266                // adj level.  Not sure what to do about this, but at least
11267                // the race is now smaller.
11268                if (!success) {
11269                    // Uh oh...  it looks like the provider's process
11270                    // has been killed on us.  We need to wait for a new
11271                    // process to be started, and make sure its death
11272                    // doesn't kill our process.
11273                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11274                            + " is crashing; detaching " + r);
11275                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11276                    checkTime(startTime, "getContentProviderImpl: before appDied");
11277                    appDiedLocked(cpr.proc);
11278                    checkTime(startTime, "getContentProviderImpl: after appDied");
11279                    if (!lastRef) {
11280                        // This wasn't the last ref our process had on
11281                        // the provider...  we have now been killed, bail.
11282                        return null;
11283                    }
11284                    providerRunning = false;
11285                    conn = null;
11286                } else {
11287                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11288                }
11289
11290                Binder.restoreCallingIdentity(origId);
11291            }
11292
11293            if (!providerRunning) {
11294                try {
11295                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11296                    cpi = AppGlobals.getPackageManager().
11297                        resolveContentProvider(name,
11298                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11299                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11300                } catch (RemoteException ex) {
11301                }
11302                if (cpi == null) {
11303                    return null;
11304                }
11305                // If the provider is a singleton AND
11306                // (it's a call within the same user || the provider is a
11307                // privileged app)
11308                // Then allow connecting to the singleton provider
11309                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11310                        cpi.name, cpi.flags)
11311                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11312                if (singleton) {
11313                    userId = UserHandle.USER_SYSTEM;
11314                }
11315                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11316                checkTime(startTime, "getContentProviderImpl: got app info for user");
11317
11318                String msg;
11319                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11320                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11321                        != null) {
11322                    throw new SecurityException(msg);
11323                }
11324                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11325
11326                if (!mProcessesReady
11327                        && !cpi.processName.equals("system")) {
11328                    // If this content provider does not run in the system
11329                    // process, and the system is not yet ready to run other
11330                    // processes, then fail fast instead of hanging.
11331                    throw new IllegalArgumentException(
11332                            "Attempt to launch content provider before system ready");
11333                }
11334
11335                // Make sure that the user who owns this provider is running.  If not,
11336                // we don't want to allow it to run.
11337                if (!mUserController.isUserRunningLocked(userId, 0)) {
11338                    Slog.w(TAG, "Unable to launch app "
11339                            + cpi.applicationInfo.packageName + "/"
11340                            + cpi.applicationInfo.uid + " for provider "
11341                            + name + ": user " + userId + " is stopped");
11342                    return null;
11343                }
11344
11345                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11346                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11347                cpr = mProviderMap.getProviderByClass(comp, userId);
11348                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11349                final boolean firstClass = cpr == null;
11350                if (firstClass) {
11351                    final long ident = Binder.clearCallingIdentity();
11352
11353                    // If permissions need a review before any of the app components can run,
11354                    // we return no provider and launch a review activity if the calling app
11355                    // is in the foreground.
11356                    if (mPermissionReviewRequired) {
11357                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11358                            return null;
11359                        }
11360                    }
11361
11362                    try {
11363                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11364                        ApplicationInfo ai =
11365                            AppGlobals.getPackageManager().
11366                                getApplicationInfo(
11367                                        cpi.applicationInfo.packageName,
11368                                        STOCK_PM_FLAGS, userId);
11369                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11370                        if (ai == null) {
11371                            Slog.w(TAG, "No package info for content provider "
11372                                    + cpi.name);
11373                            return null;
11374                        }
11375                        ai = getAppInfoForUser(ai, userId);
11376                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11377                    } catch (RemoteException ex) {
11378                        // pm is in same process, this will never happen.
11379                    } finally {
11380                        Binder.restoreCallingIdentity(ident);
11381                    }
11382                }
11383
11384                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11385
11386                if (r != null && cpr.canRunHere(r)) {
11387                    // If this is a multiprocess provider, then just return its
11388                    // info and allow the caller to instantiate it.  Only do
11389                    // this if the provider is the same user as the caller's
11390                    // process, or can run as root (so can be in any process).
11391                    return cpr.newHolder(null);
11392                }
11393
11394                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11395                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11396                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11397
11398                // This is single process, and our app is now connecting to it.
11399                // See if we are already in the process of launching this
11400                // provider.
11401                final int N = mLaunchingProviders.size();
11402                int i;
11403                for (i = 0; i < N; i++) {
11404                    if (mLaunchingProviders.get(i) == cpr) {
11405                        break;
11406                    }
11407                }
11408
11409                // If the provider is not already being launched, then get it
11410                // started.
11411                if (i >= N) {
11412                    final long origId = Binder.clearCallingIdentity();
11413
11414                    try {
11415                        // Content provider is now in use, its package can't be stopped.
11416                        try {
11417                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11418                            AppGlobals.getPackageManager().setPackageStoppedState(
11419                                    cpr.appInfo.packageName, false, userId);
11420                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11421                        } catch (RemoteException e) {
11422                        } catch (IllegalArgumentException e) {
11423                            Slog.w(TAG, "Failed trying to unstop package "
11424                                    + cpr.appInfo.packageName + ": " + e);
11425                        }
11426
11427                        // Use existing process if already started
11428                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11429                        ProcessRecord proc = getProcessRecordLocked(
11430                                cpi.processName, cpr.appInfo.uid, false);
11431                        if (proc != null && proc.thread != null && !proc.killed) {
11432                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11433                                    "Installing in existing process " + proc);
11434                            if (!proc.pubProviders.containsKey(cpi.name)) {
11435                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11436                                proc.pubProviders.put(cpi.name, cpr);
11437                                try {
11438                                    proc.thread.scheduleInstallProvider(cpi);
11439                                } catch (RemoteException e) {
11440                                }
11441                            }
11442                        } else {
11443                            checkTime(startTime, "getContentProviderImpl: before start process");
11444                            proc = startProcessLocked(cpi.processName,
11445                                    cpr.appInfo, false, 0, "content provider",
11446                                    new ComponentName(cpi.applicationInfo.packageName,
11447                                            cpi.name), false, false, false);
11448                            checkTime(startTime, "getContentProviderImpl: after start process");
11449                            if (proc == null) {
11450                                Slog.w(TAG, "Unable to launch app "
11451                                        + cpi.applicationInfo.packageName + "/"
11452                                        + cpi.applicationInfo.uid + " for provider "
11453                                        + name + ": process is bad");
11454                                return null;
11455                            }
11456                        }
11457                        cpr.launchingApp = proc;
11458                        mLaunchingProviders.add(cpr);
11459                    } finally {
11460                        Binder.restoreCallingIdentity(origId);
11461                    }
11462                }
11463
11464                checkTime(startTime, "getContentProviderImpl: updating data structures");
11465
11466                // Make sure the provider is published (the same provider class
11467                // may be published under multiple names).
11468                if (firstClass) {
11469                    mProviderMap.putProviderByClass(comp, cpr);
11470                }
11471
11472                mProviderMap.putProviderByName(name, cpr);
11473                conn = incProviderCountLocked(r, cpr, token, stable);
11474                if (conn != null) {
11475                    conn.waiting = true;
11476                }
11477            }
11478            checkTime(startTime, "getContentProviderImpl: done!");
11479        }
11480
11481        // Wait for the provider to be published...
11482        synchronized (cpr) {
11483            while (cpr.provider == null) {
11484                if (cpr.launchingApp == null) {
11485                    Slog.w(TAG, "Unable to launch app "
11486                            + cpi.applicationInfo.packageName + "/"
11487                            + cpi.applicationInfo.uid + " for provider "
11488                            + name + ": launching app became null");
11489                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11490                            UserHandle.getUserId(cpi.applicationInfo.uid),
11491                            cpi.applicationInfo.packageName,
11492                            cpi.applicationInfo.uid, name);
11493                    return null;
11494                }
11495                try {
11496                    if (DEBUG_MU) Slog.v(TAG_MU,
11497                            "Waiting to start provider " + cpr
11498                            + " launchingApp=" + cpr.launchingApp);
11499                    if (conn != null) {
11500                        conn.waiting = true;
11501                    }
11502                    cpr.wait();
11503                } catch (InterruptedException ex) {
11504                } finally {
11505                    if (conn != null) {
11506                        conn.waiting = false;
11507                    }
11508                }
11509            }
11510        }
11511        return cpr != null ? cpr.newHolder(conn) : null;
11512    }
11513
11514    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11515            ProcessRecord r, final int userId) {
11516        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11517                cpi.packageName, userId)) {
11518
11519            final boolean callerForeground = r == null || r.setSchedGroup
11520                    != ProcessList.SCHED_GROUP_BACKGROUND;
11521
11522            // Show a permission review UI only for starting from a foreground app
11523            if (!callerForeground) {
11524                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11525                        + cpi.packageName + " requires a permissions review");
11526                return false;
11527            }
11528
11529            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11530            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11531                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11532            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11533
11534            if (DEBUG_PERMISSIONS_REVIEW) {
11535                Slog.i(TAG, "u" + userId + " Launching permission review "
11536                        + "for package " + cpi.packageName);
11537            }
11538
11539            final UserHandle userHandle = new UserHandle(userId);
11540            mHandler.post(new Runnable() {
11541                @Override
11542                public void run() {
11543                    mContext.startActivityAsUser(intent, userHandle);
11544                }
11545            });
11546
11547            return false;
11548        }
11549
11550        return true;
11551    }
11552
11553    PackageManagerInternal getPackageManagerInternalLocked() {
11554        if (mPackageManagerInt == null) {
11555            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11556        }
11557        return mPackageManagerInt;
11558    }
11559
11560    @Override
11561    public final ContentProviderHolder getContentProvider(
11562            IApplicationThread caller, String name, int userId, boolean stable) {
11563        enforceNotIsolatedCaller("getContentProvider");
11564        if (caller == null) {
11565            String msg = "null IApplicationThread when getting content provider "
11566                    + name;
11567            Slog.w(TAG, msg);
11568            throw new SecurityException(msg);
11569        }
11570        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11571        // with cross-user grant.
11572        return getContentProviderImpl(caller, name, null, stable, userId);
11573    }
11574
11575    public ContentProviderHolder getContentProviderExternal(
11576            String name, int userId, IBinder token) {
11577        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11578            "Do not have permission in call getContentProviderExternal()");
11579        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11580                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11581        return getContentProviderExternalUnchecked(name, token, userId);
11582    }
11583
11584    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11585            IBinder token, int userId) {
11586        return getContentProviderImpl(null, name, token, true, userId);
11587    }
11588
11589    /**
11590     * Drop a content provider from a ProcessRecord's bookkeeping
11591     */
11592    public void removeContentProvider(IBinder connection, boolean stable) {
11593        enforceNotIsolatedCaller("removeContentProvider");
11594        long ident = Binder.clearCallingIdentity();
11595        try {
11596            synchronized (this) {
11597                ContentProviderConnection conn;
11598                try {
11599                    conn = (ContentProviderConnection)connection;
11600                } catch (ClassCastException e) {
11601                    String msg ="removeContentProvider: " + connection
11602                            + " not a ContentProviderConnection";
11603                    Slog.w(TAG, msg);
11604                    throw new IllegalArgumentException(msg);
11605                }
11606                if (conn == null) {
11607                    throw new NullPointerException("connection is null");
11608                }
11609                if (decProviderCountLocked(conn, null, null, stable)) {
11610                    updateOomAdjLocked();
11611                }
11612            }
11613        } finally {
11614            Binder.restoreCallingIdentity(ident);
11615        }
11616    }
11617
11618    public void removeContentProviderExternal(String name, IBinder token) {
11619        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11620            "Do not have permission in call removeContentProviderExternal()");
11621        int userId = UserHandle.getCallingUserId();
11622        long ident = Binder.clearCallingIdentity();
11623        try {
11624            removeContentProviderExternalUnchecked(name, token, userId);
11625        } finally {
11626            Binder.restoreCallingIdentity(ident);
11627        }
11628    }
11629
11630    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11631        synchronized (this) {
11632            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11633            if(cpr == null) {
11634                //remove from mProvidersByClass
11635                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11636                return;
11637            }
11638
11639            //update content provider record entry info
11640            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11641            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11642            if (localCpr.hasExternalProcessHandles()) {
11643                if (localCpr.removeExternalProcessHandleLocked(token)) {
11644                    updateOomAdjLocked();
11645                } else {
11646                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11647                            + " with no external reference for token: "
11648                            + token + ".");
11649                }
11650            } else {
11651                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11652                        + " with no external references.");
11653            }
11654        }
11655    }
11656
11657    public final void publishContentProviders(IApplicationThread caller,
11658            List<ContentProviderHolder> providers) {
11659        if (providers == null) {
11660            return;
11661        }
11662
11663        enforceNotIsolatedCaller("publishContentProviders");
11664        synchronized (this) {
11665            final ProcessRecord r = getRecordForAppLocked(caller);
11666            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11667            if (r == null) {
11668                throw new SecurityException(
11669                        "Unable to find app for caller " + caller
11670                      + " (pid=" + Binder.getCallingPid()
11671                      + ") when publishing content providers");
11672            }
11673
11674            final long origId = Binder.clearCallingIdentity();
11675
11676            final int N = providers.size();
11677            for (int i = 0; i < N; i++) {
11678                ContentProviderHolder src = providers.get(i);
11679                if (src == null || src.info == null || src.provider == null) {
11680                    continue;
11681                }
11682                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11683                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11684                if (dst != null) {
11685                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11686                    mProviderMap.putProviderByClass(comp, dst);
11687                    String names[] = dst.info.authority.split(";");
11688                    for (int j = 0; j < names.length; j++) {
11689                        mProviderMap.putProviderByName(names[j], dst);
11690                    }
11691
11692                    int launchingCount = mLaunchingProviders.size();
11693                    int j;
11694                    boolean wasInLaunchingProviders = false;
11695                    for (j = 0; j < launchingCount; j++) {
11696                        if (mLaunchingProviders.get(j) == dst) {
11697                            mLaunchingProviders.remove(j);
11698                            wasInLaunchingProviders = true;
11699                            j--;
11700                            launchingCount--;
11701                        }
11702                    }
11703                    if (wasInLaunchingProviders) {
11704                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11705                    }
11706                    synchronized (dst) {
11707                        dst.provider = src.provider;
11708                        dst.proc = r;
11709                        dst.notifyAll();
11710                    }
11711                    updateOomAdjLocked(r);
11712                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11713                            src.info.authority);
11714                }
11715            }
11716
11717            Binder.restoreCallingIdentity(origId);
11718        }
11719    }
11720
11721    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11722        ContentProviderConnection conn;
11723        try {
11724            conn = (ContentProviderConnection)connection;
11725        } catch (ClassCastException e) {
11726            String msg ="refContentProvider: " + connection
11727                    + " not a ContentProviderConnection";
11728            Slog.w(TAG, msg);
11729            throw new IllegalArgumentException(msg);
11730        }
11731        if (conn == null) {
11732            throw new NullPointerException("connection is null");
11733        }
11734
11735        synchronized (this) {
11736            if (stable > 0) {
11737                conn.numStableIncs += stable;
11738            }
11739            stable = conn.stableCount + stable;
11740            if (stable < 0) {
11741                throw new IllegalStateException("stableCount < 0: " + stable);
11742            }
11743
11744            if (unstable > 0) {
11745                conn.numUnstableIncs += unstable;
11746            }
11747            unstable = conn.unstableCount + unstable;
11748            if (unstable < 0) {
11749                throw new IllegalStateException("unstableCount < 0: " + unstable);
11750            }
11751
11752            if ((stable+unstable) <= 0) {
11753                throw new IllegalStateException("ref counts can't go to zero here: stable="
11754                        + stable + " unstable=" + unstable);
11755            }
11756            conn.stableCount = stable;
11757            conn.unstableCount = unstable;
11758            return !conn.dead;
11759        }
11760    }
11761
11762    public void unstableProviderDied(IBinder connection) {
11763        ContentProviderConnection conn;
11764        try {
11765            conn = (ContentProviderConnection)connection;
11766        } catch (ClassCastException e) {
11767            String msg ="refContentProvider: " + connection
11768                    + " not a ContentProviderConnection";
11769            Slog.w(TAG, msg);
11770            throw new IllegalArgumentException(msg);
11771        }
11772        if (conn == null) {
11773            throw new NullPointerException("connection is null");
11774        }
11775
11776        // Safely retrieve the content provider associated with the connection.
11777        IContentProvider provider;
11778        synchronized (this) {
11779            provider = conn.provider.provider;
11780        }
11781
11782        if (provider == null) {
11783            // Um, yeah, we're way ahead of you.
11784            return;
11785        }
11786
11787        // Make sure the caller is being honest with us.
11788        if (provider.asBinder().pingBinder()) {
11789            // Er, no, still looks good to us.
11790            synchronized (this) {
11791                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11792                        + " says " + conn + " died, but we don't agree");
11793                return;
11794            }
11795        }
11796
11797        // Well look at that!  It's dead!
11798        synchronized (this) {
11799            if (conn.provider.provider != provider) {
11800                // But something changed...  good enough.
11801                return;
11802            }
11803
11804            ProcessRecord proc = conn.provider.proc;
11805            if (proc == null || proc.thread == null) {
11806                // Seems like the process is already cleaned up.
11807                return;
11808            }
11809
11810            // As far as we're concerned, this is just like receiving a
11811            // death notification...  just a bit prematurely.
11812            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11813                    + ") early provider death");
11814            final long ident = Binder.clearCallingIdentity();
11815            try {
11816                appDiedLocked(proc);
11817            } finally {
11818                Binder.restoreCallingIdentity(ident);
11819            }
11820        }
11821    }
11822
11823    @Override
11824    public void appNotRespondingViaProvider(IBinder connection) {
11825        enforceCallingPermission(
11826                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11827
11828        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11829        if (conn == null) {
11830            Slog.w(TAG, "ContentProviderConnection is null");
11831            return;
11832        }
11833
11834        final ProcessRecord host = conn.provider.proc;
11835        if (host == null) {
11836            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11837            return;
11838        }
11839
11840        mHandler.post(new Runnable() {
11841            @Override
11842            public void run() {
11843                mAppErrors.appNotResponding(host, null, null, false,
11844                        "ContentProvider not responding");
11845            }
11846        });
11847    }
11848
11849    public final void installSystemProviders() {
11850        List<ProviderInfo> providers;
11851        synchronized (this) {
11852            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11853            providers = generateApplicationProvidersLocked(app);
11854            if (providers != null) {
11855                for (int i=providers.size()-1; i>=0; i--) {
11856                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11857                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11858                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11859                                + ": not system .apk");
11860                        providers.remove(i);
11861                    }
11862                }
11863            }
11864        }
11865        if (providers != null) {
11866            mSystemThread.installSystemProviders(providers);
11867        }
11868
11869        mConstants.start(mContext.getContentResolver());
11870        mCoreSettingsObserver = new CoreSettingsObserver(this);
11871        mFontScaleSettingObserver = new FontScaleSettingObserver();
11872
11873        // Now that the settings provider is published we can consider sending
11874        // in a rescue party.
11875        RescueParty.onSettingsProviderPublished(mContext);
11876
11877        //mUsageStatsService.monitorPackages();
11878    }
11879
11880    private void startPersistentApps(int matchFlags) {
11881        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11882
11883        synchronized (this) {
11884            try {
11885                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11886                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11887                for (ApplicationInfo app : apps) {
11888                    if (!"android".equals(app.packageName)) {
11889                        addAppLocked(app, null, false, null /* ABI override */);
11890                    }
11891                }
11892            } catch (RemoteException ex) {
11893            }
11894        }
11895    }
11896
11897    /**
11898     * When a user is unlocked, we need to install encryption-unaware providers
11899     * belonging to any running apps.
11900     */
11901    private void installEncryptionUnawareProviders(int userId) {
11902        // We're only interested in providers that are encryption unaware, and
11903        // we don't care about uninstalled apps, since there's no way they're
11904        // running at this point.
11905        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11906
11907        synchronized (this) {
11908            final int NP = mProcessNames.getMap().size();
11909            for (int ip = 0; ip < NP; ip++) {
11910                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11911                final int NA = apps.size();
11912                for (int ia = 0; ia < NA; ia++) {
11913                    final ProcessRecord app = apps.valueAt(ia);
11914                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11915
11916                    final int NG = app.pkgList.size();
11917                    for (int ig = 0; ig < NG; ig++) {
11918                        try {
11919                            final String pkgName = app.pkgList.keyAt(ig);
11920                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11921                                    .getPackageInfo(pkgName, matchFlags, userId);
11922                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11923                                for (ProviderInfo pi : pkgInfo.providers) {
11924                                    // TODO: keep in sync with generateApplicationProvidersLocked
11925                                    final boolean processMatch = Objects.equals(pi.processName,
11926                                            app.processName) || pi.multiprocess;
11927                                    final boolean userMatch = isSingleton(pi.processName,
11928                                            pi.applicationInfo, pi.name, pi.flags)
11929                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11930                                    if (processMatch && userMatch) {
11931                                        Log.v(TAG, "Installing " + pi);
11932                                        app.thread.scheduleInstallProvider(pi);
11933                                    } else {
11934                                        Log.v(TAG, "Skipping " + pi);
11935                                    }
11936                                }
11937                            }
11938                        } catch (RemoteException ignored) {
11939                        }
11940                    }
11941                }
11942            }
11943        }
11944    }
11945
11946    /**
11947     * Allows apps to retrieve the MIME type of a URI.
11948     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11949     * users, then it does not need permission to access the ContentProvider.
11950     * Either, it needs cross-user uri grants.
11951     *
11952     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11953     *
11954     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11955     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11956     */
11957    public String getProviderMimeType(Uri uri, int userId) {
11958        enforceNotIsolatedCaller("getProviderMimeType");
11959        final String name = uri.getAuthority();
11960        int callingUid = Binder.getCallingUid();
11961        int callingPid = Binder.getCallingPid();
11962        long ident = 0;
11963        boolean clearedIdentity = false;
11964        synchronized (this) {
11965            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11966        }
11967        if (canClearIdentity(callingPid, callingUid, userId)) {
11968            clearedIdentity = true;
11969            ident = Binder.clearCallingIdentity();
11970        }
11971        ContentProviderHolder holder = null;
11972        try {
11973            holder = getContentProviderExternalUnchecked(name, null, userId);
11974            if (holder != null) {
11975                return holder.provider.getType(uri);
11976            }
11977        } catch (RemoteException e) {
11978            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11979            return null;
11980        } catch (Exception e) {
11981            Log.w(TAG, "Exception while determining type of " + uri, e);
11982            return null;
11983        } finally {
11984            // We need to clear the identity to call removeContentProviderExternalUnchecked
11985            if (!clearedIdentity) {
11986                ident = Binder.clearCallingIdentity();
11987            }
11988            try {
11989                if (holder != null) {
11990                    removeContentProviderExternalUnchecked(name, null, userId);
11991                }
11992            } finally {
11993                Binder.restoreCallingIdentity(ident);
11994            }
11995        }
11996
11997        return null;
11998    }
11999
12000    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12001        if (UserHandle.getUserId(callingUid) == userId) {
12002            return true;
12003        }
12004        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12005                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12006                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12007                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12008                return true;
12009        }
12010        return false;
12011    }
12012
12013    // =========================================================
12014    // GLOBAL MANAGEMENT
12015    // =========================================================
12016
12017    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12018            boolean isolated, int isolatedUid) {
12019        String proc = customProcess != null ? customProcess : info.processName;
12020        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12021        final int userId = UserHandle.getUserId(info.uid);
12022        int uid = info.uid;
12023        if (isolated) {
12024            if (isolatedUid == 0) {
12025                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
12026                while (true) {
12027                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
12028                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
12029                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
12030                    }
12031                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12032                    mNextIsolatedProcessUid++;
12033                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12034                        // No process for this uid, use it.
12035                        break;
12036                    }
12037                    stepsLeft--;
12038                    if (stepsLeft <= 0) {
12039                        return null;
12040                    }
12041                }
12042            } else {
12043                // Special case for startIsolatedProcess (internal only), where
12044                // the uid of the isolated process is specified by the caller.
12045                uid = isolatedUid;
12046            }
12047
12048            // Register the isolated UID with this application so BatteryStats knows to
12049            // attribute resource usage to the application.
12050            //
12051            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12052            // about the process state of the isolated UID *before* it is registered with the
12053            // owning application.
12054            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12055        }
12056        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12057        if (!mBooted && !mBooting
12058                && userId == UserHandle.USER_SYSTEM
12059                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12060            r.persistent = true;
12061            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12062        }
12063        addProcessNameLocked(r);
12064        return r;
12065    }
12066
12067    private boolean uidOnBackgroundWhitelist(final int uid) {
12068        final int N = mBackgroundUidWhitelist.length;
12069        for (int i = 0; i < N; i++) {
12070            if (uid == mBackgroundUidWhitelist[i]) {
12071                return true;
12072            }
12073        }
12074        return false;
12075    }
12076
12077    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12078            String abiOverride) {
12079        ProcessRecord app;
12080        if (!isolated) {
12081            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12082                    info.uid, true);
12083        } else {
12084            app = null;
12085        }
12086
12087        if (app == null) {
12088            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12089            updateLruProcessLocked(app, false, null);
12090            updateOomAdjLocked();
12091        }
12092
12093        // This package really, really can not be stopped.
12094        try {
12095            AppGlobals.getPackageManager().setPackageStoppedState(
12096                    info.packageName, false, UserHandle.getUserId(app.uid));
12097        } catch (RemoteException e) {
12098        } catch (IllegalArgumentException e) {
12099            Slog.w(TAG, "Failed trying to unstop package "
12100                    + info.packageName + ": " + e);
12101        }
12102
12103        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12104            app.persistent = true;
12105            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12106        }
12107        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12108            mPersistentStartingProcesses.add(app);
12109            startProcessLocked(app, "added application",
12110                    customProcess != null ? customProcess : app.processName, abiOverride,
12111                    null /* entryPoint */, null /* entryPointArgs */);
12112        }
12113
12114        return app;
12115    }
12116
12117    public void unhandledBack() {
12118        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12119                "unhandledBack()");
12120
12121        synchronized(this) {
12122            final long origId = Binder.clearCallingIdentity();
12123            try {
12124                getFocusedStack().unhandledBackLocked();
12125            } finally {
12126                Binder.restoreCallingIdentity(origId);
12127            }
12128        }
12129    }
12130
12131    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12132        enforceNotIsolatedCaller("openContentUri");
12133        final int userId = UserHandle.getCallingUserId();
12134        final Uri uri = Uri.parse(uriString);
12135        String name = uri.getAuthority();
12136        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12137        ParcelFileDescriptor pfd = null;
12138        if (cph != null) {
12139            // We record the binder invoker's uid in thread-local storage before
12140            // going to the content provider to open the file.  Later, in the code
12141            // that handles all permissions checks, we look for this uid and use
12142            // that rather than the Activity Manager's own uid.  The effect is that
12143            // we do the check against the caller's permissions even though it looks
12144            // to the content provider like the Activity Manager itself is making
12145            // the request.
12146            Binder token = new Binder();
12147            sCallerIdentity.set(new Identity(
12148                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12149            try {
12150                pfd = cph.provider.openFile(null, uri, "r", null, token);
12151            } catch (FileNotFoundException e) {
12152                // do nothing; pfd will be returned null
12153            } finally {
12154                // Ensure that whatever happens, we clean up the identity state
12155                sCallerIdentity.remove();
12156                // Ensure we're done with the provider.
12157                removeContentProviderExternalUnchecked(name, null, userId);
12158            }
12159        } else {
12160            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12161        }
12162        return pfd;
12163    }
12164
12165    // Actually is sleeping or shutting down or whatever else in the future
12166    // is an inactive state.
12167    boolean isSleepingOrShuttingDownLocked() {
12168        return isSleepingLocked() || mShuttingDown;
12169    }
12170
12171    boolean isShuttingDownLocked() {
12172        return mShuttingDown;
12173    }
12174
12175    boolean isSleepingLocked() {
12176        return mSleeping;
12177    }
12178
12179    void onWakefulnessChanged(int wakefulness) {
12180        synchronized(this) {
12181            mWakefulness = wakefulness;
12182            updateSleepIfNeededLocked();
12183        }
12184    }
12185
12186    void finishRunningVoiceLocked() {
12187        if (mRunningVoice != null) {
12188            mRunningVoice = null;
12189            mVoiceWakeLock.release();
12190            updateSleepIfNeededLocked();
12191        }
12192    }
12193
12194    void startTimeTrackingFocusedActivityLocked() {
12195        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12196        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12197            mCurAppTimeTracker.start(resumedActivity.packageName);
12198        }
12199    }
12200
12201    void updateSleepIfNeededLocked() {
12202        if (mSleeping && !shouldSleepLocked()) {
12203            mSleeping = false;
12204            startTimeTrackingFocusedActivityLocked();
12205            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12206            mStackSupervisor.comeOutOfSleepIfNeededLocked();
12207            sendNotifyVrManagerOfSleepState(false);
12208            updateOomAdjLocked();
12209        } else if (!mSleeping && shouldSleepLocked()) {
12210            mSleeping = true;
12211            if (mCurAppTimeTracker != null) {
12212                mCurAppTimeTracker.stop();
12213            }
12214            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12215            mStackSupervisor.goingToSleepLocked();
12216            sendNotifyVrManagerOfSleepState(true);
12217            updateOomAdjLocked();
12218
12219            // Initialize the wake times of all processes.
12220            checkExcessivePowerUsageLocked(false);
12221            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12222            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12223            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
12224        }
12225    }
12226
12227    private boolean shouldSleepLocked() {
12228        // Resume applications while running a voice interactor.
12229        if (mRunningVoice != null) {
12230            return false;
12231        }
12232
12233        // TODO: Transform the lock screen state into a sleep token instead.
12234        switch (mWakefulness) {
12235            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12236            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12237            case PowerManagerInternal.WAKEFULNESS_DOZING:
12238                // Pause applications whenever the lock screen is shown or any sleep
12239                // tokens have been acquired.
12240                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12241            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12242            default:
12243                // If we're asleep then pause applications unconditionally.
12244                return true;
12245        }
12246    }
12247
12248    /** Pokes the task persister. */
12249    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12250        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12251    }
12252
12253    /** Notifies all listeners when the pinned stack animation starts. */
12254    @Override
12255    public void notifyPinnedStackAnimationStarted() {
12256        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12257    }
12258
12259    /** Notifies all listeners when the pinned stack animation ends. */
12260    @Override
12261    public void notifyPinnedStackAnimationEnded() {
12262        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12263    }
12264
12265    @Override
12266    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12267        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12268    }
12269
12270    @Override
12271    public boolean shutdown(int timeout) {
12272        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12273                != PackageManager.PERMISSION_GRANTED) {
12274            throw new SecurityException("Requires permission "
12275                    + android.Manifest.permission.SHUTDOWN);
12276        }
12277
12278        boolean timedout = false;
12279
12280        synchronized(this) {
12281            mShuttingDown = true;
12282            updateEventDispatchingLocked();
12283            timedout = mStackSupervisor.shutdownLocked(timeout);
12284        }
12285
12286        mAppOpsService.shutdown();
12287        if (mUsageStatsService != null) {
12288            mUsageStatsService.prepareShutdown();
12289        }
12290        mBatteryStatsService.shutdown();
12291        synchronized (this) {
12292            mProcessStats.shutdownLocked();
12293            notifyTaskPersisterLocked(null, true);
12294        }
12295
12296        return timedout;
12297    }
12298
12299    public final void activitySlept(IBinder token) {
12300        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12301
12302        final long origId = Binder.clearCallingIdentity();
12303
12304        synchronized (this) {
12305            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12306            if (r != null) {
12307                mStackSupervisor.activitySleptLocked(r);
12308            }
12309        }
12310
12311        Binder.restoreCallingIdentity(origId);
12312    }
12313
12314    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12315        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12316        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12317        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12318            boolean wasRunningVoice = mRunningVoice != null;
12319            mRunningVoice = session;
12320            if (!wasRunningVoice) {
12321                mVoiceWakeLock.acquire();
12322                updateSleepIfNeededLocked();
12323            }
12324        }
12325    }
12326
12327    private void updateEventDispatchingLocked() {
12328        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12329    }
12330
12331    @Override
12332    public void setLockScreenShown(boolean showing) {
12333        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12334                != PackageManager.PERMISSION_GRANTED) {
12335            throw new SecurityException("Requires permission "
12336                    + android.Manifest.permission.DEVICE_POWER);
12337        }
12338
12339        synchronized(this) {
12340            long ident = Binder.clearCallingIdentity();
12341            try {
12342                mKeyguardController.setKeyguardShown(showing);
12343            } finally {
12344                Binder.restoreCallingIdentity(ident);
12345            }
12346        }
12347    }
12348
12349    @Override
12350    public void notifyLockedProfile(@UserIdInt int userId) {
12351        try {
12352            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12353                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12354            }
12355        } catch (RemoteException ex) {
12356            throw new SecurityException("Fail to check is caller a privileged app", ex);
12357        }
12358
12359        synchronized (this) {
12360            final long ident = Binder.clearCallingIdentity();
12361            try {
12362                if (mUserController.shouldConfirmCredentials(userId)) {
12363                    if (mKeyguardController.isKeyguardLocked()) {
12364                        // Showing launcher to avoid user entering credential twice.
12365                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12366                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12367                    }
12368                    mStackSupervisor.lockAllProfileTasks(userId);
12369                }
12370            } finally {
12371                Binder.restoreCallingIdentity(ident);
12372            }
12373        }
12374    }
12375
12376    @Override
12377    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12378        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12379        synchronized (this) {
12380            final long ident = Binder.clearCallingIdentity();
12381            try {
12382                mActivityStarter.startConfirmCredentialIntent(intent, options);
12383            } finally {
12384                Binder.restoreCallingIdentity(ident);
12385            }
12386        }
12387    }
12388
12389    @Override
12390    public void stopAppSwitches() {
12391        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12392                != PackageManager.PERMISSION_GRANTED) {
12393            throw new SecurityException("viewquires permission "
12394                    + android.Manifest.permission.STOP_APP_SWITCHES);
12395        }
12396
12397        synchronized(this) {
12398            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12399                    + APP_SWITCH_DELAY_TIME;
12400            mDidAppSwitch = false;
12401            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12402            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12403            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12404        }
12405    }
12406
12407    public void resumeAppSwitches() {
12408        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12409                != PackageManager.PERMISSION_GRANTED) {
12410            throw new SecurityException("Requires permission "
12411                    + android.Manifest.permission.STOP_APP_SWITCHES);
12412        }
12413
12414        synchronized(this) {
12415            // Note that we don't execute any pending app switches... we will
12416            // let those wait until either the timeout, or the next start
12417            // activity request.
12418            mAppSwitchesAllowedTime = 0;
12419        }
12420    }
12421
12422    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12423            int callingPid, int callingUid, String name) {
12424        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12425            return true;
12426        }
12427
12428        int perm = checkComponentPermission(
12429                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12430                sourceUid, -1, true);
12431        if (perm == PackageManager.PERMISSION_GRANTED) {
12432            return true;
12433        }
12434
12435        // If the actual IPC caller is different from the logical source, then
12436        // also see if they are allowed to control app switches.
12437        if (callingUid != -1 && callingUid != sourceUid) {
12438            perm = checkComponentPermission(
12439                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12440                    callingUid, -1, true);
12441            if (perm == PackageManager.PERMISSION_GRANTED) {
12442                return true;
12443            }
12444        }
12445
12446        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12447        return false;
12448    }
12449
12450    public void setDebugApp(String packageName, boolean waitForDebugger,
12451            boolean persistent) {
12452        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12453                "setDebugApp()");
12454
12455        long ident = Binder.clearCallingIdentity();
12456        try {
12457            // Note that this is not really thread safe if there are multiple
12458            // callers into it at the same time, but that's not a situation we
12459            // care about.
12460            if (persistent) {
12461                final ContentResolver resolver = mContext.getContentResolver();
12462                Settings.Global.putString(
12463                    resolver, Settings.Global.DEBUG_APP,
12464                    packageName);
12465                Settings.Global.putInt(
12466                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12467                    waitForDebugger ? 1 : 0);
12468            }
12469
12470            synchronized (this) {
12471                if (!persistent) {
12472                    mOrigDebugApp = mDebugApp;
12473                    mOrigWaitForDebugger = mWaitForDebugger;
12474                }
12475                mDebugApp = packageName;
12476                mWaitForDebugger = waitForDebugger;
12477                mDebugTransient = !persistent;
12478                if (packageName != null) {
12479                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12480                            false, UserHandle.USER_ALL, "set debug app");
12481                }
12482            }
12483        } finally {
12484            Binder.restoreCallingIdentity(ident);
12485        }
12486    }
12487
12488    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12489        synchronized (this) {
12490            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12491            if (!isDebuggable) {
12492                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12493                    throw new SecurityException("Process not debuggable: " + app.packageName);
12494                }
12495            }
12496
12497            mTrackAllocationApp = processName;
12498        }
12499    }
12500
12501    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12502        synchronized (this) {
12503            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12504            if (!isDebuggable) {
12505                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12506                    throw new SecurityException("Process not debuggable: " + app.packageName);
12507                }
12508            }
12509            mProfileApp = processName;
12510            mProfileFile = profilerInfo.profileFile;
12511            if (mProfileFd != null) {
12512                try {
12513                    mProfileFd.close();
12514                } catch (IOException e) {
12515                }
12516                mProfileFd = null;
12517            }
12518            mProfileFd = profilerInfo.profileFd;
12519            mSamplingInterval = profilerInfo.samplingInterval;
12520            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12521            mStreamingOutput = profilerInfo.streamingOutput;
12522            mProfileType = 0;
12523        }
12524    }
12525
12526    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12527        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12528        if (!isDebuggable) {
12529            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12530                throw new SecurityException("Process not debuggable: " + app.packageName);
12531            }
12532        }
12533        mNativeDebuggingApp = processName;
12534    }
12535
12536    @Override
12537    public void setAlwaysFinish(boolean enabled) {
12538        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12539                "setAlwaysFinish()");
12540
12541        long ident = Binder.clearCallingIdentity();
12542        try {
12543            Settings.Global.putInt(
12544                    mContext.getContentResolver(),
12545                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12546
12547            synchronized (this) {
12548                mAlwaysFinishActivities = enabled;
12549            }
12550        } finally {
12551            Binder.restoreCallingIdentity(ident);
12552        }
12553    }
12554
12555    @Override
12556    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12557        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12558                "setActivityController()");
12559        synchronized (this) {
12560            mController = controller;
12561            mControllerIsAMonkey = imAMonkey;
12562            Watchdog.getInstance().setActivityController(controller);
12563        }
12564    }
12565
12566    @Override
12567    public void setUserIsMonkey(boolean userIsMonkey) {
12568        synchronized (this) {
12569            synchronized (mPidsSelfLocked) {
12570                final int callingPid = Binder.getCallingPid();
12571                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12572                if (proc == null) {
12573                    throw new SecurityException("Unknown process: " + callingPid);
12574                }
12575                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12576                    throw new SecurityException("Only an instrumentation process "
12577                            + "with a UiAutomation can call setUserIsMonkey");
12578                }
12579            }
12580            mUserIsMonkey = userIsMonkey;
12581        }
12582    }
12583
12584    @Override
12585    public boolean isUserAMonkey() {
12586        synchronized (this) {
12587            // If there is a controller also implies the user is a monkey.
12588            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12589        }
12590    }
12591
12592    /**
12593     * @deprecated This method is only used by a few internal components and it will soon be
12594     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12595     * No new code should be calling it.
12596     */
12597    @Deprecated
12598    public void requestBugReport(int bugreportType) {
12599        String extraOptions = null;
12600        switch (bugreportType) {
12601            case ActivityManager.BUGREPORT_OPTION_FULL:
12602                // Default options.
12603                break;
12604            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12605                extraOptions = "bugreportplus";
12606                break;
12607            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12608                extraOptions = "bugreportremote";
12609                break;
12610            case ActivityManager.BUGREPORT_OPTION_WEAR:
12611                extraOptions = "bugreportwear";
12612                break;
12613            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12614                extraOptions = "bugreporttelephony";
12615                break;
12616            default:
12617                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12618                        + bugreportType);
12619        }
12620        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12621        if (extraOptions != null) {
12622            SystemProperties.set("dumpstate.options", extraOptions);
12623        }
12624        SystemProperties.set("ctl.start", "bugreport");
12625    }
12626
12627    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12628        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12629    }
12630
12631    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12632        if (r != null && (r.instr != null || r.usingWrapper)) {
12633            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12634        }
12635        return KEY_DISPATCHING_TIMEOUT;
12636    }
12637
12638    @Override
12639    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12640        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12641                != PackageManager.PERMISSION_GRANTED) {
12642            throw new SecurityException("Requires permission "
12643                    + android.Manifest.permission.FILTER_EVENTS);
12644        }
12645        ProcessRecord proc;
12646        long timeout;
12647        synchronized (this) {
12648            synchronized (mPidsSelfLocked) {
12649                proc = mPidsSelfLocked.get(pid);
12650            }
12651            timeout = getInputDispatchingTimeoutLocked(proc);
12652        }
12653
12654        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12655            return -1;
12656        }
12657
12658        return timeout;
12659    }
12660
12661    /**
12662     * Handle input dispatching timeouts.
12663     * Returns whether input dispatching should be aborted or not.
12664     */
12665    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12666            final ActivityRecord activity, final ActivityRecord parent,
12667            final boolean aboveSystem, String reason) {
12668        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12669                != PackageManager.PERMISSION_GRANTED) {
12670            throw new SecurityException("Requires permission "
12671                    + android.Manifest.permission.FILTER_EVENTS);
12672        }
12673
12674        final String annotation;
12675        if (reason == null) {
12676            annotation = "Input dispatching timed out";
12677        } else {
12678            annotation = "Input dispatching timed out (" + reason + ")";
12679        }
12680
12681        if (proc != null) {
12682            synchronized (this) {
12683                if (proc.debugging) {
12684                    return false;
12685                }
12686
12687                if (mDidDexOpt) {
12688                    // Give more time since we were dexopting.
12689                    mDidDexOpt = false;
12690                    return false;
12691                }
12692
12693                if (proc.instr != null) {
12694                    Bundle info = new Bundle();
12695                    info.putString("shortMsg", "keyDispatchingTimedOut");
12696                    info.putString("longMsg", annotation);
12697                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12698                    return true;
12699                }
12700            }
12701            mHandler.post(new Runnable() {
12702                @Override
12703                public void run() {
12704                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12705                }
12706            });
12707        }
12708
12709        return true;
12710    }
12711
12712    @Override
12713    public Bundle getAssistContextExtras(int requestType) {
12714        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12715                null, null, true /* focused */, true /* newSessionId */,
12716                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12717        if (pae == null) {
12718            return null;
12719        }
12720        synchronized (pae) {
12721            while (!pae.haveResult) {
12722                try {
12723                    pae.wait();
12724                } catch (InterruptedException e) {
12725                }
12726            }
12727        }
12728        synchronized (this) {
12729            buildAssistBundleLocked(pae, pae.result);
12730            mPendingAssistExtras.remove(pae);
12731            mUiHandler.removeCallbacks(pae);
12732        }
12733        return pae.extras;
12734    }
12735
12736    @Override
12737    public boolean isAssistDataAllowedOnCurrentActivity() {
12738        int userId;
12739        synchronized (this) {
12740            final ActivityStack focusedStack = getFocusedStack();
12741            if (focusedStack == null || focusedStack.isAssistantStack()) {
12742                return false;
12743            }
12744
12745            final ActivityRecord activity = focusedStack.topActivity();
12746            if (activity == null) {
12747                return false;
12748            }
12749            userId = activity.userId;
12750        }
12751        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12752                Context.DEVICE_POLICY_SERVICE);
12753        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12754    }
12755
12756    @Override
12757    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12758        long ident = Binder.clearCallingIdentity();
12759        try {
12760            synchronized (this) {
12761                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12762                ActivityRecord top = getFocusedStack().topActivity();
12763                if (top != caller) {
12764                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12765                            + " is not current top " + top);
12766                    return false;
12767                }
12768                if (!top.nowVisible) {
12769                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12770                            + " is not visible");
12771                    return false;
12772                }
12773            }
12774            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12775                    token);
12776        } finally {
12777            Binder.restoreCallingIdentity(ident);
12778        }
12779    }
12780
12781    @Override
12782    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12783            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
12784        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12785                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12786                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
12787    }
12788
12789    @Override
12790    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
12791            IBinder activityToken) {
12792        // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
12793        // rely on the flags to decide whether the handleRequestAssistContextExtras() is for
12794        // autofill, but it's safer to explicitly use new AutoFill types, in case the Assist
12795        // requests use flags in the future as well (since their flags value might collide with the
12796        // autofill flag values).
12797        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
12798                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
12799                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT) != null;
12800    }
12801
12802    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12803            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12804            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12805        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12806                "enqueueAssistContext()");
12807
12808        synchronized (this) {
12809            ActivityRecord activity = getFocusedStack().topActivity();
12810            if (activity == null) {
12811                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12812                return null;
12813            }
12814            if (activity.app == null || activity.app.thread == null) {
12815                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12816                return null;
12817            }
12818            if (focused) {
12819                if (activityToken != null) {
12820                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12821                    if (activity != caller) {
12822                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12823                                + " is not current top " + activity);
12824                        return null;
12825                    }
12826                }
12827            } else {
12828                activity = ActivityRecord.forTokenLocked(activityToken);
12829                if (activity == null) {
12830                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12831                            + " couldn't be found");
12832                    return null;
12833                }
12834            }
12835
12836            PendingAssistExtras pae;
12837            Bundle extras = new Bundle();
12838            if (args != null) {
12839                extras.putAll(args);
12840            }
12841            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12842            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12843
12844            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12845                    userHandle);
12846            pae.isHome = activity.isHomeActivity();
12847
12848            // Increment the sessionId if necessary
12849            if (newSessionId) {
12850                mViSessionId++;
12851            }
12852            try {
12853                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
12854                        mViSessionId);
12855                mPendingAssistExtras.add(pae);
12856                mUiHandler.postDelayed(pae, timeout);
12857            } catch (RemoteException e) {
12858                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12859                return null;
12860            }
12861            return pae;
12862        }
12863    }
12864
12865    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12866        IResultReceiver receiver;
12867        synchronized (this) {
12868            mPendingAssistExtras.remove(pae);
12869            receiver = pae.receiver;
12870        }
12871        if (receiver != null) {
12872            // Caller wants result sent back to them.
12873            Bundle sendBundle = new Bundle();
12874            // At least return the receiver extras
12875            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12876                    pae.receiverExtras);
12877            try {
12878                pae.receiver.send(0, sendBundle);
12879            } catch (RemoteException e) {
12880            }
12881        }
12882    }
12883
12884    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12885        if (result != null) {
12886            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12887        }
12888        if (pae.hint != null) {
12889            pae.extras.putBoolean(pae.hint, true);
12890        }
12891    }
12892
12893    /** Called from an app when assist data is ready. */
12894    @Override
12895    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12896            AssistContent content, Uri referrer) {
12897        PendingAssistExtras pae = (PendingAssistExtras)token;
12898        synchronized (pae) {
12899            pae.result = extras;
12900            pae.structure = structure;
12901            pae.content = content;
12902            if (referrer != null) {
12903                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12904            }
12905            if (structure != null) {
12906                structure.setHomeActivity(pae.isHome);
12907            }
12908            pae.haveResult = true;
12909            pae.notifyAll();
12910            if (pae.intent == null && pae.receiver == null) {
12911                // Caller is just waiting for the result.
12912                return;
12913            }
12914        }
12915
12916        // We are now ready to launch the assist activity.
12917        IResultReceiver sendReceiver = null;
12918        Bundle sendBundle = null;
12919        synchronized (this) {
12920            buildAssistBundleLocked(pae, extras);
12921            boolean exists = mPendingAssistExtras.remove(pae);
12922            mUiHandler.removeCallbacks(pae);
12923            if (!exists) {
12924                // Timed out.
12925                return;
12926            }
12927            if ((sendReceiver=pae.receiver) != null) {
12928                // Caller wants result sent back to them.
12929                sendBundle = new Bundle();
12930                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12931                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12932                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12933                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12934                        pae.receiverExtras);
12935            }
12936        }
12937        if (sendReceiver != null) {
12938            try {
12939                sendReceiver.send(0, sendBundle);
12940            } catch (RemoteException e) {
12941            }
12942            return;
12943        }
12944
12945        long ident = Binder.clearCallingIdentity();
12946        try {
12947            pae.intent.replaceExtras(pae.extras);
12948            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12949                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12950                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12951            closeSystemDialogs("assist");
12952            try {
12953                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12954            } catch (ActivityNotFoundException e) {
12955                Slog.w(TAG, "No activity to handle assist action.", e);
12956            }
12957        } finally {
12958            Binder.restoreCallingIdentity(ident);
12959        }
12960    }
12961
12962    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12963            Bundle args) {
12964        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12965                true /* focused */, true /* newSessionId */, userHandle, args,
12966                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12967    }
12968
12969    public void registerProcessObserver(IProcessObserver observer) {
12970        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12971                "registerProcessObserver()");
12972        synchronized (this) {
12973            mProcessObservers.register(observer);
12974        }
12975    }
12976
12977    @Override
12978    public void unregisterProcessObserver(IProcessObserver observer) {
12979        synchronized (this) {
12980            mProcessObservers.unregister(observer);
12981        }
12982    }
12983
12984    @Override
12985    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
12986            String callingPackage) {
12987        if (!hasUsageStatsPermission(callingPackage)) {
12988            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
12989                    "registerUidObserver");
12990        }
12991        synchronized (this) {
12992            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
12993                    callingPackage, which, cutpoint));
12994        }
12995    }
12996
12997    @Override
12998    public void unregisterUidObserver(IUidObserver observer) {
12999        synchronized (this) {
13000            mUidObservers.unregister(observer);
13001        }
13002    }
13003
13004    @Override
13005    public boolean convertFromTranslucent(IBinder token) {
13006        final long origId = Binder.clearCallingIdentity();
13007        try {
13008            synchronized (this) {
13009                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13010                if (r == null) {
13011                    return false;
13012                }
13013                final boolean translucentChanged = r.changeWindowTranslucency(true);
13014                if (translucentChanged) {
13015                    r.getStack().releaseBackgroundResources(r);
13016                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13017                }
13018                mWindowManager.setAppFullscreen(token, true);
13019                return translucentChanged;
13020            }
13021        } finally {
13022            Binder.restoreCallingIdentity(origId);
13023        }
13024    }
13025
13026    @Override
13027    public boolean convertToTranslucent(IBinder token, Bundle options) {
13028        final long origId = Binder.clearCallingIdentity();
13029        try {
13030            synchronized (this) {
13031                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13032                if (r == null) {
13033                    return false;
13034                }
13035                int index = r.task.mActivities.lastIndexOf(r);
13036                if (index > 0) {
13037                    ActivityRecord under = r.task.mActivities.get(index - 1);
13038                    under.returningOptions = ActivityOptions.fromBundle(options);
13039                }
13040                final boolean translucentChanged = r.changeWindowTranslucency(false);
13041                if (translucentChanged) {
13042                    r.getStack().convertActivityToTranslucent(r);
13043                }
13044                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13045                mWindowManager.setAppFullscreen(token, false);
13046                return translucentChanged;
13047            }
13048        } finally {
13049            Binder.restoreCallingIdentity(origId);
13050        }
13051    }
13052
13053    @Override
13054    public boolean requestVisibleBehind(IBinder token, boolean visible) {
13055        final long origId = Binder.clearCallingIdentity();
13056        try {
13057            synchronized (this) {
13058                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13059                if (r != null) {
13060                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13061                }
13062            }
13063            return false;
13064        } finally {
13065            Binder.restoreCallingIdentity(origId);
13066        }
13067    }
13068
13069    @Override
13070    public boolean isBackgroundVisibleBehind(IBinder token) {
13071        final long origId = Binder.clearCallingIdentity();
13072        try {
13073            synchronized (this) {
13074                final ActivityStack stack = ActivityRecord.getStackLocked(token);
13075                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13076                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13077                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13078                return visible;
13079            }
13080        } finally {
13081            Binder.restoreCallingIdentity(origId);
13082        }
13083    }
13084
13085    @Override
13086    public Bundle getActivityOptions(IBinder token) {
13087        final long origId = Binder.clearCallingIdentity();
13088        try {
13089            synchronized (this) {
13090                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13091                if (r != null) {
13092                    final ActivityOptions activityOptions = r.pendingOptions;
13093                    r.pendingOptions = null;
13094                    return activityOptions == null ? null : activityOptions.toBundle();
13095                }
13096                return null;
13097            }
13098        } finally {
13099            Binder.restoreCallingIdentity(origId);
13100        }
13101    }
13102
13103    @Override
13104    public void setImmersive(IBinder token, boolean immersive) {
13105        synchronized(this) {
13106            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13107            if (r == null) {
13108                throw new IllegalArgumentException();
13109            }
13110            r.immersive = immersive;
13111
13112            // update associated state if we're frontmost
13113            if (r == mStackSupervisor.getResumedActivityLocked()) {
13114                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13115                applyUpdateLockStateLocked(r);
13116            }
13117        }
13118    }
13119
13120    @Override
13121    public boolean isImmersive(IBinder token) {
13122        synchronized (this) {
13123            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13124            if (r == null) {
13125                throw new IllegalArgumentException();
13126            }
13127            return r.immersive;
13128        }
13129    }
13130
13131    @Override
13132    public void setVrThread(int tid) {
13133        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13134            throw new UnsupportedOperationException("VR mode not supported on this device!");
13135        }
13136
13137        synchronized (this) {
13138            if (tid > 0 && mVrState == PERSISTENT_VR_MODE) {
13139                Slog.e(TAG, "VR thread cannot be set in persistent VR mode!");
13140                return;
13141            }
13142            ProcessRecord proc;
13143            synchronized (mPidsSelfLocked) {
13144                final int pid = Binder.getCallingPid();
13145                proc = mPidsSelfLocked.get(pid);
13146                if (proc != null && mVrState == VR_MODE && tid >= 0) {
13147                    proc.vrThreadTid = updateVrThreadLocked(proc, proc.vrThreadTid, pid, tid);
13148                    mTopAppVrThreadTid = proc.vrThreadTid;
13149                }
13150            }
13151        }
13152    }
13153
13154    @Override
13155    public void setPersistentVrThread(int tid) {
13156        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13157            String msg = "Permission Denial: setPersistentVrThread() from pid="
13158                    + Binder.getCallingPid()
13159                    + ", uid=" + Binder.getCallingUid()
13160                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13161            Slog.w(TAG, msg);
13162            throw new SecurityException(msg);
13163        }
13164        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13165            throw new UnsupportedOperationException("VR mode not supported on this device!");
13166        }
13167
13168        synchronized (this) {
13169            // Disable any existing VR thread.
13170            if (mTopAppVrThreadTid > 0) {
13171                Process.setThreadScheduler(mTopAppVrThreadTid, Process.SCHED_OTHER, 0);
13172                mTopAppVrThreadTid = 0;
13173            }
13174
13175            if (tid > 0 && mVrState != PERSISTENT_VR_MODE) {
13176                Slog.e(TAG, "Persistent VR thread may only be set in persistent VR mode!");
13177                return;
13178            }
13179            ProcessRecord proc;
13180            synchronized (mPidsSelfLocked) {
13181                final int pid = Binder.getCallingPid();
13182                mPersistentVrThreadTid =
13183                        updateVrThreadLocked(null, mPersistentVrThreadTid, pid, tid);
13184            }
13185        }
13186    }
13187
13188    /**
13189     * Used by setVrThread and setPersistentVrThread to update a thread's priority. When proc is
13190     * non-null it must be in SCHED_GROUP_TOP_APP.  When it is null, the tid is unconditionally
13191     * rescheduled.
13192     */
13193    private int updateVrThreadLocked(ProcessRecord proc, int lastTid, int pid, int tid) {
13194        // ensure the tid belongs to the process
13195        if (!Process.isThreadInProcess(pid, tid)) {
13196            throw new IllegalArgumentException("VR thread does not belong to process");
13197        }
13198
13199        // reset existing VR thread to CFS if this thread still exists and belongs to
13200        // the calling process
13201        if (lastTid != 0 && Process.isThreadInProcess(pid, lastTid)) {
13202            try {
13203                Process.setThreadScheduler(lastTid, Process.SCHED_OTHER, 0);
13204            } catch (IllegalArgumentException e) {
13205                // Ignore this.  Only occurs in race condition where previous VR thread
13206                // was destroyed during this method call.
13207            }
13208        }
13209
13210        // promote to FIFO now if the tid is non-zero
13211        try {
13212            if ((proc == null || proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP)
13213                    && tid > 0) {
13214                Process.setThreadScheduler(tid,
13215                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13216            }
13217            return tid;
13218        } catch (IllegalArgumentException e) {
13219            Slog.e(TAG, "Failed to set scheduling policy, thread does"
13220                   + " not exist:\n" + e);
13221        }
13222        return lastTid;
13223    }
13224
13225    @Override
13226    public void setRenderThread(int tid) {
13227        synchronized (this) {
13228            ProcessRecord proc;
13229            synchronized (mPidsSelfLocked) {
13230                int pid = Binder.getCallingPid();
13231                proc = mPidsSelfLocked.get(pid);
13232                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13233                    // ensure the tid belongs to the process
13234                    if (!Process.isThreadInProcess(pid, tid)) {
13235                        throw new IllegalArgumentException(
13236                            "Render thread does not belong to process");
13237                    }
13238                    proc.renderThreadTid = tid;
13239                    if (DEBUG_OOM_ADJ) {
13240                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13241                    }
13242                    // promote to FIFO now
13243                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13244                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13245                        if (mUseFifoUiScheduling) {
13246                            Process.setThreadScheduler(proc.renderThreadTid,
13247                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13248                        } else {
13249                            Process.setThreadPriority(proc.renderThreadTid, -10);
13250                        }
13251                    }
13252                } else {
13253                    if (DEBUG_OOM_ADJ) {
13254                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13255                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13256                               mUseFifoUiScheduling);
13257                    }
13258                }
13259            }
13260        }
13261    }
13262
13263    @Override
13264    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13265        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13266            throw new UnsupportedOperationException("VR mode not supported on this device!");
13267        }
13268
13269        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13270
13271        ActivityRecord r;
13272        synchronized (this) {
13273            r = ActivityRecord.isInStackLocked(token);
13274        }
13275
13276        if (r == null) {
13277            throw new IllegalArgumentException();
13278        }
13279
13280        int err;
13281        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13282                VrManagerInternal.NO_ERROR) {
13283            return err;
13284        }
13285
13286        synchronized(this) {
13287            r.requestedVrComponent = (enabled) ? packageName : null;
13288
13289            // Update associated state if this activity is currently focused
13290            if (r == mStackSupervisor.getResumedActivityLocked()) {
13291                applyUpdateVrModeLocked(r);
13292            }
13293            return 0;
13294        }
13295    }
13296
13297    @Override
13298    public boolean isVrModePackageEnabled(ComponentName packageName) {
13299        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13300            throw new UnsupportedOperationException("VR mode not supported on this device!");
13301        }
13302
13303        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13304
13305        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13306                VrManagerInternal.NO_ERROR;
13307    }
13308
13309    public boolean isTopActivityImmersive() {
13310        enforceNotIsolatedCaller("startActivity");
13311        synchronized (this) {
13312            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13313            return (r != null) ? r.immersive : false;
13314        }
13315    }
13316
13317    @Override
13318    public boolean isTopOfTask(IBinder token) {
13319        synchronized (this) {
13320            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13321            if (r == null) {
13322                throw new IllegalArgumentException();
13323            }
13324            return r.task.getTopActivity() == r;
13325        }
13326    }
13327
13328    @Override
13329    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13330        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13331            String msg = "Permission Denial: setHasTopUi() from pid="
13332                    + Binder.getCallingPid()
13333                    + ", uid=" + Binder.getCallingUid()
13334                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13335            Slog.w(TAG, msg);
13336            throw new SecurityException(msg);
13337        }
13338        final int pid = Binder.getCallingPid();
13339        final long origId = Binder.clearCallingIdentity();
13340        try {
13341            synchronized (this) {
13342                boolean changed = false;
13343                ProcessRecord pr;
13344                synchronized (mPidsSelfLocked) {
13345                    pr = mPidsSelfLocked.get(pid);
13346                    if (pr == null) {
13347                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13348                        return;
13349                    }
13350                    if (pr.hasTopUi != hasTopUi) {
13351                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13352                        pr.hasTopUi = hasTopUi;
13353                        changed = true;
13354                    }
13355                }
13356                if (changed) {
13357                    updateOomAdjLocked(pr);
13358                }
13359            }
13360        } finally {
13361            Binder.restoreCallingIdentity(origId);
13362        }
13363    }
13364
13365    public final void enterSafeMode() {
13366        synchronized(this) {
13367            // It only makes sense to do this before the system is ready
13368            // and started launching other packages.
13369            if (!mSystemReady) {
13370                try {
13371                    AppGlobals.getPackageManager().enterSafeMode();
13372                } catch (RemoteException e) {
13373                }
13374            }
13375
13376            mSafeMode = true;
13377        }
13378    }
13379
13380    public final void showSafeModeOverlay() {
13381        View v = LayoutInflater.from(mContext).inflate(
13382                com.android.internal.R.layout.safe_mode, null);
13383        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13384        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13385        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13386        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13387        lp.gravity = Gravity.BOTTOM | Gravity.START;
13388        lp.format = v.getBackground().getOpacity();
13389        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13390                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13391        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13392        ((WindowManager)mContext.getSystemService(
13393                Context.WINDOW_SERVICE)).addView(v, lp);
13394    }
13395
13396    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13397        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13398            return;
13399        }
13400        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13401        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13402        synchronized (stats) {
13403            if (mBatteryStatsService.isOnBattery()) {
13404                mBatteryStatsService.enforceCallingPermission();
13405                int MY_UID = Binder.getCallingUid();
13406                final int uid;
13407                if (sender == null) {
13408                    uid = sourceUid;
13409                } else {
13410                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13411                }
13412                BatteryStatsImpl.Uid.Pkg pkg =
13413                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13414                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13415                pkg.noteWakeupAlarmLocked(tag);
13416            }
13417        }
13418    }
13419
13420    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13421        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13422            return;
13423        }
13424        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13425        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13426        synchronized (stats) {
13427            mBatteryStatsService.enforceCallingPermission();
13428            int MY_UID = Binder.getCallingUid();
13429            final int uid;
13430            if (sender == null) {
13431                uid = sourceUid;
13432            } else {
13433                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13434            }
13435            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13436        }
13437    }
13438
13439    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13440        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13441            return;
13442        }
13443        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13444        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13445        synchronized (stats) {
13446            mBatteryStatsService.enforceCallingPermission();
13447            int MY_UID = Binder.getCallingUid();
13448            final int uid;
13449            if (sender == null) {
13450                uid = sourceUid;
13451            } else {
13452                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13453            }
13454            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13455        }
13456    }
13457
13458    public boolean killPids(int[] pids, String pReason, boolean secure) {
13459        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13460            throw new SecurityException("killPids only available to the system");
13461        }
13462        String reason = (pReason == null) ? "Unknown" : pReason;
13463        // XXX Note: don't acquire main activity lock here, because the window
13464        // manager calls in with its locks held.
13465
13466        boolean killed = false;
13467        synchronized (mPidsSelfLocked) {
13468            int worstType = 0;
13469            for (int i=0; i<pids.length; i++) {
13470                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13471                if (proc != null) {
13472                    int type = proc.setAdj;
13473                    if (type > worstType) {
13474                        worstType = type;
13475                    }
13476                }
13477            }
13478
13479            // If the worst oom_adj is somewhere in the cached proc LRU range,
13480            // then constrain it so we will kill all cached procs.
13481            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13482                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13483                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13484            }
13485
13486            // If this is not a secure call, don't let it kill processes that
13487            // are important.
13488            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13489                worstType = ProcessList.SERVICE_ADJ;
13490            }
13491
13492            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13493            for (int i=0; i<pids.length; i++) {
13494                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13495                if (proc == null) {
13496                    continue;
13497                }
13498                int adj = proc.setAdj;
13499                if (adj >= worstType && !proc.killedByAm) {
13500                    proc.kill(reason, true);
13501                    killed = true;
13502                }
13503            }
13504        }
13505        return killed;
13506    }
13507
13508    @Override
13509    public void killUid(int appId, int userId, String reason) {
13510        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13511        synchronized (this) {
13512            final long identity = Binder.clearCallingIdentity();
13513            try {
13514                killPackageProcessesLocked(null, appId, userId,
13515                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13516                        reason != null ? reason : "kill uid");
13517            } finally {
13518                Binder.restoreCallingIdentity(identity);
13519            }
13520        }
13521    }
13522
13523    @Override
13524    public boolean killProcessesBelowForeground(String reason) {
13525        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13526            throw new SecurityException("killProcessesBelowForeground() only available to system");
13527        }
13528
13529        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13530    }
13531
13532    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13533        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13534            throw new SecurityException("killProcessesBelowAdj() only available to system");
13535        }
13536
13537        boolean killed = false;
13538        synchronized (mPidsSelfLocked) {
13539            final int size = mPidsSelfLocked.size();
13540            for (int i = 0; i < size; i++) {
13541                final int pid = mPidsSelfLocked.keyAt(i);
13542                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13543                if (proc == null) continue;
13544
13545                final int adj = proc.setAdj;
13546                if (adj > belowAdj && !proc.killedByAm) {
13547                    proc.kill(reason, true);
13548                    killed = true;
13549                }
13550            }
13551        }
13552        return killed;
13553    }
13554
13555    @Override
13556    public void hang(final IBinder who, boolean allowRestart) {
13557        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13558                != PackageManager.PERMISSION_GRANTED) {
13559            throw new SecurityException("Requires permission "
13560                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13561        }
13562
13563        final IBinder.DeathRecipient death = new DeathRecipient() {
13564            @Override
13565            public void binderDied() {
13566                synchronized (this) {
13567                    notifyAll();
13568                }
13569            }
13570        };
13571
13572        try {
13573            who.linkToDeath(death, 0);
13574        } catch (RemoteException e) {
13575            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13576            return;
13577        }
13578
13579        synchronized (this) {
13580            Watchdog.getInstance().setAllowRestart(allowRestart);
13581            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13582            synchronized (death) {
13583                while (who.isBinderAlive()) {
13584                    try {
13585                        death.wait();
13586                    } catch (InterruptedException e) {
13587                    }
13588                }
13589            }
13590            Watchdog.getInstance().setAllowRestart(true);
13591        }
13592    }
13593
13594    @Override
13595    public void restart() {
13596        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13597                != PackageManager.PERMISSION_GRANTED) {
13598            throw new SecurityException("Requires permission "
13599                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13600        }
13601
13602        Log.i(TAG, "Sending shutdown broadcast...");
13603
13604        BroadcastReceiver br = new BroadcastReceiver() {
13605            @Override public void onReceive(Context context, Intent intent) {
13606                // Now the broadcast is done, finish up the low-level shutdown.
13607                Log.i(TAG, "Shutting down activity manager...");
13608                shutdown(10000);
13609                Log.i(TAG, "Shutdown complete, restarting!");
13610                Process.killProcess(Process.myPid());
13611                System.exit(10);
13612            }
13613        };
13614
13615        // First send the high-level shut down broadcast.
13616        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13617        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13618        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13619        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13620        mContext.sendOrderedBroadcastAsUser(intent,
13621                UserHandle.ALL, null, br, mHandler, 0, null, null);
13622        */
13623        br.onReceive(mContext, intent);
13624    }
13625
13626    private long getLowRamTimeSinceIdle(long now) {
13627        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13628    }
13629
13630    @Override
13631    public void performIdleMaintenance() {
13632        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13633                != PackageManager.PERMISSION_GRANTED) {
13634            throw new SecurityException("Requires permission "
13635                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13636        }
13637
13638        synchronized (this) {
13639            final long now = SystemClock.uptimeMillis();
13640            final long timeSinceLastIdle = now - mLastIdleTime;
13641            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13642            mLastIdleTime = now;
13643            mLowRamTimeSinceLastIdle = 0;
13644            if (mLowRamStartTime != 0) {
13645                mLowRamStartTime = now;
13646            }
13647
13648            StringBuilder sb = new StringBuilder(128);
13649            sb.append("Idle maintenance over ");
13650            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13651            sb.append(" low RAM for ");
13652            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13653            Slog.i(TAG, sb.toString());
13654
13655            // If at least 1/3 of our time since the last idle period has been spent
13656            // with RAM low, then we want to kill processes.
13657            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13658
13659            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13660                ProcessRecord proc = mLruProcesses.get(i);
13661                if (proc.notCachedSinceIdle) {
13662                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13663                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13664                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13665                        if (doKilling && proc.initialIdlePss != 0
13666                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13667                            sb = new StringBuilder(128);
13668                            sb.append("Kill");
13669                            sb.append(proc.processName);
13670                            sb.append(" in idle maint: pss=");
13671                            sb.append(proc.lastPss);
13672                            sb.append(", swapPss=");
13673                            sb.append(proc.lastSwapPss);
13674                            sb.append(", initialPss=");
13675                            sb.append(proc.initialIdlePss);
13676                            sb.append(", period=");
13677                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13678                            sb.append(", lowRamPeriod=");
13679                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13680                            Slog.wtfQuiet(TAG, sb.toString());
13681                            proc.kill("idle maint (pss " + proc.lastPss
13682                                    + " from " + proc.initialIdlePss + ")", true);
13683                        }
13684                    }
13685                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13686                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13687                    proc.notCachedSinceIdle = true;
13688                    proc.initialIdlePss = 0;
13689                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13690                            mTestPssMode, isSleepingLocked(), now);
13691                }
13692            }
13693
13694            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13695            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13696        }
13697    }
13698
13699    @Override
13700    public void sendIdleJobTrigger() {
13701        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13702                != PackageManager.PERMISSION_GRANTED) {
13703            throw new SecurityException("Requires permission "
13704                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13705        }
13706
13707        final long ident = Binder.clearCallingIdentity();
13708        try {
13709            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13710                    .setPackage("android")
13711                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13712            broadcastIntent(null, intent, null, null, 0, null, null, null,
13713                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13714        } finally {
13715            Binder.restoreCallingIdentity(ident);
13716        }
13717    }
13718
13719    private void retrieveSettings() {
13720        final ContentResolver resolver = mContext.getContentResolver();
13721        final boolean freeformWindowManagement =
13722                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13723                        || Settings.Global.getInt(
13724                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13725        final boolean supportsPictureInPicture =
13726                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13727
13728        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13729        final boolean supportsSplitScreenMultiWindow =
13730                ActivityManager.supportsSplitScreenMultiWindow();
13731        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13732        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13733        final boolean alwaysFinishActivities =
13734                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13735        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13736        final boolean forceResizable = Settings.Global.getInt(
13737                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13738        final boolean supportsLeanbackOnly =
13739                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13740
13741        // Transfer any global setting for forcing RTL layout, into a System Property
13742        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13743
13744        final Configuration configuration = new Configuration();
13745        Settings.System.getConfiguration(resolver, configuration);
13746        if (forceRtl) {
13747            // This will take care of setting the correct layout direction flags
13748            configuration.setLayoutDirection(configuration.locale);
13749        }
13750
13751        synchronized (this) {
13752            mDebugApp = mOrigDebugApp = debugApp;
13753            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13754            mAlwaysFinishActivities = alwaysFinishActivities;
13755            mSupportsLeanbackOnly = supportsLeanbackOnly;
13756            mForceResizableActivities = forceResizable;
13757            if (supportsMultiWindow || forceResizable) {
13758                mSupportsMultiWindow = true;
13759                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13760            } else {
13761                mSupportsMultiWindow = false;
13762                mSupportsFreeformWindowManagement = false;
13763            }
13764            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13765            mSupportsPictureInPicture = supportsPictureInPicture;
13766            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13767            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13768            // This happens before any activities are started, so we can change global configuration
13769            // in-place.
13770            updateConfigurationLocked(configuration, null, true);
13771            final Configuration globalConfig = getGlobalConfiguration();
13772            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13773
13774            // Load resources only after the current configuration has been set.
13775            final Resources res = mContext.getResources();
13776            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13777            mThumbnailWidth = res.getDimensionPixelSize(
13778                    com.android.internal.R.dimen.thumbnail_width);
13779            mThumbnailHeight = res.getDimensionPixelSize(
13780                    com.android.internal.R.dimen.thumbnail_height);
13781            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13782                    com.android.internal.R.string.config_appsNotReportingCrashes));
13783            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13784                    com.android.internal.R.bool.config_customUserSwitchUi);
13785            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13786                mFullscreenThumbnailScale = (float) res
13787                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13788                    (float) globalConfig.screenWidthDp;
13789            } else {
13790                mFullscreenThumbnailScale = res.getFraction(
13791                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13792            }
13793        }
13794    }
13795
13796    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13797        traceLog.traceBegin("PhaseActivityManagerReady");
13798        synchronized(this) {
13799            if (mSystemReady) {
13800                // If we're done calling all the receivers, run the next "boot phase" passed in
13801                // by the SystemServer
13802                if (goingCallback != null) {
13803                    goingCallback.run();
13804                }
13805                return;
13806            }
13807
13808            mLocalDeviceIdleController
13809                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13810            mAssistUtils = new AssistUtils(mContext);
13811            VrManagerInternal vrManagerInternal = LocalServices.getService(VrManagerInternal.class);
13812            if (vrManagerInternal != null) {
13813                vrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener);
13814            }
13815            // Make sure we have the current profile info, since it is needed for security checks.
13816            mUserController.onSystemReady();
13817            mRecentTasks.onSystemReadyLocked();
13818            mAppOpsService.systemReady();
13819            mSystemReady = true;
13820        }
13821
13822        ArrayList<ProcessRecord> procsToKill = null;
13823        synchronized(mPidsSelfLocked) {
13824            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13825                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13826                if (!isAllowedWhileBooting(proc.info)){
13827                    if (procsToKill == null) {
13828                        procsToKill = new ArrayList<ProcessRecord>();
13829                    }
13830                    procsToKill.add(proc);
13831                }
13832            }
13833        }
13834
13835        synchronized(this) {
13836            if (procsToKill != null) {
13837                for (int i=procsToKill.size()-1; i>=0; i--) {
13838                    ProcessRecord proc = procsToKill.get(i);
13839                    Slog.i(TAG, "Removing system update proc: " + proc);
13840                    removeProcessLocked(proc, true, false, "system update done");
13841                }
13842            }
13843
13844            // Now that we have cleaned up any update processes, we
13845            // are ready to start launching real processes and know that
13846            // we won't trample on them any more.
13847            mProcessesReady = true;
13848        }
13849
13850        Slog.i(TAG, "System now ready");
13851        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13852            SystemClock.uptimeMillis());
13853
13854        synchronized(this) {
13855            // Make sure we have no pre-ready processes sitting around.
13856
13857            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13858                ResolveInfo ri = mContext.getPackageManager()
13859                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13860                                STOCK_PM_FLAGS);
13861                CharSequence errorMsg = null;
13862                if (ri != null) {
13863                    ActivityInfo ai = ri.activityInfo;
13864                    ApplicationInfo app = ai.applicationInfo;
13865                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13866                        mTopAction = Intent.ACTION_FACTORY_TEST;
13867                        mTopData = null;
13868                        mTopComponent = new ComponentName(app.packageName,
13869                                ai.name);
13870                    } else {
13871                        errorMsg = mContext.getResources().getText(
13872                                com.android.internal.R.string.factorytest_not_system);
13873                    }
13874                } else {
13875                    errorMsg = mContext.getResources().getText(
13876                            com.android.internal.R.string.factorytest_no_action);
13877                }
13878                if (errorMsg != null) {
13879                    mTopAction = null;
13880                    mTopData = null;
13881                    mTopComponent = null;
13882                    Message msg = Message.obtain();
13883                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13884                    msg.getData().putCharSequence("msg", errorMsg);
13885                    mUiHandler.sendMessage(msg);
13886                }
13887            }
13888        }
13889
13890        retrieveSettings();
13891        final int currentUserId;
13892        synchronized (this) {
13893            currentUserId = mUserController.getCurrentUserIdLocked();
13894            readGrantedUriPermissionsLocked();
13895        }
13896
13897        if (goingCallback != null) goingCallback.run();
13898        traceLog.traceBegin("ActivityManagerStartApps");
13899        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13900                Integer.toString(currentUserId), currentUserId);
13901        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13902                Integer.toString(currentUserId), currentUserId);
13903        mSystemServiceManager.startUser(currentUserId);
13904
13905        synchronized (this) {
13906            // Only start up encryption-aware persistent apps; once user is
13907            // unlocked we'll come back around and start unaware apps
13908            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13909
13910            // Start up initial activity.
13911            mBooting = true;
13912            // Enable home activity for system user, so that the system can always boot. We don't
13913            // do this when the system user is not setup since the setup wizard should be the one
13914            // to handle home activity in this case.
13915            if (UserManager.isSplitSystemUser() &&
13916                    Settings.Secure.getInt(mContext.getContentResolver(),
13917                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13918                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13919                try {
13920                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13921                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13922                            UserHandle.USER_SYSTEM);
13923                } catch (RemoteException e) {
13924                    throw e.rethrowAsRuntimeException();
13925                }
13926            }
13927            startHomeActivityLocked(currentUserId, "systemReady");
13928
13929            try {
13930                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13931                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13932                            + " data partition or your device will be unstable.");
13933                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13934                }
13935            } catch (RemoteException e) {
13936            }
13937
13938            if (!Build.isBuildConsistent()) {
13939                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13940                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13941            }
13942
13943            long ident = Binder.clearCallingIdentity();
13944            try {
13945                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13946                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13947                        | Intent.FLAG_RECEIVER_FOREGROUND);
13948                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13949                broadcastIntentLocked(null, null, intent,
13950                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13951                        null, false, false, MY_PID, Process.SYSTEM_UID,
13952                        currentUserId);
13953                intent = new Intent(Intent.ACTION_USER_STARTING);
13954                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13955                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13956                broadcastIntentLocked(null, null, intent,
13957                        null, new IIntentReceiver.Stub() {
13958                            @Override
13959                            public void performReceive(Intent intent, int resultCode, String data,
13960                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13961                                    throws RemoteException {
13962                            }
13963                        }, 0, null, null,
13964                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13965                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13966            } catch (Throwable t) {
13967                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13968            } finally {
13969                Binder.restoreCallingIdentity(ident);
13970            }
13971            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13972            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13973            traceLog.traceEnd(); // ActivityManagerStartApps
13974            traceLog.traceEnd(); // PhaseActivityManagerReady
13975        }
13976    }
13977
13978    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13979        synchronized (this) {
13980            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13981        }
13982    }
13983
13984    void skipCurrentReceiverLocked(ProcessRecord app) {
13985        for (BroadcastQueue queue : mBroadcastQueues) {
13986            queue.skipCurrentReceiverLocked(app);
13987        }
13988    }
13989
13990    /**
13991     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13992     * The application process will exit immediately after this call returns.
13993     * @param app object of the crashing app, null for the system server
13994     * @param crashInfo describing the exception
13995     */
13996    public void handleApplicationCrash(IBinder app,
13997            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13998        ProcessRecord r = findAppProcess(app, "Crash");
13999        final String processName = app == null ? "system_server"
14000                : (r == null ? "unknown" : r.processName);
14001
14002        handleApplicationCrashInner("crash", r, processName, crashInfo);
14003    }
14004
14005    /* Native crash reporting uses this inner version because it needs to be somewhat
14006     * decoupled from the AM-managed cleanup lifecycle
14007     */
14008    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14009            ApplicationErrorReport.CrashInfo crashInfo) {
14010        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14011                UserHandle.getUserId(Binder.getCallingUid()), processName,
14012                r == null ? -1 : r.info.flags,
14013                crashInfo.exceptionClassName,
14014                crashInfo.exceptionMessage,
14015                crashInfo.throwFileName,
14016                crashInfo.throwLineNumber);
14017
14018        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14019
14020        mAppErrors.crashApplication(r, crashInfo);
14021    }
14022
14023    public void handleApplicationStrictModeViolation(
14024            IBinder app,
14025            int violationMask,
14026            StrictMode.ViolationInfo info) {
14027        ProcessRecord r = findAppProcess(app, "StrictMode");
14028        if (r == null) {
14029            return;
14030        }
14031
14032        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14033            Integer stackFingerprint = info.hashCode();
14034            boolean logIt = true;
14035            synchronized (mAlreadyLoggedViolatedStacks) {
14036                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14037                    logIt = false;
14038                    // TODO: sub-sample into EventLog for these, with
14039                    // the info.durationMillis?  Then we'd get
14040                    // the relative pain numbers, without logging all
14041                    // the stack traces repeatedly.  We'd want to do
14042                    // likewise in the client code, which also does
14043                    // dup suppression, before the Binder call.
14044                } else {
14045                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14046                        mAlreadyLoggedViolatedStacks.clear();
14047                    }
14048                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14049                }
14050            }
14051            if (logIt) {
14052                logStrictModeViolationToDropBox(r, info);
14053            }
14054        }
14055
14056        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14057            AppErrorResult result = new AppErrorResult();
14058            synchronized (this) {
14059                final long origId = Binder.clearCallingIdentity();
14060
14061                Message msg = Message.obtain();
14062                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14063                HashMap<String, Object> data = new HashMap<String, Object>();
14064                data.put("result", result);
14065                data.put("app", r);
14066                data.put("violationMask", violationMask);
14067                data.put("info", info);
14068                msg.obj = data;
14069                mUiHandler.sendMessage(msg);
14070
14071                Binder.restoreCallingIdentity(origId);
14072            }
14073            int res = result.get();
14074            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14075        }
14076    }
14077
14078    // Depending on the policy in effect, there could be a bunch of
14079    // these in quick succession so we try to batch these together to
14080    // minimize disk writes, number of dropbox entries, and maximize
14081    // compression, by having more fewer, larger records.
14082    private void logStrictModeViolationToDropBox(
14083            ProcessRecord process,
14084            StrictMode.ViolationInfo info) {
14085        if (info == null) {
14086            return;
14087        }
14088        final boolean isSystemApp = process == null ||
14089                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14090                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14091        final String processName = process == null ? "unknown" : process.processName;
14092        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14093        final DropBoxManager dbox = (DropBoxManager)
14094                mContext.getSystemService(Context.DROPBOX_SERVICE);
14095
14096        // Exit early if the dropbox isn't configured to accept this report type.
14097        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14098
14099        boolean bufferWasEmpty;
14100        boolean needsFlush;
14101        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14102        synchronized (sb) {
14103            bufferWasEmpty = sb.length() == 0;
14104            appendDropBoxProcessHeaders(process, processName, sb);
14105            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14106            sb.append("System-App: ").append(isSystemApp).append("\n");
14107            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14108            if (info.violationNumThisLoop != 0) {
14109                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14110            }
14111            if (info.numAnimationsRunning != 0) {
14112                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14113            }
14114            if (info.broadcastIntentAction != null) {
14115                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14116            }
14117            if (info.durationMillis != -1) {
14118                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14119            }
14120            if (info.numInstances != -1) {
14121                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14122            }
14123            if (info.tags != null) {
14124                for (String tag : info.tags) {
14125                    sb.append("Span-Tag: ").append(tag).append("\n");
14126                }
14127            }
14128            sb.append("\n");
14129            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14130                sb.append(info.crashInfo.stackTrace);
14131                sb.append("\n");
14132            }
14133            if (info.message != null) {
14134                sb.append(info.message);
14135                sb.append("\n");
14136            }
14137
14138            // Only buffer up to ~64k.  Various logging bits truncate
14139            // things at 128k.
14140            needsFlush = (sb.length() > 64 * 1024);
14141        }
14142
14143        // Flush immediately if the buffer's grown too large, or this
14144        // is a non-system app.  Non-system apps are isolated with a
14145        // different tag & policy and not batched.
14146        //
14147        // Batching is useful during internal testing with
14148        // StrictMode settings turned up high.  Without batching,
14149        // thousands of separate files could be created on boot.
14150        if (!isSystemApp || needsFlush) {
14151            new Thread("Error dump: " + dropboxTag) {
14152                @Override
14153                public void run() {
14154                    String report;
14155                    synchronized (sb) {
14156                        report = sb.toString();
14157                        sb.delete(0, sb.length());
14158                        sb.trimToSize();
14159                    }
14160                    if (report.length() != 0) {
14161                        dbox.addText(dropboxTag, report);
14162                    }
14163                }
14164            }.start();
14165            return;
14166        }
14167
14168        // System app batching:
14169        if (!bufferWasEmpty) {
14170            // An existing dropbox-writing thread is outstanding, so
14171            // we don't need to start it up.  The existing thread will
14172            // catch the buffer appends we just did.
14173            return;
14174        }
14175
14176        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14177        // (After this point, we shouldn't access AMS internal data structures.)
14178        new Thread("Error dump: " + dropboxTag) {
14179            @Override
14180            public void run() {
14181                // 5 second sleep to let stacks arrive and be batched together
14182                try {
14183                    Thread.sleep(5000);  // 5 seconds
14184                } catch (InterruptedException e) {}
14185
14186                String errorReport;
14187                synchronized (mStrictModeBuffer) {
14188                    errorReport = mStrictModeBuffer.toString();
14189                    if (errorReport.length() == 0) {
14190                        return;
14191                    }
14192                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14193                    mStrictModeBuffer.trimToSize();
14194                }
14195                dbox.addText(dropboxTag, errorReport);
14196            }
14197        }.start();
14198    }
14199
14200    /**
14201     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14202     * @param app object of the crashing app, null for the system server
14203     * @param tag reported by the caller
14204     * @param system whether this wtf is coming from the system
14205     * @param crashInfo describing the context of the error
14206     * @return true if the process should exit immediately (WTF is fatal)
14207     */
14208    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14209            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14210        final int callingUid = Binder.getCallingUid();
14211        final int callingPid = Binder.getCallingPid();
14212
14213        if (system) {
14214            // If this is coming from the system, we could very well have low-level
14215            // system locks held, so we want to do this all asynchronously.  And we
14216            // never want this to become fatal, so there is that too.
14217            mHandler.post(new Runnable() {
14218                @Override public void run() {
14219                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14220                }
14221            });
14222            return false;
14223        }
14224
14225        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14226                crashInfo);
14227
14228        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14229                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14230        final boolean isSystem = (r == null) || r.persistent;
14231
14232        if (isFatal && !isSystem) {
14233            mAppErrors.crashApplication(r, crashInfo);
14234            return true;
14235        } else {
14236            return false;
14237        }
14238    }
14239
14240    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14241            final ApplicationErrorReport.CrashInfo crashInfo) {
14242        final ProcessRecord r = findAppProcess(app, "WTF");
14243        final String processName = app == null ? "system_server"
14244                : (r == null ? "unknown" : r.processName);
14245
14246        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14247                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14248
14249        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14250
14251        return r;
14252    }
14253
14254    /**
14255     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14256     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14257     */
14258    private ProcessRecord findAppProcess(IBinder app, String reason) {
14259        if (app == null) {
14260            return null;
14261        }
14262
14263        synchronized (this) {
14264            final int NP = mProcessNames.getMap().size();
14265            for (int ip=0; ip<NP; ip++) {
14266                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14267                final int NA = apps.size();
14268                for (int ia=0; ia<NA; ia++) {
14269                    ProcessRecord p = apps.valueAt(ia);
14270                    if (p.thread != null && p.thread.asBinder() == app) {
14271                        return p;
14272                    }
14273                }
14274            }
14275
14276            Slog.w(TAG, "Can't find mystery application for " + reason
14277                    + " from pid=" + Binder.getCallingPid()
14278                    + " uid=" + Binder.getCallingUid() + ": " + app);
14279            return null;
14280        }
14281    }
14282
14283    /**
14284     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14285     * to append various headers to the dropbox log text.
14286     */
14287    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14288            StringBuilder sb) {
14289        // Watchdog thread ends up invoking this function (with
14290        // a null ProcessRecord) to add the stack file to dropbox.
14291        // Do not acquire a lock on this (am) in such cases, as it
14292        // could cause a potential deadlock, if and when watchdog
14293        // is invoked due to unavailability of lock on am and it
14294        // would prevent watchdog from killing system_server.
14295        if (process == null) {
14296            sb.append("Process: ").append(processName).append("\n");
14297            return;
14298        }
14299        // Note: ProcessRecord 'process' is guarded by the service
14300        // instance.  (notably process.pkgList, which could otherwise change
14301        // concurrently during execution of this method)
14302        synchronized (this) {
14303            sb.append("Process: ").append(processName).append("\n");
14304            int flags = process.info.flags;
14305            IPackageManager pm = AppGlobals.getPackageManager();
14306            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14307            for (int ip=0; ip<process.pkgList.size(); ip++) {
14308                String pkg = process.pkgList.keyAt(ip);
14309                sb.append("Package: ").append(pkg);
14310                try {
14311                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14312                    if (pi != null) {
14313                        sb.append(" v").append(pi.versionCode);
14314                        if (pi.versionName != null) {
14315                            sb.append(" (").append(pi.versionName).append(")");
14316                        }
14317                    }
14318                } catch (RemoteException e) {
14319                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14320                }
14321                sb.append("\n");
14322            }
14323        }
14324    }
14325
14326    private static String processClass(ProcessRecord process) {
14327        if (process == null || process.pid == MY_PID) {
14328            return "system_server";
14329        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14330            return "system_app";
14331        } else {
14332            return "data_app";
14333        }
14334    }
14335
14336    private volatile long mWtfClusterStart;
14337    private volatile int mWtfClusterCount;
14338
14339    /**
14340     * Write a description of an error (crash, WTF, ANR) to the drop box.
14341     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14342     * @param process which caused the error, null means the system server
14343     * @param activity which triggered the error, null if unknown
14344     * @param parent activity related to the error, null if unknown
14345     * @param subject line related to the error, null if absent
14346     * @param report in long form describing the error, null if absent
14347     * @param dataFile text file to include in the report, null if none
14348     * @param crashInfo giving an application stack trace, null if absent
14349     */
14350    public void addErrorToDropBox(String eventType,
14351            ProcessRecord process, String processName, ActivityRecord activity,
14352            ActivityRecord parent, String subject,
14353            final String report, final File dataFile,
14354            final ApplicationErrorReport.CrashInfo crashInfo) {
14355        // NOTE -- this must never acquire the ActivityManagerService lock,
14356        // otherwise the watchdog may be prevented from resetting the system.
14357
14358        // Bail early if not published yet
14359        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14360        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14361
14362        // Exit early if the dropbox isn't configured to accept this report type.
14363        final String dropboxTag = processClass(process) + "_" + eventType;
14364        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14365
14366        // Rate-limit how often we're willing to do the heavy lifting below to
14367        // collect and record logs; currently 5 logs per 10 second period.
14368        final long now = SystemClock.elapsedRealtime();
14369        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14370            mWtfClusterStart = now;
14371            mWtfClusterCount = 1;
14372        } else {
14373            if (mWtfClusterCount++ >= 5) return;
14374        }
14375
14376        final StringBuilder sb = new StringBuilder(1024);
14377        appendDropBoxProcessHeaders(process, processName, sb);
14378        if (process != null) {
14379            sb.append("Foreground: ")
14380                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14381                    .append("\n");
14382        }
14383        if (activity != null) {
14384            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14385        }
14386        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14387            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14388        }
14389        if (parent != null && parent != activity) {
14390            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14391        }
14392        if (subject != null) {
14393            sb.append("Subject: ").append(subject).append("\n");
14394        }
14395        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14396        if (Debug.isDebuggerConnected()) {
14397            sb.append("Debugger: Connected\n");
14398        }
14399        sb.append("\n");
14400
14401        // Do the rest in a worker thread to avoid blocking the caller on I/O
14402        // (After this point, we shouldn't access AMS internal data structures.)
14403        Thread worker = new Thread("Error dump: " + dropboxTag) {
14404            @Override
14405            public void run() {
14406                if (report != null) {
14407                    sb.append(report);
14408                }
14409
14410                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14411                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14412                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14413                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14414
14415                if (dataFile != null && maxDataFileSize > 0) {
14416                    try {
14417                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14418                                    "\n\n[[TRUNCATED]]"));
14419                    } catch (IOException e) {
14420                        Slog.e(TAG, "Error reading " + dataFile, e);
14421                    }
14422                }
14423                if (crashInfo != null && crashInfo.stackTrace != null) {
14424                    sb.append(crashInfo.stackTrace);
14425                }
14426
14427                if (lines > 0) {
14428                    sb.append("\n");
14429
14430                    // Merge several logcat streams, and take the last N lines
14431                    InputStreamReader input = null;
14432                    try {
14433                        java.lang.Process logcat = new ProcessBuilder(
14434                                "/system/bin/timeout", "-k", "15s", "10s",
14435                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14436                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14437                                        .redirectErrorStream(true).start();
14438
14439                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14440                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14441                        input = new InputStreamReader(logcat.getInputStream());
14442
14443                        int num;
14444                        char[] buf = new char[8192];
14445                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14446                    } catch (IOException e) {
14447                        Slog.e(TAG, "Error running logcat", e);
14448                    } finally {
14449                        if (input != null) try { input.close(); } catch (IOException e) {}
14450                    }
14451                }
14452
14453                dbox.addText(dropboxTag, sb.toString());
14454            }
14455        };
14456
14457        if (process == null) {
14458            // If process is null, we are being called from some internal code
14459            // and may be about to die -- run this synchronously.
14460            worker.run();
14461        } else {
14462            worker.start();
14463        }
14464    }
14465
14466    @Override
14467    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14468        enforceNotIsolatedCaller("getProcessesInErrorState");
14469        // assume our apps are happy - lazy create the list
14470        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14471
14472        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14473                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14474        int userId = UserHandle.getUserId(Binder.getCallingUid());
14475
14476        synchronized (this) {
14477
14478            // iterate across all processes
14479            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14480                ProcessRecord app = mLruProcesses.get(i);
14481                if (!allUsers && app.userId != userId) {
14482                    continue;
14483                }
14484                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14485                    // This one's in trouble, so we'll generate a report for it
14486                    // crashes are higher priority (in case there's a crash *and* an anr)
14487                    ActivityManager.ProcessErrorStateInfo report = null;
14488                    if (app.crashing) {
14489                        report = app.crashingReport;
14490                    } else if (app.notResponding) {
14491                        report = app.notRespondingReport;
14492                    }
14493
14494                    if (report != null) {
14495                        if (errList == null) {
14496                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14497                        }
14498                        errList.add(report);
14499                    } else {
14500                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14501                                " crashing = " + app.crashing +
14502                                " notResponding = " + app.notResponding);
14503                    }
14504                }
14505            }
14506        }
14507
14508        return errList;
14509    }
14510
14511    static int procStateToImportance(int procState, int memAdj,
14512            ActivityManager.RunningAppProcessInfo currApp) {
14513        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14514        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14515            currApp.lru = memAdj;
14516        } else {
14517            currApp.lru = 0;
14518        }
14519        return imp;
14520    }
14521
14522    private void fillInProcMemInfo(ProcessRecord app,
14523            ActivityManager.RunningAppProcessInfo outInfo) {
14524        outInfo.pid = app.pid;
14525        outInfo.uid = app.info.uid;
14526        if (mHeavyWeightProcess == app) {
14527            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14528        }
14529        if (app.persistent) {
14530            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14531        }
14532        if (app.activities.size() > 0) {
14533            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14534        }
14535        outInfo.lastTrimLevel = app.trimMemoryLevel;
14536        int adj = app.curAdj;
14537        int procState = app.curProcState;
14538        outInfo.importance = procStateToImportance(procState, adj, outInfo);
14539        outInfo.importanceReasonCode = app.adjTypeCode;
14540        outInfo.processState = app.curProcState;
14541    }
14542
14543    @Override
14544    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14545        enforceNotIsolatedCaller("getRunningAppProcesses");
14546
14547        final int callingUid = Binder.getCallingUid();
14548
14549        // Lazy instantiation of list
14550        List<ActivityManager.RunningAppProcessInfo> runList = null;
14551        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14552                callingUid) == PackageManager.PERMISSION_GRANTED;
14553        final int userId = UserHandle.getUserId(callingUid);
14554        final boolean allUids = isGetTasksAllowed(
14555                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14556
14557        synchronized (this) {
14558            // Iterate across all processes
14559            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14560                ProcessRecord app = mLruProcesses.get(i);
14561                if ((!allUsers && app.userId != userId)
14562                        || (!allUids && app.uid != callingUid)) {
14563                    continue;
14564                }
14565                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14566                    // Generate process state info for running application
14567                    ActivityManager.RunningAppProcessInfo currApp =
14568                        new ActivityManager.RunningAppProcessInfo(app.processName,
14569                                app.pid, app.getPackageList());
14570                    fillInProcMemInfo(app, currApp);
14571                    if (app.adjSource instanceof ProcessRecord) {
14572                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14573                        currApp.importanceReasonImportance =
14574                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14575                                        app.adjSourceProcState);
14576                    } else if (app.adjSource instanceof ActivityRecord) {
14577                        ActivityRecord r = (ActivityRecord)app.adjSource;
14578                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14579                    }
14580                    if (app.adjTarget instanceof ComponentName) {
14581                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14582                    }
14583                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14584                    //        + " lru=" + currApp.lru);
14585                    if (runList == null) {
14586                        runList = new ArrayList<>();
14587                    }
14588                    runList.add(currApp);
14589                }
14590            }
14591        }
14592        return runList;
14593    }
14594
14595    @Override
14596    public List<ApplicationInfo> getRunningExternalApplications() {
14597        enforceNotIsolatedCaller("getRunningExternalApplications");
14598        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14599        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14600        if (runningApps != null && runningApps.size() > 0) {
14601            Set<String> extList = new HashSet<String>();
14602            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14603                if (app.pkgList != null) {
14604                    for (String pkg : app.pkgList) {
14605                        extList.add(pkg);
14606                    }
14607                }
14608            }
14609            IPackageManager pm = AppGlobals.getPackageManager();
14610            for (String pkg : extList) {
14611                try {
14612                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14613                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14614                        retList.add(info);
14615                    }
14616                } catch (RemoteException e) {
14617                }
14618            }
14619        }
14620        return retList;
14621    }
14622
14623    @Override
14624    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14625        enforceNotIsolatedCaller("getMyMemoryState");
14626        synchronized (this) {
14627            ProcessRecord proc;
14628            synchronized (mPidsSelfLocked) {
14629                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14630            }
14631            fillInProcMemInfo(proc, outInfo);
14632        }
14633    }
14634
14635    @Override
14636    public int getMemoryTrimLevel() {
14637        enforceNotIsolatedCaller("getMyMemoryState");
14638        synchronized (this) {
14639            return mLastMemoryLevel;
14640        }
14641    }
14642
14643    @Override
14644    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14645            FileDescriptor err, String[] args, ShellCallback callback,
14646            ResultReceiver resultReceiver) {
14647        (new ActivityManagerShellCommand(this, false)).exec(
14648                this, in, out, err, args, callback, resultReceiver);
14649    }
14650
14651    @Override
14652    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14653        if (checkCallingPermission(android.Manifest.permission.DUMP)
14654                != PackageManager.PERMISSION_GRANTED) {
14655            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14656                    + Binder.getCallingPid()
14657                    + ", uid=" + Binder.getCallingUid()
14658                    + " without permission "
14659                    + android.Manifest.permission.DUMP);
14660            return;
14661        }
14662
14663        boolean dumpAll = false;
14664        boolean dumpClient = false;
14665        boolean dumpCheckin = false;
14666        boolean dumpCheckinFormat = false;
14667        boolean dumpVisibleStacksOnly = false;
14668        boolean dumpFocusedStackOnly = false;
14669        String dumpPackage = null;
14670
14671        int opti = 0;
14672        while (opti < args.length) {
14673            String opt = args[opti];
14674            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14675                break;
14676            }
14677            opti++;
14678            if ("-a".equals(opt)) {
14679                dumpAll = true;
14680            } else if ("-c".equals(opt)) {
14681                dumpClient = true;
14682            } else if ("-v".equals(opt)) {
14683                dumpVisibleStacksOnly = true;
14684            } else if ("-f".equals(opt)) {
14685                dumpFocusedStackOnly = true;
14686            } else if ("-p".equals(opt)) {
14687                if (opti < args.length) {
14688                    dumpPackage = args[opti];
14689                    opti++;
14690                } else {
14691                    pw.println("Error: -p option requires package argument");
14692                    return;
14693                }
14694                dumpClient = true;
14695            } else if ("--checkin".equals(opt)) {
14696                dumpCheckin = dumpCheckinFormat = true;
14697            } else if ("-C".equals(opt)) {
14698                dumpCheckinFormat = true;
14699            } else if ("-h".equals(opt)) {
14700                ActivityManagerShellCommand.dumpHelp(pw, true);
14701                return;
14702            } else {
14703                pw.println("Unknown argument: " + opt + "; use -h for help");
14704            }
14705        }
14706
14707        long origId = Binder.clearCallingIdentity();
14708        boolean more = false;
14709        // Is the caller requesting to dump a particular piece of data?
14710        if (opti < args.length) {
14711            String cmd = args[opti];
14712            opti++;
14713            if ("activities".equals(cmd) || "a".equals(cmd)) {
14714                synchronized (this) {
14715                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14716                }
14717            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14718                synchronized (this) {
14719                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14720                }
14721            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14722                String[] newArgs;
14723                String name;
14724                if (opti >= args.length) {
14725                    name = null;
14726                    newArgs = EMPTY_STRING_ARRAY;
14727                } else {
14728                    dumpPackage = args[opti];
14729                    opti++;
14730                    newArgs = new String[args.length - opti];
14731                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14732                            args.length - opti);
14733                }
14734                synchronized (this) {
14735                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14736                }
14737            } else if ("broadcast-stats".equals(cmd)) {
14738                String[] newArgs;
14739                String name;
14740                if (opti >= args.length) {
14741                    name = null;
14742                    newArgs = EMPTY_STRING_ARRAY;
14743                } else {
14744                    dumpPackage = args[opti];
14745                    opti++;
14746                    newArgs = new String[args.length - opti];
14747                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14748                            args.length - opti);
14749                }
14750                synchronized (this) {
14751                    if (dumpCheckinFormat) {
14752                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14753                                dumpPackage);
14754                    } else {
14755                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14756                    }
14757                }
14758            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14759                String[] newArgs;
14760                String name;
14761                if (opti >= args.length) {
14762                    name = null;
14763                    newArgs = EMPTY_STRING_ARRAY;
14764                } else {
14765                    dumpPackage = args[opti];
14766                    opti++;
14767                    newArgs = new String[args.length - opti];
14768                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14769                            args.length - opti);
14770                }
14771                synchronized (this) {
14772                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14773                }
14774            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14775                String[] newArgs;
14776                String name;
14777                if (opti >= args.length) {
14778                    name = null;
14779                    newArgs = EMPTY_STRING_ARRAY;
14780                } else {
14781                    dumpPackage = args[opti];
14782                    opti++;
14783                    newArgs = new String[args.length - opti];
14784                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14785                            args.length - opti);
14786                }
14787                synchronized (this) {
14788                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14789                }
14790            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14791                synchronized (this) {
14792                    dumpOomLocked(fd, pw, args, opti, true);
14793                }
14794            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14795                synchronized (this) {
14796                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14797                }
14798            } else if ("provider".equals(cmd)) {
14799                String[] newArgs;
14800                String name;
14801                if (opti >= args.length) {
14802                    name = null;
14803                    newArgs = EMPTY_STRING_ARRAY;
14804                } else {
14805                    name = args[opti];
14806                    opti++;
14807                    newArgs = new String[args.length - opti];
14808                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14809                }
14810                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14811                    pw.println("No providers match: " + name);
14812                    pw.println("Use -h for help.");
14813                }
14814            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14815                synchronized (this) {
14816                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14817                }
14818            } else if ("service".equals(cmd)) {
14819                String[] newArgs;
14820                String name;
14821                if (opti >= args.length) {
14822                    name = null;
14823                    newArgs = EMPTY_STRING_ARRAY;
14824                } else {
14825                    name = args[opti];
14826                    opti++;
14827                    newArgs = new String[args.length - opti];
14828                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14829                            args.length - opti);
14830                }
14831                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14832                    pw.println("No services match: " + name);
14833                    pw.println("Use -h for help.");
14834                }
14835            } else if ("package".equals(cmd)) {
14836                String[] newArgs;
14837                if (opti >= args.length) {
14838                    pw.println("package: no package name specified");
14839                    pw.println("Use -h for help.");
14840                } else {
14841                    dumpPackage = args[opti];
14842                    opti++;
14843                    newArgs = new String[args.length - opti];
14844                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14845                            args.length - opti);
14846                    args = newArgs;
14847                    opti = 0;
14848                    more = true;
14849                }
14850            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14851                synchronized (this) {
14852                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14853                }
14854            } else if ("settings".equals(cmd)) {
14855                synchronized (this) {
14856                    mConstants.dump(pw);
14857                }
14858            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14859                if (dumpClient) {
14860                    ActiveServices.ServiceDumper dumper;
14861                    synchronized (this) {
14862                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14863                                dumpPackage);
14864                    }
14865                    dumper.dumpWithClient();
14866                } else {
14867                    synchronized (this) {
14868                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14869                                dumpPackage).dumpLocked();
14870                    }
14871                }
14872            } else if ("locks".equals(cmd)) {
14873                LockGuard.dump(fd, pw, args);
14874            } else {
14875                // Dumping a single activity?
14876                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
14877                        dumpFocusedStackOnly)) {
14878                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14879                    int res = shell.exec(this, null, fd, null, args, null,
14880                            new ResultReceiver(null));
14881                    if (res < 0) {
14882                        pw.println("Bad activity command, or no activities match: " + cmd);
14883                        pw.println("Use -h for help.");
14884                    }
14885                }
14886            }
14887            if (!more) {
14888                Binder.restoreCallingIdentity(origId);
14889                return;
14890            }
14891        }
14892
14893        // No piece of data specified, dump everything.
14894        if (dumpCheckinFormat) {
14895            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14896        } else if (dumpClient) {
14897            ActiveServices.ServiceDumper sdumper;
14898            synchronized (this) {
14899                mConstants.dump(pw);
14900                pw.println();
14901                if (dumpAll) {
14902                    pw.println("-------------------------------------------------------------------------------");
14903                }
14904                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14905                pw.println();
14906                if (dumpAll) {
14907                    pw.println("-------------------------------------------------------------------------------");
14908                }
14909                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14910                pw.println();
14911                if (dumpAll) {
14912                    pw.println("-------------------------------------------------------------------------------");
14913                }
14914                if (dumpAll || dumpPackage != null) {
14915                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14916                    pw.println();
14917                    if (dumpAll) {
14918                        pw.println("-------------------------------------------------------------------------------");
14919                    }
14920                }
14921                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14922                pw.println();
14923                if (dumpAll) {
14924                    pw.println("-------------------------------------------------------------------------------");
14925                }
14926                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14927                pw.println();
14928                if (dumpAll) {
14929                    pw.println("-------------------------------------------------------------------------------");
14930                }
14931                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14932                        dumpPackage);
14933            }
14934            sdumper.dumpWithClient();
14935            pw.println();
14936            synchronized (this) {
14937                if (dumpAll) {
14938                    pw.println("-------------------------------------------------------------------------------");
14939                }
14940                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14941                pw.println();
14942                if (dumpAll) {
14943                    pw.println("-------------------------------------------------------------------------------");
14944                }
14945                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14946                if (mAssociations.size() > 0) {
14947                    pw.println();
14948                    if (dumpAll) {
14949                        pw.println("-------------------------------------------------------------------------------");
14950                    }
14951                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14952                }
14953                pw.println();
14954                if (dumpAll) {
14955                    pw.println("-------------------------------------------------------------------------------");
14956                }
14957                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14958            }
14959
14960        } else {
14961            synchronized (this) {
14962                mConstants.dump(pw);
14963                pw.println();
14964                if (dumpAll) {
14965                    pw.println("-------------------------------------------------------------------------------");
14966                }
14967                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14968                pw.println();
14969                if (dumpAll) {
14970                    pw.println("-------------------------------------------------------------------------------");
14971                }
14972                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14973                pw.println();
14974                if (dumpAll) {
14975                    pw.println("-------------------------------------------------------------------------------");
14976                }
14977                if (dumpAll || dumpPackage != null) {
14978                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14979                    pw.println();
14980                    if (dumpAll) {
14981                        pw.println("-------------------------------------------------------------------------------");
14982                    }
14983                }
14984                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14985                pw.println();
14986                if (dumpAll) {
14987                    pw.println("-------------------------------------------------------------------------------");
14988                }
14989                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14990                pw.println();
14991                if (dumpAll) {
14992                    pw.println("-------------------------------------------------------------------------------");
14993                }
14994                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14995                        .dumpLocked();
14996                pw.println();
14997                if (dumpAll) {
14998                    pw.println("-------------------------------------------------------------------------------");
14999                }
15000                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15001                pw.println();
15002                if (dumpAll) {
15003                    pw.println("-------------------------------------------------------------------------------");
15004                }
15005                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15006                if (mAssociations.size() > 0) {
15007                    pw.println();
15008                    if (dumpAll) {
15009                        pw.println("-------------------------------------------------------------------------------");
15010                    }
15011                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15012                }
15013                pw.println();
15014                if (dumpAll) {
15015                    pw.println("-------------------------------------------------------------------------------");
15016                }
15017                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15018            }
15019        }
15020        Binder.restoreCallingIdentity(origId);
15021    }
15022
15023    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15024            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15025        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15026
15027        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15028                dumpPackage);
15029        boolean needSep = printedAnything;
15030
15031        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15032                mStackSupervisor.getResumedActivityLocked(),
15033                dumpPackage, needSep, "  ResumedActivity: ");
15034        if (printed) {
15035            printedAnything = true;
15036            needSep = false;
15037        }
15038
15039        if (dumpPackage == null) {
15040            if (needSep) {
15041                pw.println();
15042            }
15043            needSep = true;
15044            printedAnything = true;
15045            mStackSupervisor.dump(pw, "  ");
15046        }
15047
15048        if (!printedAnything) {
15049            pw.println("  (nothing)");
15050        }
15051    }
15052
15053    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15054            int opti, boolean dumpAll, String dumpPackage) {
15055        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15056
15057        boolean printedAnything = false;
15058
15059        if (mRecentTasks != null && mRecentTasks.size() > 0) {
15060            boolean printedHeader = false;
15061
15062            final int N = mRecentTasks.size();
15063            for (int i=0; i<N; i++) {
15064                TaskRecord tr = mRecentTasks.get(i);
15065                if (dumpPackage != null) {
15066                    if (tr.realActivity == null ||
15067                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
15068                        continue;
15069                    }
15070                }
15071                if (!printedHeader) {
15072                    pw.println("  Recent tasks:");
15073                    printedHeader = true;
15074                    printedAnything = true;
15075                }
15076                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15077                        pw.println(tr);
15078                if (dumpAll) {
15079                    mRecentTasks.get(i).dump(pw, "    ");
15080                }
15081            }
15082        }
15083
15084        if (!printedAnything) {
15085            pw.println("  (nothing)");
15086        }
15087    }
15088
15089    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15090            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15091        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15092
15093        int dumpUid = 0;
15094        if (dumpPackage != null) {
15095            IPackageManager pm = AppGlobals.getPackageManager();
15096            try {
15097                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15098            } catch (RemoteException e) {
15099            }
15100        }
15101
15102        boolean printedAnything = false;
15103
15104        final long now = SystemClock.uptimeMillis();
15105
15106        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15107            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15108                    = mAssociations.valueAt(i1);
15109            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15110                SparseArray<ArrayMap<String, Association>> sourceUids
15111                        = targetComponents.valueAt(i2);
15112                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15113                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15114                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15115                        Association ass = sourceProcesses.valueAt(i4);
15116                        if (dumpPackage != null) {
15117                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15118                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15119                                continue;
15120                            }
15121                        }
15122                        printedAnything = true;
15123                        pw.print("  ");
15124                        pw.print(ass.mTargetProcess);
15125                        pw.print("/");
15126                        UserHandle.formatUid(pw, ass.mTargetUid);
15127                        pw.print(" <- ");
15128                        pw.print(ass.mSourceProcess);
15129                        pw.print("/");
15130                        UserHandle.formatUid(pw, ass.mSourceUid);
15131                        pw.println();
15132                        pw.print("    via ");
15133                        pw.print(ass.mTargetComponent.flattenToShortString());
15134                        pw.println();
15135                        pw.print("    ");
15136                        long dur = ass.mTime;
15137                        if (ass.mNesting > 0) {
15138                            dur += now - ass.mStartTime;
15139                        }
15140                        TimeUtils.formatDuration(dur, pw);
15141                        pw.print(" (");
15142                        pw.print(ass.mCount);
15143                        pw.print(" times)");
15144                        pw.print("  ");
15145                        for (int i=0; i<ass.mStateTimes.length; i++) {
15146                            long amt = ass.mStateTimes[i];
15147                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15148                                amt += now - ass.mLastStateUptime;
15149                            }
15150                            if (amt != 0) {
15151                                pw.print(" ");
15152                                pw.print(ProcessList.makeProcStateString(
15153                                            i + ActivityManager.MIN_PROCESS_STATE));
15154                                pw.print("=");
15155                                TimeUtils.formatDuration(amt, pw);
15156                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15157                                    pw.print("*");
15158                                }
15159                            }
15160                        }
15161                        pw.println();
15162                        if (ass.mNesting > 0) {
15163                            pw.print("    Currently active: ");
15164                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15165                            pw.println();
15166                        }
15167                    }
15168                }
15169            }
15170
15171        }
15172
15173        if (!printedAnything) {
15174            pw.println("  (nothing)");
15175        }
15176    }
15177
15178    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15179            String header, boolean needSep) {
15180        boolean printed = false;
15181        int whichAppId = -1;
15182        if (dumpPackage != null) {
15183            try {
15184                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15185                        dumpPackage, 0);
15186                whichAppId = UserHandle.getAppId(info.uid);
15187            } catch (NameNotFoundException e) {
15188                e.printStackTrace();
15189            }
15190        }
15191        for (int i=0; i<uids.size(); i++) {
15192            UidRecord uidRec = uids.valueAt(i);
15193            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15194                continue;
15195            }
15196            if (!printed) {
15197                printed = true;
15198                if (needSep) {
15199                    pw.println();
15200                }
15201                pw.print("  ");
15202                pw.println(header);
15203                needSep = true;
15204            }
15205            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15206            pw.print(": "); pw.println(uidRec);
15207        }
15208        return printed;
15209    }
15210
15211    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15212            int opti, boolean dumpAll, String dumpPackage) {
15213        boolean needSep = false;
15214        boolean printedAnything = false;
15215        int numPers = 0;
15216
15217        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15218
15219        if (dumpAll) {
15220            final int NP = mProcessNames.getMap().size();
15221            for (int ip=0; ip<NP; ip++) {
15222                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15223                final int NA = procs.size();
15224                for (int ia=0; ia<NA; ia++) {
15225                    ProcessRecord r = procs.valueAt(ia);
15226                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15227                        continue;
15228                    }
15229                    if (!needSep) {
15230                        pw.println("  All known processes:");
15231                        needSep = true;
15232                        printedAnything = true;
15233                    }
15234                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15235                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15236                        pw.print(" "); pw.println(r);
15237                    r.dump(pw, "    ");
15238                    if (r.persistent) {
15239                        numPers++;
15240                    }
15241                }
15242            }
15243        }
15244
15245        if (mIsolatedProcesses.size() > 0) {
15246            boolean printed = false;
15247            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15248                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15249                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15250                    continue;
15251                }
15252                if (!printed) {
15253                    if (needSep) {
15254                        pw.println();
15255                    }
15256                    pw.println("  Isolated process list (sorted by uid):");
15257                    printedAnything = true;
15258                    printed = true;
15259                    needSep = true;
15260                }
15261                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15262                pw.println(r);
15263            }
15264        }
15265
15266        if (mActiveInstrumentation.size() > 0) {
15267            boolean printed = false;
15268            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15269                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15270                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15271                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15272                    continue;
15273                }
15274                if (!printed) {
15275                    if (needSep) {
15276                        pw.println();
15277                    }
15278                    pw.println("  Active instrumentation:");
15279                    printedAnything = true;
15280                    printed = true;
15281                    needSep = true;
15282                }
15283                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15284                pw.println(ai);
15285                ai.dump(pw, "      ");
15286            }
15287        }
15288
15289        if (mActiveUids.size() > 0) {
15290            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15291                printedAnything = needSep = true;
15292            }
15293        }
15294        if (mValidateUids.size() > 0) {
15295            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15296                printedAnything = needSep = true;
15297            }
15298        }
15299
15300        if (mLruProcesses.size() > 0) {
15301            if (needSep) {
15302                pw.println();
15303            }
15304            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15305                    pw.print(" total, non-act at ");
15306                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15307                    pw.print(", non-svc at ");
15308                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15309                    pw.println("):");
15310            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15311            needSep = true;
15312            printedAnything = true;
15313        }
15314
15315        if (dumpAll || dumpPackage != null) {
15316            synchronized (mPidsSelfLocked) {
15317                boolean printed = false;
15318                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15319                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15320                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15321                        continue;
15322                    }
15323                    if (!printed) {
15324                        if (needSep) pw.println();
15325                        needSep = true;
15326                        pw.println("  PID mappings:");
15327                        printed = true;
15328                        printedAnything = true;
15329                    }
15330                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15331                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15332                }
15333            }
15334        }
15335
15336        if (mForegroundProcesses.size() > 0) {
15337            synchronized (mPidsSelfLocked) {
15338                boolean printed = false;
15339                for (int i=0; i<mForegroundProcesses.size(); i++) {
15340                    ProcessRecord r = mPidsSelfLocked.get(
15341                            mForegroundProcesses.valueAt(i).pid);
15342                    if (dumpPackage != null && (r == null
15343                            || !r.pkgList.containsKey(dumpPackage))) {
15344                        continue;
15345                    }
15346                    if (!printed) {
15347                        if (needSep) pw.println();
15348                        needSep = true;
15349                        pw.println("  Foreground Processes:");
15350                        printed = true;
15351                        printedAnything = true;
15352                    }
15353                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
15354                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
15355                }
15356            }
15357        }
15358
15359        if (mPersistentStartingProcesses.size() > 0) {
15360            if (needSep) pw.println();
15361            needSep = true;
15362            printedAnything = true;
15363            pw.println("  Persisent processes that are starting:");
15364            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15365                    "Starting Norm", "Restarting PERS", dumpPackage);
15366        }
15367
15368        if (mRemovedProcesses.size() > 0) {
15369            if (needSep) pw.println();
15370            needSep = true;
15371            printedAnything = true;
15372            pw.println("  Processes that are being removed:");
15373            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15374                    "Removed Norm", "Removed PERS", dumpPackage);
15375        }
15376
15377        if (mProcessesOnHold.size() > 0) {
15378            if (needSep) pw.println();
15379            needSep = true;
15380            printedAnything = true;
15381            pw.println("  Processes that are on old until the system is ready:");
15382            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15383                    "OnHold Norm", "OnHold PERS", dumpPackage);
15384        }
15385
15386        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15387
15388        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15389        if (needSep) {
15390            printedAnything = true;
15391        }
15392
15393        if (dumpPackage == null) {
15394            pw.println();
15395            needSep = false;
15396            mUserController.dump(pw, dumpAll);
15397        }
15398        if (mHomeProcess != null && (dumpPackage == null
15399                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15400            if (needSep) {
15401                pw.println();
15402                needSep = false;
15403            }
15404            pw.println("  mHomeProcess: " + mHomeProcess);
15405        }
15406        if (mPreviousProcess != null && (dumpPackage == null
15407                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15408            if (needSep) {
15409                pw.println();
15410                needSep = false;
15411            }
15412            pw.println("  mPreviousProcess: " + mPreviousProcess);
15413        }
15414        if (dumpAll) {
15415            StringBuilder sb = new StringBuilder(128);
15416            sb.append("  mPreviousProcessVisibleTime: ");
15417            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15418            pw.println(sb);
15419        }
15420        if (mHeavyWeightProcess != null && (dumpPackage == null
15421                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15422            if (needSep) {
15423                pw.println();
15424                needSep = false;
15425            }
15426            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15427        }
15428        if (dumpPackage == null) {
15429            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15430            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15431        }
15432        if (dumpAll) {
15433            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15434            if (mCompatModePackages.getPackages().size() > 0) {
15435                boolean printed = false;
15436                for (Map.Entry<String, Integer> entry
15437                        : mCompatModePackages.getPackages().entrySet()) {
15438                    String pkg = entry.getKey();
15439                    int mode = entry.getValue();
15440                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15441                        continue;
15442                    }
15443                    if (!printed) {
15444                        pw.println("  mScreenCompatPackages:");
15445                        printed = true;
15446                    }
15447                    pw.print("    "); pw.print(pkg); pw.print(": ");
15448                            pw.print(mode); pw.println();
15449                }
15450            }
15451            final int NI = mUidObservers.getRegisteredCallbackCount();
15452            boolean printed = false;
15453            for (int i=0; i<NI; i++) {
15454                final UidObserverRegistration reg = (UidObserverRegistration)
15455                        mUidObservers.getRegisteredCallbackCookie(i);
15456                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15457                    if (!printed) {
15458                        pw.println("  mUidObservers:");
15459                        printed = true;
15460                    }
15461                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15462                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15463                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15464                        pw.print(" IDLE");
15465                    }
15466                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15467                        pw.print(" ACT" );
15468                    }
15469                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15470                        pw.print(" GONE");
15471                    }
15472                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15473                        pw.print(" STATE");
15474                        pw.print(" (cut="); pw.print(reg.cutpoint);
15475                        pw.print(")");
15476                    }
15477                    pw.println();
15478                    if (reg.lastProcStates != null) {
15479                        final int NJ = reg.lastProcStates.size();
15480                        for (int j=0; j<NJ; j++) {
15481                            pw.print("      Last ");
15482                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15483                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15484                        }
15485                    }
15486                }
15487            }
15488            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15489            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15490        }
15491        if (dumpPackage == null) {
15492            pw.println("  mWakefulness="
15493                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15494            pw.println("  mSleepTokens=" + mSleepTokens);
15495            pw.println("  mSleeping=" + mSleeping);
15496            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15497            if (mRunningVoice != null) {
15498                pw.println("  mRunningVoice=" + mRunningVoice);
15499                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15500            }
15501        }
15502        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15503                || mOrigWaitForDebugger) {
15504            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15505                    || dumpPackage.equals(mOrigDebugApp)) {
15506                if (needSep) {
15507                    pw.println();
15508                    needSep = false;
15509                }
15510                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15511                        + " mDebugTransient=" + mDebugTransient
15512                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15513            }
15514        }
15515        if (mCurAppTimeTracker != null) {
15516            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15517        }
15518        if (mMemWatchProcesses.getMap().size() > 0) {
15519            pw.println("  Mem watch processes:");
15520            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15521                    = mMemWatchProcesses.getMap();
15522            for (int i=0; i<procs.size(); i++) {
15523                final String proc = procs.keyAt(i);
15524                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15525                for (int j=0; j<uids.size(); j++) {
15526                    if (needSep) {
15527                        pw.println();
15528                        needSep = false;
15529                    }
15530                    StringBuilder sb = new StringBuilder();
15531                    sb.append("    ").append(proc).append('/');
15532                    UserHandle.formatUid(sb, uids.keyAt(j));
15533                    Pair<Long, String> val = uids.valueAt(j);
15534                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15535                    if (val.second != null) {
15536                        sb.append(", report to ").append(val.second);
15537                    }
15538                    pw.println(sb.toString());
15539                }
15540            }
15541            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15542            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15543            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15544                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15545        }
15546        if (mTrackAllocationApp != null) {
15547            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15548                if (needSep) {
15549                    pw.println();
15550                    needSep = false;
15551                }
15552                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15553            }
15554        }
15555        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15556                || mProfileFd != null) {
15557            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15558                if (needSep) {
15559                    pw.println();
15560                    needSep = false;
15561                }
15562                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15563                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15564                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15565                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15566                pw.println("  mProfileType=" + mProfileType);
15567            }
15568        }
15569        if (mNativeDebuggingApp != null) {
15570            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15571                if (needSep) {
15572                    pw.println();
15573                    needSep = false;
15574                }
15575                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15576            }
15577        }
15578        if (dumpPackage == null) {
15579            if (mAlwaysFinishActivities) {
15580                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15581            }
15582            if (mController != null) {
15583                pw.println("  mController=" + mController
15584                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15585            }
15586            if (dumpAll) {
15587                pw.println("  Total persistent processes: " + numPers);
15588                pw.println("  mProcessesReady=" + mProcessesReady
15589                        + " mSystemReady=" + mSystemReady
15590                        + " mBooted=" + mBooted
15591                        + " mFactoryTest=" + mFactoryTest);
15592                pw.println("  mBooting=" + mBooting
15593                        + " mCallFinishBooting=" + mCallFinishBooting
15594                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15595                pw.print("  mLastPowerCheckRealtime=");
15596                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15597                        pw.println("");
15598                pw.print("  mLastPowerCheckUptime=");
15599                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15600                        pw.println("");
15601                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15602                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15603                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15604                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15605                        + " (" + mLruProcesses.size() + " total)"
15606                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15607                        + " mNumServiceProcs=" + mNumServiceProcs
15608                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15609                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15610                        + " mLastMemoryLevel=" + mLastMemoryLevel
15611                        + " mLastNumProcesses=" + mLastNumProcesses);
15612                long now = SystemClock.uptimeMillis();
15613                pw.print("  mLastIdleTime=");
15614                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15615                        pw.print(" mLowRamSinceLastIdle=");
15616                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15617                        pw.println();
15618            }
15619        }
15620
15621        if (!printedAnything) {
15622            pw.println("  (nothing)");
15623        }
15624    }
15625
15626    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15627            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15628        if (mProcessesToGc.size() > 0) {
15629            boolean printed = false;
15630            long now = SystemClock.uptimeMillis();
15631            for (int i=0; i<mProcessesToGc.size(); i++) {
15632                ProcessRecord proc = mProcessesToGc.get(i);
15633                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15634                    continue;
15635                }
15636                if (!printed) {
15637                    if (needSep) pw.println();
15638                    needSep = true;
15639                    pw.println("  Processes that are waiting to GC:");
15640                    printed = true;
15641                }
15642                pw.print("    Process "); pw.println(proc);
15643                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15644                        pw.print(", last gced=");
15645                        pw.print(now-proc.lastRequestedGc);
15646                        pw.print(" ms ago, last lowMem=");
15647                        pw.print(now-proc.lastLowMemory);
15648                        pw.println(" ms ago");
15649
15650            }
15651        }
15652        return needSep;
15653    }
15654
15655    void printOomLevel(PrintWriter pw, String name, int adj) {
15656        pw.print("    ");
15657        if (adj >= 0) {
15658            pw.print(' ');
15659            if (adj < 10) pw.print(' ');
15660        } else {
15661            if (adj > -10) pw.print(' ');
15662        }
15663        pw.print(adj);
15664        pw.print(": ");
15665        pw.print(name);
15666        pw.print(" (");
15667        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15668        pw.println(")");
15669    }
15670
15671    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15672            int opti, boolean dumpAll) {
15673        boolean needSep = false;
15674
15675        if (mLruProcesses.size() > 0) {
15676            if (needSep) pw.println();
15677            needSep = true;
15678            pw.println("  OOM levels:");
15679            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15680            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15681            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15682            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15683            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15684            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15685            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15686            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15687            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15688            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15689            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15690            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15691            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15692            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15693
15694            if (needSep) pw.println();
15695            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15696                    pw.print(" total, non-act at ");
15697                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15698                    pw.print(", non-svc at ");
15699                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15700                    pw.println("):");
15701            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15702            needSep = true;
15703        }
15704
15705        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15706
15707        pw.println();
15708        pw.println("  mHomeProcess: " + mHomeProcess);
15709        pw.println("  mPreviousProcess: " + mPreviousProcess);
15710        if (mHeavyWeightProcess != null) {
15711            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15712        }
15713
15714        return true;
15715    }
15716
15717    /**
15718     * There are three ways to call this:
15719     *  - no provider specified: dump all the providers
15720     *  - a flattened component name that matched an existing provider was specified as the
15721     *    first arg: dump that one provider
15722     *  - the first arg isn't the flattened component name of an existing provider:
15723     *    dump all providers whose component contains the first arg as a substring
15724     */
15725    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15726            int opti, boolean dumpAll) {
15727        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15728    }
15729
15730    static class ItemMatcher {
15731        ArrayList<ComponentName> components;
15732        ArrayList<String> strings;
15733        ArrayList<Integer> objects;
15734        boolean all;
15735
15736        ItemMatcher() {
15737            all = true;
15738        }
15739
15740        void build(String name) {
15741            ComponentName componentName = ComponentName.unflattenFromString(name);
15742            if (componentName != null) {
15743                if (components == null) {
15744                    components = new ArrayList<ComponentName>();
15745                }
15746                components.add(componentName);
15747                all = false;
15748            } else {
15749                int objectId = 0;
15750                // Not a '/' separated full component name; maybe an object ID?
15751                try {
15752                    objectId = Integer.parseInt(name, 16);
15753                    if (objects == null) {
15754                        objects = new ArrayList<Integer>();
15755                    }
15756                    objects.add(objectId);
15757                    all = false;
15758                } catch (RuntimeException e) {
15759                    // Not an integer; just do string match.
15760                    if (strings == null) {
15761                        strings = new ArrayList<String>();
15762                    }
15763                    strings.add(name);
15764                    all = false;
15765                }
15766            }
15767        }
15768
15769        int build(String[] args, int opti) {
15770            for (; opti<args.length; opti++) {
15771                String name = args[opti];
15772                if ("--".equals(name)) {
15773                    return opti+1;
15774                }
15775                build(name);
15776            }
15777            return opti;
15778        }
15779
15780        boolean match(Object object, ComponentName comp) {
15781            if (all) {
15782                return true;
15783            }
15784            if (components != null) {
15785                for (int i=0; i<components.size(); i++) {
15786                    if (components.get(i).equals(comp)) {
15787                        return true;
15788                    }
15789                }
15790            }
15791            if (objects != null) {
15792                for (int i=0; i<objects.size(); i++) {
15793                    if (System.identityHashCode(object) == objects.get(i)) {
15794                        return true;
15795                    }
15796                }
15797            }
15798            if (strings != null) {
15799                String flat = comp.flattenToString();
15800                for (int i=0; i<strings.size(); i++) {
15801                    if (flat.contains(strings.get(i))) {
15802                        return true;
15803                    }
15804                }
15805            }
15806            return false;
15807        }
15808    }
15809
15810    /**
15811     * There are three things that cmd can be:
15812     *  - a flattened component name that matches an existing activity
15813     *  - the cmd arg isn't the flattened component name of an existing activity:
15814     *    dump all activity whose component contains the cmd as a substring
15815     *  - A hex number of the ActivityRecord object instance.
15816     *
15817     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
15818     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
15819     */
15820    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15821            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
15822        ArrayList<ActivityRecord> activities;
15823
15824        synchronized (this) {
15825            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
15826                    dumpFocusedStackOnly);
15827        }
15828
15829        if (activities.size() <= 0) {
15830            return false;
15831        }
15832
15833        String[] newArgs = new String[args.length - opti];
15834        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15835
15836        TaskRecord lastTask = null;
15837        boolean needSep = false;
15838        for (int i=activities.size()-1; i>=0; i--) {
15839            ActivityRecord r = activities.get(i);
15840            if (needSep) {
15841                pw.println();
15842            }
15843            needSep = true;
15844            synchronized (this) {
15845                if (lastTask != r.task) {
15846                    lastTask = r.task;
15847                    pw.print("TASK "); pw.print(lastTask.affinity);
15848                            pw.print(" id="); pw.print(lastTask.taskId);
15849                            pw.print(" userId="); pw.println(lastTask.userId);
15850                    if (dumpAll) {
15851                        lastTask.dump(pw, "  ");
15852                    }
15853                }
15854            }
15855            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15856        }
15857        return true;
15858    }
15859
15860    /**
15861     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15862     * there is a thread associated with the activity.
15863     */
15864    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15865            final ActivityRecord r, String[] args, boolean dumpAll) {
15866        String innerPrefix = prefix + "  ";
15867        synchronized (this) {
15868            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15869                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15870                    pw.print(" pid=");
15871                    if (r.app != null) pw.println(r.app.pid);
15872                    else pw.println("(not running)");
15873            if (dumpAll) {
15874                r.dump(pw, innerPrefix);
15875            }
15876        }
15877        if (r.app != null && r.app.thread != null) {
15878            // flush anything that is already in the PrintWriter since the thread is going
15879            // to write to the file descriptor directly
15880            pw.flush();
15881            try {
15882                TransferPipe tp = new TransferPipe();
15883                try {
15884                    r.app.thread.dumpActivity(tp.getWriteFd(),
15885                            r.appToken, innerPrefix, args);
15886                    tp.go(fd);
15887                } finally {
15888                    tp.kill();
15889                }
15890            } catch (IOException e) {
15891                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15892            } catch (RemoteException e) {
15893                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15894            }
15895        }
15896    }
15897
15898    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15899            int opti, boolean dumpAll, String dumpPackage) {
15900        boolean needSep = false;
15901        boolean onlyHistory = false;
15902        boolean printedAnything = false;
15903
15904        if ("history".equals(dumpPackage)) {
15905            if (opti < args.length && "-s".equals(args[opti])) {
15906                dumpAll = false;
15907            }
15908            onlyHistory = true;
15909            dumpPackage = null;
15910        }
15911
15912        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15913        if (!onlyHistory && dumpAll) {
15914            if (mRegisteredReceivers.size() > 0) {
15915                boolean printed = false;
15916                Iterator it = mRegisteredReceivers.values().iterator();
15917                while (it.hasNext()) {
15918                    ReceiverList r = (ReceiverList)it.next();
15919                    if (dumpPackage != null && (r.app == null ||
15920                            !dumpPackage.equals(r.app.info.packageName))) {
15921                        continue;
15922                    }
15923                    if (!printed) {
15924                        pw.println("  Registered Receivers:");
15925                        needSep = true;
15926                        printed = true;
15927                        printedAnything = true;
15928                    }
15929                    pw.print("  * "); pw.println(r);
15930                    r.dump(pw, "    ");
15931                }
15932            }
15933
15934            if (mReceiverResolver.dump(pw, needSep ?
15935                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15936                    "    ", dumpPackage, false, false)) {
15937                needSep = true;
15938                printedAnything = true;
15939            }
15940        }
15941
15942        for (BroadcastQueue q : mBroadcastQueues) {
15943            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15944            printedAnything |= needSep;
15945        }
15946
15947        needSep = true;
15948
15949        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15950            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15951                if (needSep) {
15952                    pw.println();
15953                }
15954                needSep = true;
15955                printedAnything = true;
15956                pw.print("  Sticky broadcasts for user ");
15957                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15958                StringBuilder sb = new StringBuilder(128);
15959                for (Map.Entry<String, ArrayList<Intent>> ent
15960                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15961                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15962                    if (dumpAll) {
15963                        pw.println(":");
15964                        ArrayList<Intent> intents = ent.getValue();
15965                        final int N = intents.size();
15966                        for (int i=0; i<N; i++) {
15967                            sb.setLength(0);
15968                            sb.append("    Intent: ");
15969                            intents.get(i).toShortString(sb, false, true, false, false);
15970                            pw.println(sb.toString());
15971                            Bundle bundle = intents.get(i).getExtras();
15972                            if (bundle != null) {
15973                                pw.print("      ");
15974                                pw.println(bundle.toString());
15975                            }
15976                        }
15977                    } else {
15978                        pw.println("");
15979                    }
15980                }
15981            }
15982        }
15983
15984        if (!onlyHistory && dumpAll) {
15985            pw.println();
15986            for (BroadcastQueue queue : mBroadcastQueues) {
15987                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15988                        + queue.mBroadcastsScheduled);
15989            }
15990            pw.println("  mHandler:");
15991            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15992            needSep = true;
15993            printedAnything = true;
15994        }
15995
15996        if (!printedAnything) {
15997            pw.println("  (nothing)");
15998        }
15999    }
16000
16001    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16002            int opti, boolean dumpAll, String dumpPackage) {
16003        if (mCurBroadcastStats == null) {
16004            return;
16005        }
16006
16007        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16008        final long now = SystemClock.elapsedRealtime();
16009        if (mLastBroadcastStats != null) {
16010            pw.print("  Last stats (from ");
16011            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16012            pw.print(" to ");
16013            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16014            pw.print(", ");
16015            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16016                    - mLastBroadcastStats.mStartUptime, pw);
16017            pw.println(" uptime):");
16018            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16019                pw.println("    (nothing)");
16020            }
16021            pw.println();
16022        }
16023        pw.print("  Current stats (from ");
16024        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16025        pw.print(" to now, ");
16026        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16027                - mCurBroadcastStats.mStartUptime, pw);
16028        pw.println(" uptime):");
16029        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16030            pw.println("    (nothing)");
16031        }
16032    }
16033
16034    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16035            int opti, boolean fullCheckin, String dumpPackage) {
16036        if (mCurBroadcastStats == null) {
16037            return;
16038        }
16039
16040        if (mLastBroadcastStats != null) {
16041            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16042            if (fullCheckin) {
16043                mLastBroadcastStats = null;
16044                return;
16045            }
16046        }
16047        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16048        if (fullCheckin) {
16049            mCurBroadcastStats = null;
16050        }
16051    }
16052
16053    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16054            int opti, boolean dumpAll, String dumpPackage) {
16055        boolean needSep;
16056        boolean printedAnything = false;
16057
16058        ItemMatcher matcher = new ItemMatcher();
16059        matcher.build(args, opti);
16060
16061        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16062
16063        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16064        printedAnything |= needSep;
16065
16066        if (mLaunchingProviders.size() > 0) {
16067            boolean printed = false;
16068            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16069                ContentProviderRecord r = mLaunchingProviders.get(i);
16070                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16071                    continue;
16072                }
16073                if (!printed) {
16074                    if (needSep) pw.println();
16075                    needSep = true;
16076                    pw.println("  Launching content providers:");
16077                    printed = true;
16078                    printedAnything = true;
16079                }
16080                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16081                        pw.println(r);
16082            }
16083        }
16084
16085        if (!printedAnything) {
16086            pw.println("  (nothing)");
16087        }
16088    }
16089
16090    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16091            int opti, boolean dumpAll, String dumpPackage) {
16092        boolean needSep = false;
16093        boolean printedAnything = false;
16094
16095        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16096
16097        if (mGrantedUriPermissions.size() > 0) {
16098            boolean printed = false;
16099            int dumpUid = -2;
16100            if (dumpPackage != null) {
16101                try {
16102                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16103                            MATCH_ANY_USER, 0);
16104                } catch (NameNotFoundException e) {
16105                    dumpUid = -1;
16106                }
16107            }
16108            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16109                int uid = mGrantedUriPermissions.keyAt(i);
16110                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16111                    continue;
16112                }
16113                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16114                if (!printed) {
16115                    if (needSep) pw.println();
16116                    needSep = true;
16117                    pw.println("  Granted Uri Permissions:");
16118                    printed = true;
16119                    printedAnything = true;
16120                }
16121                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16122                for (UriPermission perm : perms.values()) {
16123                    pw.print("    "); pw.println(perm);
16124                    if (dumpAll) {
16125                        perm.dump(pw, "      ");
16126                    }
16127                }
16128            }
16129        }
16130
16131        if (!printedAnything) {
16132            pw.println("  (nothing)");
16133        }
16134    }
16135
16136    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16137            int opti, boolean dumpAll, String dumpPackage) {
16138        boolean printed = false;
16139
16140        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16141
16142        if (mIntentSenderRecords.size() > 0) {
16143            Iterator<WeakReference<PendingIntentRecord>> it
16144                    = mIntentSenderRecords.values().iterator();
16145            while (it.hasNext()) {
16146                WeakReference<PendingIntentRecord> ref = it.next();
16147                PendingIntentRecord rec = ref != null ? ref.get(): null;
16148                if (dumpPackage != null && (rec == null
16149                        || !dumpPackage.equals(rec.key.packageName))) {
16150                    continue;
16151                }
16152                printed = true;
16153                if (rec != null) {
16154                    pw.print("  * "); pw.println(rec);
16155                    if (dumpAll) {
16156                        rec.dump(pw, "    ");
16157                    }
16158                } else {
16159                    pw.print("  * "); pw.println(ref);
16160                }
16161            }
16162        }
16163
16164        if (!printed) {
16165            pw.println("  (nothing)");
16166        }
16167    }
16168
16169    private static final int dumpProcessList(PrintWriter pw,
16170            ActivityManagerService service, List list,
16171            String prefix, String normalLabel, String persistentLabel,
16172            String dumpPackage) {
16173        int numPers = 0;
16174        final int N = list.size()-1;
16175        for (int i=N; i>=0; i--) {
16176            ProcessRecord r = (ProcessRecord)list.get(i);
16177            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16178                continue;
16179            }
16180            pw.println(String.format("%s%s #%2d: %s",
16181                    prefix, (r.persistent ? persistentLabel : normalLabel),
16182                    i, r.toString()));
16183            if (r.persistent) {
16184                numPers++;
16185            }
16186        }
16187        return numPers;
16188    }
16189
16190    private static final boolean dumpProcessOomList(PrintWriter pw,
16191            ActivityManagerService service, List<ProcessRecord> origList,
16192            String prefix, String normalLabel, String persistentLabel,
16193            boolean inclDetails, String dumpPackage) {
16194
16195        ArrayList<Pair<ProcessRecord, Integer>> list
16196                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16197        for (int i=0; i<origList.size(); i++) {
16198            ProcessRecord r = origList.get(i);
16199            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16200                continue;
16201            }
16202            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16203        }
16204
16205        if (list.size() <= 0) {
16206            return false;
16207        }
16208
16209        Comparator<Pair<ProcessRecord, Integer>> comparator
16210                = new Comparator<Pair<ProcessRecord, Integer>>() {
16211            @Override
16212            public int compare(Pair<ProcessRecord, Integer> object1,
16213                    Pair<ProcessRecord, Integer> object2) {
16214                if (object1.first.setAdj != object2.first.setAdj) {
16215                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16216                }
16217                if (object1.first.setProcState != object2.first.setProcState) {
16218                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16219                }
16220                if (object1.second.intValue() != object2.second.intValue()) {
16221                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16222                }
16223                return 0;
16224            }
16225        };
16226
16227        Collections.sort(list, comparator);
16228
16229        final long curRealtime = SystemClock.elapsedRealtime();
16230        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16231        final long curUptime = SystemClock.uptimeMillis();
16232        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16233
16234        for (int i=list.size()-1; i>=0; i--) {
16235            ProcessRecord r = list.get(i).first;
16236            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16237            char schedGroup;
16238            switch (r.setSchedGroup) {
16239                case ProcessList.SCHED_GROUP_BACKGROUND:
16240                    schedGroup = 'B';
16241                    break;
16242                case ProcessList.SCHED_GROUP_DEFAULT:
16243                    schedGroup = 'F';
16244                    break;
16245                case ProcessList.SCHED_GROUP_TOP_APP:
16246                    schedGroup = 'T';
16247                    break;
16248                default:
16249                    schedGroup = '?';
16250                    break;
16251            }
16252            char foreground;
16253            if (r.foregroundActivities) {
16254                foreground = 'A';
16255            } else if (r.foregroundServices) {
16256                foreground = 'S';
16257            } else {
16258                foreground = ' ';
16259            }
16260            String procState = ProcessList.makeProcStateString(r.curProcState);
16261            pw.print(prefix);
16262            pw.print(r.persistent ? persistentLabel : normalLabel);
16263            pw.print(" #");
16264            int num = (origList.size()-1)-list.get(i).second;
16265            if (num < 10) pw.print(' ');
16266            pw.print(num);
16267            pw.print(": ");
16268            pw.print(oomAdj);
16269            pw.print(' ');
16270            pw.print(schedGroup);
16271            pw.print('/');
16272            pw.print(foreground);
16273            pw.print('/');
16274            pw.print(procState);
16275            pw.print(" trm:");
16276            if (r.trimMemoryLevel < 10) pw.print(' ');
16277            pw.print(r.trimMemoryLevel);
16278            pw.print(' ');
16279            pw.print(r.toShortString());
16280            pw.print(" (");
16281            pw.print(r.adjType);
16282            pw.println(')');
16283            if (r.adjSource != null || r.adjTarget != null) {
16284                pw.print(prefix);
16285                pw.print("    ");
16286                if (r.adjTarget instanceof ComponentName) {
16287                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16288                } else if (r.adjTarget != null) {
16289                    pw.print(r.adjTarget.toString());
16290                } else {
16291                    pw.print("{null}");
16292                }
16293                pw.print("<=");
16294                if (r.adjSource instanceof ProcessRecord) {
16295                    pw.print("Proc{");
16296                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16297                    pw.println("}");
16298                } else if (r.adjSource != null) {
16299                    pw.println(r.adjSource.toString());
16300                } else {
16301                    pw.println("{null}");
16302                }
16303            }
16304            if (inclDetails) {
16305                pw.print(prefix);
16306                pw.print("    ");
16307                pw.print("oom: max="); pw.print(r.maxAdj);
16308                pw.print(" curRaw="); pw.print(r.curRawAdj);
16309                pw.print(" setRaw="); pw.print(r.setRawAdj);
16310                pw.print(" cur="); pw.print(r.curAdj);
16311                pw.print(" set="); pw.println(r.setAdj);
16312                pw.print(prefix);
16313                pw.print("    ");
16314                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16315                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16316                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16317                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16318                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16319                pw.println();
16320                pw.print(prefix);
16321                pw.print("    ");
16322                pw.print("cached="); pw.print(r.cached);
16323                pw.print(" empty="); pw.print(r.empty);
16324                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16325
16326                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16327                    if (r.lastWakeTime != 0) {
16328                        long wtime;
16329                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16330                        synchronized (stats) {
16331                            wtime = stats.getProcessWakeTime(r.info.uid,
16332                                    r.pid, curRealtime);
16333                        }
16334                        long timeUsed = wtime - r.lastWakeTime;
16335                        pw.print(prefix);
16336                        pw.print("    ");
16337                        pw.print("keep awake over ");
16338                        TimeUtils.formatDuration(realtimeSince, pw);
16339                        pw.print(" used ");
16340                        TimeUtils.formatDuration(timeUsed, pw);
16341                        pw.print(" (");
16342                        pw.print((timeUsed*100)/realtimeSince);
16343                        pw.println("%)");
16344                    }
16345                    if (r.lastCpuTime != 0) {
16346                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16347                        pw.print(prefix);
16348                        pw.print("    ");
16349                        pw.print("run cpu over ");
16350                        TimeUtils.formatDuration(uptimeSince, pw);
16351                        pw.print(" used ");
16352                        TimeUtils.formatDuration(timeUsed, pw);
16353                        pw.print(" (");
16354                        pw.print((timeUsed*100)/uptimeSince);
16355                        pw.println("%)");
16356                    }
16357                }
16358            }
16359        }
16360        return true;
16361    }
16362
16363    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16364            String[] args) {
16365        ArrayList<ProcessRecord> procs;
16366        synchronized (this) {
16367            if (args != null && args.length > start
16368                    && args[start].charAt(0) != '-') {
16369                procs = new ArrayList<ProcessRecord>();
16370                int pid = -1;
16371                try {
16372                    pid = Integer.parseInt(args[start]);
16373                } catch (NumberFormatException e) {
16374                }
16375                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16376                    ProcessRecord proc = mLruProcesses.get(i);
16377                    if (proc.pid == pid) {
16378                        procs.add(proc);
16379                    } else if (allPkgs && proc.pkgList != null
16380                            && proc.pkgList.containsKey(args[start])) {
16381                        procs.add(proc);
16382                    } else if (proc.processName.equals(args[start])) {
16383                        procs.add(proc);
16384                    }
16385                }
16386                if (procs.size() <= 0) {
16387                    return null;
16388                }
16389            } else {
16390                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16391            }
16392        }
16393        return procs;
16394    }
16395
16396    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16397            PrintWriter pw, String[] args) {
16398        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16399        if (procs == null) {
16400            pw.println("No process found for: " + args[0]);
16401            return;
16402        }
16403
16404        long uptime = SystemClock.uptimeMillis();
16405        long realtime = SystemClock.elapsedRealtime();
16406        pw.println("Applications Graphics Acceleration Info:");
16407        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16408
16409        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16410            ProcessRecord r = procs.get(i);
16411            if (r.thread != null) {
16412                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16413                pw.flush();
16414                try {
16415                    TransferPipe tp = new TransferPipe();
16416                    try {
16417                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16418                        tp.go(fd);
16419                    } finally {
16420                        tp.kill();
16421                    }
16422                } catch (IOException e) {
16423                    pw.println("Failure while dumping the app: " + r);
16424                    pw.flush();
16425                } catch (RemoteException e) {
16426                    pw.println("Got a RemoteException while dumping the app " + r);
16427                    pw.flush();
16428                }
16429            }
16430        }
16431    }
16432
16433    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16434        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16435        if (procs == null) {
16436            pw.println("No process found for: " + args[0]);
16437            return;
16438        }
16439
16440        pw.println("Applications Database Info:");
16441
16442        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16443            ProcessRecord r = procs.get(i);
16444            if (r.thread != null) {
16445                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16446                pw.flush();
16447                try {
16448                    TransferPipe tp = new TransferPipe();
16449                    try {
16450                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16451                        tp.go(fd);
16452                    } finally {
16453                        tp.kill();
16454                    }
16455                } catch (IOException e) {
16456                    pw.println("Failure while dumping the app: " + r);
16457                    pw.flush();
16458                } catch (RemoteException e) {
16459                    pw.println("Got a RemoteException while dumping the app " + r);
16460                    pw.flush();
16461                }
16462            }
16463        }
16464    }
16465
16466    final static class MemItem {
16467        final boolean isProc;
16468        final String label;
16469        final String shortLabel;
16470        final long pss;
16471        final long swapPss;
16472        final int id;
16473        final boolean hasActivities;
16474        ArrayList<MemItem> subitems;
16475
16476        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16477                boolean _hasActivities) {
16478            isProc = true;
16479            label = _label;
16480            shortLabel = _shortLabel;
16481            pss = _pss;
16482            swapPss = _swapPss;
16483            id = _id;
16484            hasActivities = _hasActivities;
16485        }
16486
16487        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16488            isProc = false;
16489            label = _label;
16490            shortLabel = _shortLabel;
16491            pss = _pss;
16492            swapPss = _swapPss;
16493            id = _id;
16494            hasActivities = false;
16495        }
16496    }
16497
16498    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16499            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16500        if (sort && !isCompact) {
16501            Collections.sort(items, new Comparator<MemItem>() {
16502                @Override
16503                public int compare(MemItem lhs, MemItem rhs) {
16504                    if (lhs.pss < rhs.pss) {
16505                        return 1;
16506                    } else if (lhs.pss > rhs.pss) {
16507                        return -1;
16508                    }
16509                    return 0;
16510                }
16511            });
16512        }
16513
16514        for (int i=0; i<items.size(); i++) {
16515            MemItem mi = items.get(i);
16516            if (!isCompact) {
16517                if (dumpSwapPss) {
16518                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16519                            mi.label, stringifyKBSize(mi.swapPss));
16520                } else {
16521                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16522                }
16523            } else if (mi.isProc) {
16524                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16525                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16526                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16527                pw.println(mi.hasActivities ? ",a" : ",e");
16528            } else {
16529                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16530                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16531            }
16532            if (mi.subitems != null) {
16533                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16534                        true, isCompact, dumpSwapPss);
16535            }
16536        }
16537    }
16538
16539    // These are in KB.
16540    static final long[] DUMP_MEM_BUCKETS = new long[] {
16541        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16542        120*1024, 160*1024, 200*1024,
16543        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16544        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16545    };
16546
16547    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16548            boolean stackLike) {
16549        int start = label.lastIndexOf('.');
16550        if (start >= 0) start++;
16551        else start = 0;
16552        int end = label.length();
16553        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16554            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16555                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16556                out.append(bucket);
16557                out.append(stackLike ? "MB." : "MB ");
16558                out.append(label, start, end);
16559                return;
16560            }
16561        }
16562        out.append(memKB/1024);
16563        out.append(stackLike ? "MB." : "MB ");
16564        out.append(label, start, end);
16565    }
16566
16567    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16568            ProcessList.NATIVE_ADJ,
16569            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16570            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16571            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16572            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16573            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16574            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16575    };
16576    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16577            "Native",
16578            "System", "Persistent", "Persistent Service", "Foreground",
16579            "Visible", "Perceptible",
16580            "Heavy Weight", "Backup",
16581            "A Services", "Home",
16582            "Previous", "B Services", "Cached"
16583    };
16584    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16585            "native",
16586            "sys", "pers", "persvc", "fore",
16587            "vis", "percept",
16588            "heavy", "backup",
16589            "servicea", "home",
16590            "prev", "serviceb", "cached"
16591    };
16592
16593    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16594            long realtime, boolean isCheckinRequest, boolean isCompact) {
16595        if (isCompact) {
16596            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16597        }
16598        if (isCheckinRequest || isCompact) {
16599            // short checkin version
16600            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16601        } else {
16602            pw.println("Applications Memory Usage (in Kilobytes):");
16603            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16604        }
16605    }
16606
16607    private static final int KSM_SHARED = 0;
16608    private static final int KSM_SHARING = 1;
16609    private static final int KSM_UNSHARED = 2;
16610    private static final int KSM_VOLATILE = 3;
16611
16612    private final long[] getKsmInfo() {
16613        long[] longOut = new long[4];
16614        final int[] SINGLE_LONG_FORMAT = new int[] {
16615            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16616        };
16617        long[] longTmp = new long[1];
16618        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16619                SINGLE_LONG_FORMAT, null, longTmp, null);
16620        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16621        longTmp[0] = 0;
16622        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16623                SINGLE_LONG_FORMAT, null, longTmp, null);
16624        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16625        longTmp[0] = 0;
16626        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16627                SINGLE_LONG_FORMAT, null, longTmp, null);
16628        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16629        longTmp[0] = 0;
16630        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16631                SINGLE_LONG_FORMAT, null, longTmp, null);
16632        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16633        return longOut;
16634    }
16635
16636    private static String stringifySize(long size, int order) {
16637        Locale locale = Locale.US;
16638        switch (order) {
16639            case 1:
16640                return String.format(locale, "%,13d", size);
16641            case 1024:
16642                return String.format(locale, "%,9dK", size / 1024);
16643            case 1024 * 1024:
16644                return String.format(locale, "%,5dM", size / 1024 / 1024);
16645            case 1024 * 1024 * 1024:
16646                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16647            default:
16648                throw new IllegalArgumentException("Invalid size order");
16649        }
16650    }
16651
16652    private static String stringifyKBSize(long size) {
16653        return stringifySize(size * 1024, 1024);
16654    }
16655
16656    // Update this version number in case you change the 'compact' format
16657    private static final int MEMINFO_COMPACT_VERSION = 1;
16658
16659    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16660            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16661        boolean dumpDetails = false;
16662        boolean dumpFullDetails = false;
16663        boolean dumpDalvik = false;
16664        boolean dumpSummaryOnly = false;
16665        boolean dumpUnreachable = false;
16666        boolean oomOnly = false;
16667        boolean isCompact = false;
16668        boolean localOnly = false;
16669        boolean packages = false;
16670        boolean isCheckinRequest = false;
16671        boolean dumpSwapPss = false;
16672
16673        int opti = 0;
16674        while (opti < args.length) {
16675            String opt = args[opti];
16676            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16677                break;
16678            }
16679            opti++;
16680            if ("-a".equals(opt)) {
16681                dumpDetails = true;
16682                dumpFullDetails = true;
16683                dumpDalvik = true;
16684                dumpSwapPss = true;
16685            } else if ("-d".equals(opt)) {
16686                dumpDalvik = true;
16687            } else if ("-c".equals(opt)) {
16688                isCompact = true;
16689            } else if ("-s".equals(opt)) {
16690                dumpDetails = true;
16691                dumpSummaryOnly = true;
16692            } else if ("-S".equals(opt)) {
16693                dumpSwapPss = true;
16694            } else if ("--unreachable".equals(opt)) {
16695                dumpUnreachable = true;
16696            } else if ("--oom".equals(opt)) {
16697                oomOnly = true;
16698            } else if ("--local".equals(opt)) {
16699                localOnly = true;
16700            } else if ("--package".equals(opt)) {
16701                packages = true;
16702            } else if ("--checkin".equals(opt)) {
16703                isCheckinRequest = true;
16704
16705            } else if ("-h".equals(opt)) {
16706                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16707                pw.println("  -a: include all available information for each process.");
16708                pw.println("  -d: include dalvik details.");
16709                pw.println("  -c: dump in a compact machine-parseable representation.");
16710                pw.println("  -s: dump only summary of application memory usage.");
16711                pw.println("  -S: dump also SwapPss.");
16712                pw.println("  --oom: only show processes organized by oom adj.");
16713                pw.println("  --local: only collect details locally, don't call process.");
16714                pw.println("  --package: interpret process arg as package, dumping all");
16715                pw.println("             processes that have loaded that package.");
16716                pw.println("  --checkin: dump data for a checkin");
16717                pw.println("If [process] is specified it can be the name or ");
16718                pw.println("pid of a specific process to dump.");
16719                return;
16720            } else {
16721                pw.println("Unknown argument: " + opt + "; use -h for help");
16722            }
16723        }
16724
16725        long uptime = SystemClock.uptimeMillis();
16726        long realtime = SystemClock.elapsedRealtime();
16727        final long[] tmpLong = new long[1];
16728
16729        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16730        if (procs == null) {
16731            // No Java processes.  Maybe they want to print a native process.
16732            if (args != null && args.length > opti
16733                    && args[opti].charAt(0) != '-') {
16734                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16735                        = new ArrayList<ProcessCpuTracker.Stats>();
16736                updateCpuStatsNow();
16737                int findPid = -1;
16738                try {
16739                    findPid = Integer.parseInt(args[opti]);
16740                } catch (NumberFormatException e) {
16741                }
16742                synchronized (mProcessCpuTracker) {
16743                    final int N = mProcessCpuTracker.countStats();
16744                    for (int i=0; i<N; i++) {
16745                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16746                        if (st.pid == findPid || (st.baseName != null
16747                                && st.baseName.equals(args[opti]))) {
16748                            nativeProcs.add(st);
16749                        }
16750                    }
16751                }
16752                if (nativeProcs.size() > 0) {
16753                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16754                            isCompact);
16755                    Debug.MemoryInfo mi = null;
16756                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16757                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16758                        final int pid = r.pid;
16759                        if (!isCheckinRequest && dumpDetails) {
16760                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16761                        }
16762                        if (mi == null) {
16763                            mi = new Debug.MemoryInfo();
16764                        }
16765                        if (dumpDetails || (!brief && !oomOnly)) {
16766                            Debug.getMemoryInfo(pid, mi);
16767                        } else {
16768                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16769                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16770                        }
16771                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16772                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16773                        if (isCheckinRequest) {
16774                            pw.println();
16775                        }
16776                    }
16777                    return;
16778                }
16779            }
16780            pw.println("No process found for: " + args[opti]);
16781            return;
16782        }
16783
16784        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16785            dumpDetails = true;
16786        }
16787
16788        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16789
16790        String[] innerArgs = new String[args.length-opti];
16791        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16792
16793        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16794        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16795        long nativePss = 0;
16796        long nativeSwapPss = 0;
16797        long dalvikPss = 0;
16798        long dalvikSwapPss = 0;
16799        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16800                EmptyArray.LONG;
16801        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16802                EmptyArray.LONG;
16803        long otherPss = 0;
16804        long otherSwapPss = 0;
16805        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16806        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16807
16808        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16809        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16810        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16811                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16812
16813        long totalPss = 0;
16814        long totalSwapPss = 0;
16815        long cachedPss = 0;
16816        long cachedSwapPss = 0;
16817        boolean hasSwapPss = false;
16818
16819        Debug.MemoryInfo mi = null;
16820        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16821            final ProcessRecord r = procs.get(i);
16822            final IApplicationThread thread;
16823            final int pid;
16824            final int oomAdj;
16825            final boolean hasActivities;
16826            synchronized (this) {
16827                thread = r.thread;
16828                pid = r.pid;
16829                oomAdj = r.getSetAdjWithServices();
16830                hasActivities = r.activities.size() > 0;
16831            }
16832            if (thread != null) {
16833                if (!isCheckinRequest && dumpDetails) {
16834                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16835                }
16836                if (mi == null) {
16837                    mi = new Debug.MemoryInfo();
16838                }
16839                if (dumpDetails || (!brief && !oomOnly)) {
16840                    Debug.getMemoryInfo(pid, mi);
16841                    hasSwapPss = mi.hasSwappedOutPss;
16842                } else {
16843                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16844                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16845                }
16846                if (dumpDetails) {
16847                    if (localOnly) {
16848                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16849                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16850                        if (isCheckinRequest) {
16851                            pw.println();
16852                        }
16853                    } else {
16854                        pw.flush();
16855                        try {
16856                            TransferPipe tp = new TransferPipe();
16857                            try {
16858                                thread.dumpMemInfo(tp.getWriteFd(),
16859                                        mi, isCheckinRequest, dumpFullDetails,
16860                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16861                                tp.go(fd);
16862                            } finally {
16863                                tp.kill();
16864                            }
16865                        } catch (IOException e) {
16866                            if (!isCheckinRequest) {
16867                                pw.println("Got IoException!");
16868                                pw.flush();
16869                            }
16870                        } catch (RemoteException e) {
16871                            if (!isCheckinRequest) {
16872                                pw.println("Got RemoteException!");
16873                                pw.flush();
16874                            }
16875                        }
16876                    }
16877                }
16878
16879                final long myTotalPss = mi.getTotalPss();
16880                final long myTotalUss = mi.getTotalUss();
16881                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16882
16883                synchronized (this) {
16884                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16885                        // Record this for posterity if the process has been stable.
16886                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16887                    }
16888                }
16889
16890                if (!isCheckinRequest && mi != null) {
16891                    totalPss += myTotalPss;
16892                    totalSwapPss += myTotalSwapPss;
16893                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16894                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16895                            myTotalSwapPss, pid, hasActivities);
16896                    procMems.add(pssItem);
16897                    procMemsMap.put(pid, pssItem);
16898
16899                    nativePss += mi.nativePss;
16900                    nativeSwapPss += mi.nativeSwappedOutPss;
16901                    dalvikPss += mi.dalvikPss;
16902                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16903                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16904                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16905                        dalvikSubitemSwapPss[j] +=
16906                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16907                    }
16908                    otherPss += mi.otherPss;
16909                    otherSwapPss += mi.otherSwappedOutPss;
16910                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16911                        long mem = mi.getOtherPss(j);
16912                        miscPss[j] += mem;
16913                        otherPss -= mem;
16914                        mem = mi.getOtherSwappedOutPss(j);
16915                        miscSwapPss[j] += mem;
16916                        otherSwapPss -= mem;
16917                    }
16918
16919                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16920                        cachedPss += myTotalPss;
16921                        cachedSwapPss += myTotalSwapPss;
16922                    }
16923
16924                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16925                        if (oomIndex == (oomPss.length - 1)
16926                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16927                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16928                            oomPss[oomIndex] += myTotalPss;
16929                            oomSwapPss[oomIndex] += myTotalSwapPss;
16930                            if (oomProcs[oomIndex] == null) {
16931                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16932                            }
16933                            oomProcs[oomIndex].add(pssItem);
16934                            break;
16935                        }
16936                    }
16937                }
16938            }
16939        }
16940
16941        long nativeProcTotalPss = 0;
16942
16943        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16944            // If we are showing aggregations, also look for native processes to
16945            // include so that our aggregations are more accurate.
16946            updateCpuStatsNow();
16947            mi = null;
16948            synchronized (mProcessCpuTracker) {
16949                final int N = mProcessCpuTracker.countStats();
16950                for (int i=0; i<N; i++) {
16951                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16952                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16953                        if (mi == null) {
16954                            mi = new Debug.MemoryInfo();
16955                        }
16956                        if (!brief && !oomOnly) {
16957                            Debug.getMemoryInfo(st.pid, mi);
16958                        } else {
16959                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16960                            mi.nativePrivateDirty = (int)tmpLong[0];
16961                        }
16962
16963                        final long myTotalPss = mi.getTotalPss();
16964                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16965                        totalPss += myTotalPss;
16966                        nativeProcTotalPss += myTotalPss;
16967
16968                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16969                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16970                        procMems.add(pssItem);
16971
16972                        nativePss += mi.nativePss;
16973                        nativeSwapPss += mi.nativeSwappedOutPss;
16974                        dalvikPss += mi.dalvikPss;
16975                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16976                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16977                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16978                            dalvikSubitemSwapPss[j] +=
16979                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16980                        }
16981                        otherPss += mi.otherPss;
16982                        otherSwapPss += mi.otherSwappedOutPss;
16983                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16984                            long mem = mi.getOtherPss(j);
16985                            miscPss[j] += mem;
16986                            otherPss -= mem;
16987                            mem = mi.getOtherSwappedOutPss(j);
16988                            miscSwapPss[j] += mem;
16989                            otherSwapPss -= mem;
16990                        }
16991                        oomPss[0] += myTotalPss;
16992                        oomSwapPss[0] += myTotalSwapPss;
16993                        if (oomProcs[0] == null) {
16994                            oomProcs[0] = new ArrayList<MemItem>();
16995                        }
16996                        oomProcs[0].add(pssItem);
16997                    }
16998                }
16999            }
17000
17001            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17002
17003            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17004            final MemItem dalvikItem =
17005                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17006            if (dalvikSubitemPss.length > 0) {
17007                dalvikItem.subitems = new ArrayList<MemItem>();
17008                for (int j=0; j<dalvikSubitemPss.length; j++) {
17009                    final String name = Debug.MemoryInfo.getOtherLabel(
17010                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
17011                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17012                                    dalvikSubitemSwapPss[j], j));
17013                }
17014            }
17015            catMems.add(dalvikItem);
17016            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17017            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17018                String label = Debug.MemoryInfo.getOtherLabel(j);
17019                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17020            }
17021
17022            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17023            for (int j=0; j<oomPss.length; j++) {
17024                if (oomPss[j] != 0) {
17025                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17026                            : DUMP_MEM_OOM_LABEL[j];
17027                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17028                            DUMP_MEM_OOM_ADJ[j]);
17029                    item.subitems = oomProcs[j];
17030                    oomMems.add(item);
17031                }
17032            }
17033
17034            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17035            if (!brief && !oomOnly && !isCompact) {
17036                pw.println();
17037                pw.println("Total PSS by process:");
17038                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17039                pw.println();
17040            }
17041            if (!isCompact) {
17042                pw.println("Total PSS by OOM adjustment:");
17043            }
17044            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17045            if (!brief && !oomOnly) {
17046                PrintWriter out = categoryPw != null ? categoryPw : pw;
17047                if (!isCompact) {
17048                    out.println();
17049                    out.println("Total PSS by category:");
17050                }
17051                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17052            }
17053            if (!isCompact) {
17054                pw.println();
17055            }
17056            MemInfoReader memInfo = new MemInfoReader();
17057            memInfo.readMemInfo();
17058            if (nativeProcTotalPss > 0) {
17059                synchronized (this) {
17060                    final long cachedKb = memInfo.getCachedSizeKb();
17061                    final long freeKb = memInfo.getFreeSizeKb();
17062                    final long zramKb = memInfo.getZramTotalSizeKb();
17063                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17064                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17065                            kernelKb*1024, nativeProcTotalPss*1024);
17066                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17067                            nativeProcTotalPss);
17068                }
17069            }
17070            if (!brief) {
17071                if (!isCompact) {
17072                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17073                    pw.print(" (status ");
17074                    switch (mLastMemoryLevel) {
17075                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17076                            pw.println("normal)");
17077                            break;
17078                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17079                            pw.println("moderate)");
17080                            break;
17081                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17082                            pw.println("low)");
17083                            break;
17084                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17085                            pw.println("critical)");
17086                            break;
17087                        default:
17088                            pw.print(mLastMemoryLevel);
17089                            pw.println(")");
17090                            break;
17091                    }
17092                    pw.print(" Free RAM: ");
17093                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17094                            + memInfo.getFreeSizeKb()));
17095                    pw.print(" (");
17096                    pw.print(stringifyKBSize(cachedPss));
17097                    pw.print(" cached pss + ");
17098                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17099                    pw.print(" cached kernel + ");
17100                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17101                    pw.println(" free)");
17102                } else {
17103                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17104                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17105                            + memInfo.getFreeSizeKb()); pw.print(",");
17106                    pw.println(totalPss - cachedPss);
17107                }
17108            }
17109            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17110                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17111                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17112            if (!isCompact) {
17113                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17114                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17115                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17116                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17117                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17118            } else {
17119                pw.print("lostram,"); pw.println(lostRAM);
17120            }
17121            if (!brief) {
17122                if (memInfo.getZramTotalSizeKb() != 0) {
17123                    if (!isCompact) {
17124                        pw.print("     ZRAM: ");
17125                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17126                                pw.print(" physical used for ");
17127                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17128                                        - memInfo.getSwapFreeSizeKb()));
17129                                pw.print(" in swap (");
17130                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17131                                pw.println(" total swap)");
17132                    } else {
17133                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17134                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17135                                pw.println(memInfo.getSwapFreeSizeKb());
17136                    }
17137                }
17138                final long[] ksm = getKsmInfo();
17139                if (!isCompact) {
17140                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17141                            || ksm[KSM_VOLATILE] != 0) {
17142                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17143                                pw.print(" saved from shared ");
17144                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17145                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17146                                pw.print(" unshared; ");
17147                                pw.print(stringifyKBSize(
17148                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17149                    }
17150                    pw.print("   Tuning: ");
17151                    pw.print(ActivityManager.staticGetMemoryClass());
17152                    pw.print(" (large ");
17153                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17154                    pw.print("), oom ");
17155                    pw.print(stringifySize(
17156                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17157                    pw.print(", restore limit ");
17158                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17159                    if (ActivityManager.isLowRamDeviceStatic()) {
17160                        pw.print(" (low-ram)");
17161                    }
17162                    if (ActivityManager.isHighEndGfx()) {
17163                        pw.print(" (high-end-gfx)");
17164                    }
17165                    pw.println();
17166                } else {
17167                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17168                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17169                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17170                    pw.print("tuning,");
17171                    pw.print(ActivityManager.staticGetMemoryClass());
17172                    pw.print(',');
17173                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17174                    pw.print(',');
17175                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17176                    if (ActivityManager.isLowRamDeviceStatic()) {
17177                        pw.print(",low-ram");
17178                    }
17179                    if (ActivityManager.isHighEndGfx()) {
17180                        pw.print(",high-end-gfx");
17181                    }
17182                    pw.println();
17183                }
17184            }
17185        }
17186    }
17187
17188    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17189            long memtrack, String name) {
17190        sb.append("  ");
17191        sb.append(ProcessList.makeOomAdjString(oomAdj));
17192        sb.append(' ');
17193        sb.append(ProcessList.makeProcStateString(procState));
17194        sb.append(' ');
17195        ProcessList.appendRamKb(sb, pss);
17196        sb.append(": ");
17197        sb.append(name);
17198        if (memtrack > 0) {
17199            sb.append(" (");
17200            sb.append(stringifyKBSize(memtrack));
17201            sb.append(" memtrack)");
17202        }
17203    }
17204
17205    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17206        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17207        sb.append(" (pid ");
17208        sb.append(mi.pid);
17209        sb.append(") ");
17210        sb.append(mi.adjType);
17211        sb.append('\n');
17212        if (mi.adjReason != null) {
17213            sb.append("                      ");
17214            sb.append(mi.adjReason);
17215            sb.append('\n');
17216        }
17217    }
17218
17219    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17220        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17221        for (int i=0, N=memInfos.size(); i<N; i++) {
17222            ProcessMemInfo mi = memInfos.get(i);
17223            infoMap.put(mi.pid, mi);
17224        }
17225        updateCpuStatsNow();
17226        long[] memtrackTmp = new long[1];
17227        final List<ProcessCpuTracker.Stats> stats;
17228        // Get a list of Stats that have vsize > 0
17229        synchronized (mProcessCpuTracker) {
17230            stats = mProcessCpuTracker.getStats((st) -> {
17231                return st.vsize > 0;
17232            });
17233        }
17234        final int statsCount = stats.size();
17235        for (int i = 0; i < statsCount; i++) {
17236            ProcessCpuTracker.Stats st = stats.get(i);
17237            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17238            if (pss > 0) {
17239                if (infoMap.indexOfKey(st.pid) < 0) {
17240                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17241                            ProcessList.NATIVE_ADJ, -1, "native", null);
17242                    mi.pss = pss;
17243                    mi.memtrack = memtrackTmp[0];
17244                    memInfos.add(mi);
17245                }
17246            }
17247        }
17248
17249        long totalPss = 0;
17250        long totalMemtrack = 0;
17251        for (int i=0, N=memInfos.size(); i<N; i++) {
17252            ProcessMemInfo mi = memInfos.get(i);
17253            if (mi.pss == 0) {
17254                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17255                mi.memtrack = memtrackTmp[0];
17256            }
17257            totalPss += mi.pss;
17258            totalMemtrack += mi.memtrack;
17259        }
17260        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17261            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17262                if (lhs.oomAdj != rhs.oomAdj) {
17263                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17264                }
17265                if (lhs.pss != rhs.pss) {
17266                    return lhs.pss < rhs.pss ? 1 : -1;
17267                }
17268                return 0;
17269            }
17270        });
17271
17272        StringBuilder tag = new StringBuilder(128);
17273        StringBuilder stack = new StringBuilder(128);
17274        tag.append("Low on memory -- ");
17275        appendMemBucket(tag, totalPss, "total", false);
17276        appendMemBucket(stack, totalPss, "total", true);
17277
17278        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17279        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17280        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17281
17282        boolean firstLine = true;
17283        int lastOomAdj = Integer.MIN_VALUE;
17284        long extraNativeRam = 0;
17285        long extraNativeMemtrack = 0;
17286        long cachedPss = 0;
17287        for (int i=0, N=memInfos.size(); i<N; i++) {
17288            ProcessMemInfo mi = memInfos.get(i);
17289
17290            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17291                cachedPss += mi.pss;
17292            }
17293
17294            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17295                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17296                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17297                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17298                if (lastOomAdj != mi.oomAdj) {
17299                    lastOomAdj = mi.oomAdj;
17300                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17301                        tag.append(" / ");
17302                    }
17303                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17304                        if (firstLine) {
17305                            stack.append(":");
17306                            firstLine = false;
17307                        }
17308                        stack.append("\n\t at ");
17309                    } else {
17310                        stack.append("$");
17311                    }
17312                } else {
17313                    tag.append(" ");
17314                    stack.append("$");
17315                }
17316                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17317                    appendMemBucket(tag, mi.pss, mi.name, false);
17318                }
17319                appendMemBucket(stack, mi.pss, mi.name, true);
17320                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17321                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17322                    stack.append("(");
17323                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17324                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17325                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17326                            stack.append(":");
17327                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17328                        }
17329                    }
17330                    stack.append(")");
17331                }
17332            }
17333
17334            appendMemInfo(fullNativeBuilder, mi);
17335            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17336                // The short form only has native processes that are >= 512K.
17337                if (mi.pss >= 512) {
17338                    appendMemInfo(shortNativeBuilder, mi);
17339                } else {
17340                    extraNativeRam += mi.pss;
17341                    extraNativeMemtrack += mi.memtrack;
17342                }
17343            } else {
17344                // Short form has all other details, but if we have collected RAM
17345                // from smaller native processes let's dump a summary of that.
17346                if (extraNativeRam > 0) {
17347                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17348                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17349                    shortNativeBuilder.append('\n');
17350                    extraNativeRam = 0;
17351                }
17352                appendMemInfo(fullJavaBuilder, mi);
17353            }
17354        }
17355
17356        fullJavaBuilder.append("           ");
17357        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17358        fullJavaBuilder.append(": TOTAL");
17359        if (totalMemtrack > 0) {
17360            fullJavaBuilder.append(" (");
17361            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17362            fullJavaBuilder.append(" memtrack)");
17363        } else {
17364        }
17365        fullJavaBuilder.append("\n");
17366
17367        MemInfoReader memInfo = new MemInfoReader();
17368        memInfo.readMemInfo();
17369        final long[] infos = memInfo.getRawInfo();
17370
17371        StringBuilder memInfoBuilder = new StringBuilder(1024);
17372        Debug.getMemInfo(infos);
17373        memInfoBuilder.append("  MemInfo: ");
17374        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17375        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17376        memInfoBuilder.append(stringifyKBSize(
17377                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17378        memInfoBuilder.append(stringifyKBSize(
17379                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17380        memInfoBuilder.append(stringifyKBSize(
17381                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17382        memInfoBuilder.append("           ");
17383        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17384        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17385        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17386        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17387        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17388            memInfoBuilder.append("  ZRAM: ");
17389            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17390            memInfoBuilder.append(" RAM, ");
17391            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17392            memInfoBuilder.append(" swap total, ");
17393            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17394            memInfoBuilder.append(" swap free\n");
17395        }
17396        final long[] ksm = getKsmInfo();
17397        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17398                || ksm[KSM_VOLATILE] != 0) {
17399            memInfoBuilder.append("  KSM: ");
17400            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17401            memInfoBuilder.append(" saved from shared ");
17402            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17403            memInfoBuilder.append("\n       ");
17404            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17405            memInfoBuilder.append(" unshared; ");
17406            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17407            memInfoBuilder.append(" volatile\n");
17408        }
17409        memInfoBuilder.append("  Free RAM: ");
17410        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17411                + memInfo.getFreeSizeKb()));
17412        memInfoBuilder.append("\n");
17413        memInfoBuilder.append("  Used RAM: ");
17414        memInfoBuilder.append(stringifyKBSize(
17415                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17416        memInfoBuilder.append("\n");
17417        memInfoBuilder.append("  Lost RAM: ");
17418        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17419                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17420                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17421        memInfoBuilder.append("\n");
17422        Slog.i(TAG, "Low on memory:");
17423        Slog.i(TAG, shortNativeBuilder.toString());
17424        Slog.i(TAG, fullJavaBuilder.toString());
17425        Slog.i(TAG, memInfoBuilder.toString());
17426
17427        StringBuilder dropBuilder = new StringBuilder(1024);
17428        /*
17429        StringWriter oomSw = new StringWriter();
17430        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17431        StringWriter catSw = new StringWriter();
17432        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17433        String[] emptyArgs = new String[] { };
17434        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17435        oomPw.flush();
17436        String oomString = oomSw.toString();
17437        */
17438        dropBuilder.append("Low on memory:");
17439        dropBuilder.append(stack);
17440        dropBuilder.append('\n');
17441        dropBuilder.append(fullNativeBuilder);
17442        dropBuilder.append(fullJavaBuilder);
17443        dropBuilder.append('\n');
17444        dropBuilder.append(memInfoBuilder);
17445        dropBuilder.append('\n');
17446        /*
17447        dropBuilder.append(oomString);
17448        dropBuilder.append('\n');
17449        */
17450        StringWriter catSw = new StringWriter();
17451        synchronized (ActivityManagerService.this) {
17452            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17453            String[] emptyArgs = new String[] { };
17454            catPw.println();
17455            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17456            catPw.println();
17457            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17458                    false, null).dumpLocked();
17459            catPw.println();
17460            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17461            catPw.flush();
17462        }
17463        dropBuilder.append(catSw.toString());
17464        addErrorToDropBox("lowmem", null, "system_server", null,
17465                null, tag.toString(), dropBuilder.toString(), null, null);
17466        //Slog.i(TAG, "Sent to dropbox:");
17467        //Slog.i(TAG, dropBuilder.toString());
17468        synchronized (ActivityManagerService.this) {
17469            long now = SystemClock.uptimeMillis();
17470            if (mLastMemUsageReportTime < now) {
17471                mLastMemUsageReportTime = now;
17472            }
17473        }
17474    }
17475
17476    /**
17477     * Searches array of arguments for the specified string
17478     * @param args array of argument strings
17479     * @param value value to search for
17480     * @return true if the value is contained in the array
17481     */
17482    private static boolean scanArgs(String[] args, String value) {
17483        if (args != null) {
17484            for (String arg : args) {
17485                if (value.equals(arg)) {
17486                    return true;
17487                }
17488            }
17489        }
17490        return false;
17491    }
17492
17493    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17494            ContentProviderRecord cpr, boolean always) {
17495        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17496
17497        if (!inLaunching || always) {
17498            synchronized (cpr) {
17499                cpr.launchingApp = null;
17500                cpr.notifyAll();
17501            }
17502            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17503            String names[] = cpr.info.authority.split(";");
17504            for (int j = 0; j < names.length; j++) {
17505                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17506            }
17507        }
17508
17509        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17510            ContentProviderConnection conn = cpr.connections.get(i);
17511            if (conn.waiting) {
17512                // If this connection is waiting for the provider, then we don't
17513                // need to mess with its process unless we are always removing
17514                // or for some reason the provider is not currently launching.
17515                if (inLaunching && !always) {
17516                    continue;
17517                }
17518            }
17519            ProcessRecord capp = conn.client;
17520            conn.dead = true;
17521            if (conn.stableCount > 0) {
17522                if (!capp.persistent && capp.thread != null
17523                        && capp.pid != 0
17524                        && capp.pid != MY_PID) {
17525                    capp.kill("depends on provider "
17526                            + cpr.name.flattenToShortString()
17527                            + " in dying proc " + (proc != null ? proc.processName : "??")
17528                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17529                }
17530            } else if (capp.thread != null && conn.provider.provider != null) {
17531                try {
17532                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17533                } catch (RemoteException e) {
17534                }
17535                // In the protocol here, we don't expect the client to correctly
17536                // clean up this connection, we'll just remove it.
17537                cpr.connections.remove(i);
17538                if (conn.client.conProviders.remove(conn)) {
17539                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17540                }
17541            }
17542        }
17543
17544        if (inLaunching && always) {
17545            mLaunchingProviders.remove(cpr);
17546        }
17547        return inLaunching;
17548    }
17549
17550    /**
17551     * Main code for cleaning up a process when it has gone away.  This is
17552     * called both as a result of the process dying, or directly when stopping
17553     * a process when running in single process mode.
17554     *
17555     * @return Returns true if the given process has been restarted, so the
17556     * app that was passed in must remain on the process lists.
17557     */
17558    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17559            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17560        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
17561        if (index >= 0) {
17562            removeLruProcessLocked(app);
17563            ProcessList.remove(app.pid);
17564        }
17565
17566        mProcessesToGc.remove(app);
17567        mPendingPssProcesses.remove(app);
17568
17569        // Dismiss any open dialogs.
17570        if (app.crashDialog != null && !app.forceCrashReport) {
17571            app.crashDialog.dismiss();
17572            app.crashDialog = null;
17573        }
17574        if (app.anrDialog != null) {
17575            app.anrDialog.dismiss();
17576            app.anrDialog = null;
17577        }
17578        if (app.waitDialog != null) {
17579            app.waitDialog.dismiss();
17580            app.waitDialog = null;
17581        }
17582
17583        app.crashing = false;
17584        app.notResponding = false;
17585
17586        app.resetPackageList(mProcessStats);
17587        app.unlinkDeathRecipient();
17588        app.makeInactive(mProcessStats);
17589        app.waitingToKill = null;
17590        app.forcingToForeground = null;
17591        updateProcessForegroundLocked(app, false, false);
17592        app.foregroundActivities = false;
17593        app.hasShownUi = false;
17594        app.treatLikeActivity = false;
17595        app.hasAboveClient = false;
17596        app.hasClientActivities = false;
17597
17598        mServices.killServicesLocked(app, allowRestart);
17599
17600        boolean restart = false;
17601
17602        // Remove published content providers.
17603        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17604            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17605            final boolean always = app.bad || !allowRestart;
17606            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17607            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17608                // We left the provider in the launching list, need to
17609                // restart it.
17610                restart = true;
17611            }
17612
17613            cpr.provider = null;
17614            cpr.proc = null;
17615        }
17616        app.pubProviders.clear();
17617
17618        // Take care of any launching providers waiting for this process.
17619        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17620            restart = true;
17621        }
17622
17623        // Unregister from connected content providers.
17624        if (!app.conProviders.isEmpty()) {
17625            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17626                ContentProviderConnection conn = app.conProviders.get(i);
17627                conn.provider.connections.remove(conn);
17628                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17629                        conn.provider.name);
17630            }
17631            app.conProviders.clear();
17632        }
17633
17634        // At this point there may be remaining entries in mLaunchingProviders
17635        // where we were the only one waiting, so they are no longer of use.
17636        // Look for these and clean up if found.
17637        // XXX Commented out for now.  Trying to figure out a way to reproduce
17638        // the actual situation to identify what is actually going on.
17639        if (false) {
17640            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17641                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17642                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17643                    synchronized (cpr) {
17644                        cpr.launchingApp = null;
17645                        cpr.notifyAll();
17646                    }
17647                }
17648            }
17649        }
17650
17651        skipCurrentReceiverLocked(app);
17652
17653        // Unregister any receivers.
17654        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17655            removeReceiverLocked(app.receivers.valueAt(i));
17656        }
17657        app.receivers.clear();
17658
17659        // If the app is undergoing backup, tell the backup manager about it
17660        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17661            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17662                    + mBackupTarget.appInfo + " died during backup");
17663            mHandler.post(new Runnable() {
17664                @Override
17665                public void run(){
17666                    try {
17667                        IBackupManager bm = IBackupManager.Stub.asInterface(
17668                                ServiceManager.getService(Context.BACKUP_SERVICE));
17669                        bm.agentDisconnected(app.info.packageName);
17670                    } catch (RemoteException e) {
17671                        // can't happen; backup manager is local
17672                    }
17673                }
17674            });
17675        }
17676
17677        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17678            ProcessChangeItem item = mPendingProcessChanges.get(i);
17679            if (item.pid == app.pid) {
17680                mPendingProcessChanges.remove(i);
17681                mAvailProcessChanges.add(item);
17682            }
17683        }
17684        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17685                null).sendToTarget();
17686
17687        // If the caller is restarting this app, then leave it in its
17688        // current lists and let the caller take care of it.
17689        if (restarting) {
17690            return false;
17691        }
17692
17693        if (!app.persistent || app.isolated) {
17694            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17695                    "Removing non-persistent process during cleanup: " + app);
17696            if (!replacingPid) {
17697                removeProcessNameLocked(app.processName, app.uid, app);
17698            }
17699            if (mHeavyWeightProcess == app) {
17700                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17701                        mHeavyWeightProcess.userId, 0));
17702                mHeavyWeightProcess = null;
17703            }
17704        } else if (!app.removed) {
17705            // This app is persistent, so we need to keep its record around.
17706            // If it is not already on the pending app list, add it there
17707            // and start a new process for it.
17708            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17709                mPersistentStartingProcesses.add(app);
17710                restart = true;
17711            }
17712        }
17713        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17714                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17715        mProcessesOnHold.remove(app);
17716
17717        if (app == mHomeProcess) {
17718            mHomeProcess = null;
17719        }
17720        if (app == mPreviousProcess) {
17721            mPreviousProcess = null;
17722        }
17723
17724        if (restart && !app.isolated) {
17725            // We have components that still need to be running in the
17726            // process, so re-launch it.
17727            if (index < 0) {
17728                ProcessList.remove(app.pid);
17729            }
17730            addProcessNameLocked(app);
17731            startProcessLocked(app, "restart", app.processName);
17732            return true;
17733        } else if (app.pid > 0 && app.pid != MY_PID) {
17734            // Goodbye!
17735            boolean removed;
17736            synchronized (mPidsSelfLocked) {
17737                mPidsSelfLocked.remove(app.pid);
17738                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17739            }
17740            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17741            if (app.isolated) {
17742                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17743            }
17744            app.setPid(0);
17745        }
17746        return false;
17747    }
17748
17749    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17750        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17751            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17752            if (cpr.launchingApp == app) {
17753                return true;
17754            }
17755        }
17756        return false;
17757    }
17758
17759    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17760        // Look through the content providers we are waiting to have launched,
17761        // and if any run in this process then either schedule a restart of
17762        // the process or kill the client waiting for it if this process has
17763        // gone bad.
17764        boolean restart = false;
17765        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17766            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17767            if (cpr.launchingApp == app) {
17768                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17769                    restart = true;
17770                } else {
17771                    removeDyingProviderLocked(app, cpr, true);
17772                }
17773            }
17774        }
17775        return restart;
17776    }
17777
17778    // =========================================================
17779    // SERVICES
17780    // =========================================================
17781
17782    @Override
17783    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17784            int flags) {
17785        enforceNotIsolatedCaller("getServices");
17786
17787        final int callingUid = Binder.getCallingUid();
17788        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
17789            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
17790        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
17791            callingUid);
17792        synchronized (this) {
17793            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
17794                allowed, canInteractAcrossUsers);
17795        }
17796    }
17797
17798    @Override
17799    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17800        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17801        synchronized (this) {
17802            return mServices.getRunningServiceControlPanelLocked(name);
17803        }
17804    }
17805
17806    @Override
17807    public ComponentName startService(IApplicationThread caller, Intent service,
17808            String resolvedType, int id, Notification notification,
17809            String callingPackage, int userId)
17810            throws TransactionTooLargeException {
17811        enforceNotIsolatedCaller("startService");
17812        // Refuse possible leaked file descriptors
17813        if (service != null && service.hasFileDescriptors() == true) {
17814            throw new IllegalArgumentException("File descriptors passed in Intent");
17815        }
17816
17817        if (callingPackage == null) {
17818            throw new IllegalArgumentException("callingPackage cannot be null");
17819        }
17820
17821        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17822                "startService: " + service + " type=" + resolvedType);
17823        synchronized(this) {
17824            final int callingPid = Binder.getCallingPid();
17825            final int callingUid = Binder.getCallingUid();
17826            final long origId = Binder.clearCallingIdentity();
17827            ComponentName res = mServices.startServiceLocked(caller, service,
17828                    resolvedType, id, notification,
17829                    callingPid, callingUid, callingPackage, userId);
17830            Binder.restoreCallingIdentity(origId);
17831            return res;
17832        }
17833    }
17834
17835    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17836            String callingPackage, int userId)
17837            throws TransactionTooLargeException {
17838        synchronized(this) {
17839            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17840                    "startServiceInPackage: " + service + " type=" + resolvedType);
17841            final long origId = Binder.clearCallingIdentity();
17842            ComponentName res = mServices.startServiceLocked(null, service,
17843                    resolvedType, 0, null, -1, uid, callingPackage, userId);
17844            Binder.restoreCallingIdentity(origId);
17845            return res;
17846        }
17847    }
17848
17849    @Override
17850    public int stopService(IApplicationThread caller, Intent service,
17851            String resolvedType, int userId) {
17852        enforceNotIsolatedCaller("stopService");
17853        // Refuse possible leaked file descriptors
17854        if (service != null && service.hasFileDescriptors() == true) {
17855            throw new IllegalArgumentException("File descriptors passed in Intent");
17856        }
17857
17858        synchronized(this) {
17859            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17860        }
17861    }
17862
17863    @Override
17864    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17865        enforceNotIsolatedCaller("peekService");
17866        // Refuse possible leaked file descriptors
17867        if (service != null && service.hasFileDescriptors() == true) {
17868            throw new IllegalArgumentException("File descriptors passed in Intent");
17869        }
17870
17871        if (callingPackage == null) {
17872            throw new IllegalArgumentException("callingPackage cannot be null");
17873        }
17874
17875        synchronized(this) {
17876            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17877        }
17878    }
17879
17880    @Override
17881    public boolean stopServiceToken(ComponentName className, IBinder token,
17882            int startId) {
17883        synchronized(this) {
17884            return mServices.stopServiceTokenLocked(className, token, startId);
17885        }
17886    }
17887
17888    @Override
17889    public void setServiceForeground(ComponentName className, IBinder token,
17890            int id, Notification notification, int flags) {
17891        synchronized(this) {
17892            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17893        }
17894    }
17895
17896    @Override
17897    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17898            boolean requireFull, String name, String callerPackage) {
17899        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17900                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17901    }
17902
17903    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17904            String className, int flags) {
17905        boolean result = false;
17906        // For apps that don't have pre-defined UIDs, check for permission
17907        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17908            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17909                if (ActivityManager.checkUidPermission(
17910                        INTERACT_ACROSS_USERS,
17911                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17912                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17913                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17914                            + " requests FLAG_SINGLE_USER, but app does not hold "
17915                            + INTERACT_ACROSS_USERS;
17916                    Slog.w(TAG, msg);
17917                    throw new SecurityException(msg);
17918                }
17919                // Permission passed
17920                result = true;
17921            }
17922        } else if ("system".equals(componentProcessName)) {
17923            result = true;
17924        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17925            // Phone app and persistent apps are allowed to export singleuser providers.
17926            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17927                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17928        }
17929        if (DEBUG_MU) Slog.v(TAG_MU,
17930                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17931                + Integer.toHexString(flags) + ") = " + result);
17932        return result;
17933    }
17934
17935    /**
17936     * Checks to see if the caller is in the same app as the singleton
17937     * component, or the component is in a special app. It allows special apps
17938     * to export singleton components but prevents exporting singleton
17939     * components for regular apps.
17940     */
17941    boolean isValidSingletonCall(int callingUid, int componentUid) {
17942        int componentAppId = UserHandle.getAppId(componentUid);
17943        return UserHandle.isSameApp(callingUid, componentUid)
17944                || componentAppId == Process.SYSTEM_UID
17945                || componentAppId == Process.PHONE_UID
17946                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17947                        == PackageManager.PERMISSION_GRANTED;
17948    }
17949
17950    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17951            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17952            int userId) throws TransactionTooLargeException {
17953        enforceNotIsolatedCaller("bindService");
17954
17955        // Refuse possible leaked file descriptors
17956        if (service != null && service.hasFileDescriptors() == true) {
17957            throw new IllegalArgumentException("File descriptors passed in Intent");
17958        }
17959
17960        if (callingPackage == null) {
17961            throw new IllegalArgumentException("callingPackage cannot be null");
17962        }
17963
17964        synchronized(this) {
17965            return mServices.bindServiceLocked(caller, token, service,
17966                    resolvedType, connection, flags, callingPackage, userId);
17967        }
17968    }
17969
17970    public boolean unbindService(IServiceConnection connection) {
17971        synchronized (this) {
17972            return mServices.unbindServiceLocked(connection);
17973        }
17974    }
17975
17976    public void publishService(IBinder token, Intent intent, IBinder service) {
17977        // Refuse possible leaked file descriptors
17978        if (intent != null && intent.hasFileDescriptors() == true) {
17979            throw new IllegalArgumentException("File descriptors passed in Intent");
17980        }
17981
17982        synchronized(this) {
17983            if (!(token instanceof ServiceRecord)) {
17984                throw new IllegalArgumentException("Invalid service token");
17985            }
17986            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17987        }
17988    }
17989
17990    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17991        // Refuse possible leaked file descriptors
17992        if (intent != null && intent.hasFileDescriptors() == true) {
17993            throw new IllegalArgumentException("File descriptors passed in Intent");
17994        }
17995
17996        synchronized(this) {
17997            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17998        }
17999    }
18000
18001    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18002        synchronized(this) {
18003            if (!(token instanceof ServiceRecord)) {
18004                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18005                throw new IllegalArgumentException("Invalid service token");
18006            }
18007            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18008        }
18009    }
18010
18011    // =========================================================
18012    // BACKUP AND RESTORE
18013    // =========================================================
18014
18015    // Cause the target app to be launched if necessary and its backup agent
18016    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18017    // activity manager to announce its creation.
18018    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18019        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18020        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18021
18022        IPackageManager pm = AppGlobals.getPackageManager();
18023        ApplicationInfo app = null;
18024        try {
18025            app = pm.getApplicationInfo(packageName, 0, userId);
18026        } catch (RemoteException e) {
18027            // can't happen; package manager is process-local
18028        }
18029        if (app == null) {
18030            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18031            return false;
18032        }
18033
18034        synchronized(this) {
18035            // !!! TODO: currently no check here that we're already bound
18036            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18037            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18038            synchronized (stats) {
18039                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18040            }
18041
18042            // Backup agent is now in use, its package can't be stopped.
18043            try {
18044                AppGlobals.getPackageManager().setPackageStoppedState(
18045                        app.packageName, false, UserHandle.getUserId(app.uid));
18046            } catch (RemoteException e) {
18047            } catch (IllegalArgumentException e) {
18048                Slog.w(TAG, "Failed trying to unstop package "
18049                        + app.packageName + ": " + e);
18050            }
18051
18052            BackupRecord r = new BackupRecord(ss, app, backupMode);
18053            ComponentName hostingName =
18054                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18055                            ? new ComponentName(app.packageName, app.backupAgentName)
18056                            : new ComponentName("android", "FullBackupAgent");
18057            // startProcessLocked() returns existing proc's record if it's already running
18058            ProcessRecord proc = startProcessLocked(app.processName, app,
18059                    false, 0, "backup", hostingName, false, false, false);
18060            if (proc == null) {
18061                Slog.e(TAG, "Unable to start backup agent process " + r);
18062                return false;
18063            }
18064
18065            // If the app is a regular app (uid >= 10000) and not the system server or phone
18066            // process, etc, then mark it as being in full backup so that certain calls to the
18067            // process can be blocked. This is not reset to false anywhere because we kill the
18068            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18069            if (UserHandle.isApp(app.uid) &&
18070                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18071                proc.inFullBackup = true;
18072            }
18073            r.app = proc;
18074            mBackupTarget = r;
18075            mBackupAppName = app.packageName;
18076
18077            // Try not to kill the process during backup
18078            updateOomAdjLocked(proc);
18079
18080            // If the process is already attached, schedule the creation of the backup agent now.
18081            // If it is not yet live, this will be done when it attaches to the framework.
18082            if (proc.thread != null) {
18083                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18084                try {
18085                    proc.thread.scheduleCreateBackupAgent(app,
18086                            compatibilityInfoForPackageLocked(app), backupMode);
18087                } catch (RemoteException e) {
18088                    // Will time out on the backup manager side
18089                }
18090            } else {
18091                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18092            }
18093            // Invariants: at this point, the target app process exists and the application
18094            // is either already running or in the process of coming up.  mBackupTarget and
18095            // mBackupAppName describe the app, so that when it binds back to the AM we
18096            // know that it's scheduled for a backup-agent operation.
18097        }
18098
18099        return true;
18100    }
18101
18102    @Override
18103    public void clearPendingBackup() {
18104        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18105        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18106
18107        synchronized (this) {
18108            mBackupTarget = null;
18109            mBackupAppName = null;
18110        }
18111    }
18112
18113    // A backup agent has just come up
18114    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18115        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18116                + " = " + agent);
18117
18118        synchronized(this) {
18119            if (!agentPackageName.equals(mBackupAppName)) {
18120                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18121                return;
18122            }
18123        }
18124
18125        long oldIdent = Binder.clearCallingIdentity();
18126        try {
18127            IBackupManager bm = IBackupManager.Stub.asInterface(
18128                    ServiceManager.getService(Context.BACKUP_SERVICE));
18129            bm.agentConnected(agentPackageName, agent);
18130        } catch (RemoteException e) {
18131            // can't happen; the backup manager service is local
18132        } catch (Exception e) {
18133            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18134            e.printStackTrace();
18135        } finally {
18136            Binder.restoreCallingIdentity(oldIdent);
18137        }
18138    }
18139
18140    // done with this agent
18141    public void unbindBackupAgent(ApplicationInfo appInfo) {
18142        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18143        if (appInfo == null) {
18144            Slog.w(TAG, "unbind backup agent for null app");
18145            return;
18146        }
18147
18148        synchronized(this) {
18149            try {
18150                if (mBackupAppName == null) {
18151                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18152                    return;
18153                }
18154
18155                if (!mBackupAppName.equals(appInfo.packageName)) {
18156                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18157                    return;
18158                }
18159
18160                // Not backing this app up any more; reset its OOM adjustment
18161                final ProcessRecord proc = mBackupTarget.app;
18162                updateOomAdjLocked(proc);
18163                proc.inFullBackup = false;
18164
18165                // If the app crashed during backup, 'thread' will be null here
18166                if (proc.thread != null) {
18167                    try {
18168                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18169                                compatibilityInfoForPackageLocked(appInfo));
18170                    } catch (Exception e) {
18171                        Slog.e(TAG, "Exception when unbinding backup agent:");
18172                        e.printStackTrace();
18173                    }
18174                }
18175            } finally {
18176                mBackupTarget = null;
18177                mBackupAppName = null;
18178            }
18179        }
18180    }
18181    // =========================================================
18182    // BROADCASTS
18183    // =========================================================
18184
18185    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18186        if (UserHandle.getAppId(uid) < Process.FIRST_APPLICATION_UID) {
18187            return false;
18188        }
18189        // Easy case -- we have the app's ProcessRecord.
18190        if (record != null) {
18191            return record.info.isInstantApp();
18192        }
18193        // Otherwise check with PackageManager.
18194        mAppOpsService.checkPackage(uid, callerPackage);
18195        try {
18196            IPackageManager pm = AppGlobals.getPackageManager();
18197            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18198        } catch (RemoteException e) {
18199            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18200            return true;
18201        }
18202    }
18203
18204    boolean isPendingBroadcastProcessLocked(int pid) {
18205        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18206                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18207    }
18208
18209    void skipPendingBroadcastLocked(int pid) {
18210            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18211            for (BroadcastQueue queue : mBroadcastQueues) {
18212                queue.skipPendingBroadcastLocked(pid);
18213            }
18214    }
18215
18216    // The app just attached; send any pending broadcasts that it should receive
18217    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18218        boolean didSomething = false;
18219        for (BroadcastQueue queue : mBroadcastQueues) {
18220            didSomething |= queue.sendPendingBroadcastsLocked(app);
18221        }
18222        return didSomething;
18223    }
18224
18225    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18226            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18227            boolean visibleToInstantApps) {
18228        enforceNotIsolatedCaller("registerReceiver");
18229        ArrayList<Intent> stickyIntents = null;
18230        ProcessRecord callerApp = null;
18231        int callingUid;
18232        int callingPid;
18233        boolean instantApp;
18234        synchronized(this) {
18235            if (caller != null) {
18236                callerApp = getRecordForAppLocked(caller);
18237                if (callerApp == null) {
18238                    throw new SecurityException(
18239                            "Unable to find app for caller " + caller
18240                            + " (pid=" + Binder.getCallingPid()
18241                            + ") when registering receiver " + receiver);
18242                }
18243                if (callerApp.info.uid != Process.SYSTEM_UID &&
18244                        !callerApp.pkgList.containsKey(callerPackage) &&
18245                        !"android".equals(callerPackage)) {
18246                    throw new SecurityException("Given caller package " + callerPackage
18247                            + " is not running in process " + callerApp);
18248                }
18249                callingUid = callerApp.info.uid;
18250                callingPid = callerApp.pid;
18251            } else {
18252                callerPackage = null;
18253                callingUid = Binder.getCallingUid();
18254                callingPid = Binder.getCallingPid();
18255            }
18256
18257            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18258            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18259                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18260
18261            Iterator<String> actions = filter.actionsIterator();
18262            if (actions == null) {
18263                ArrayList<String> noAction = new ArrayList<String>(1);
18264                noAction.add(null);
18265                actions = noAction.iterator();
18266            }
18267
18268            // Collect stickies of users
18269            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18270            while (actions.hasNext()) {
18271                String action = actions.next();
18272                for (int id : userIds) {
18273                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18274                    if (stickies != null) {
18275                        ArrayList<Intent> intents = stickies.get(action);
18276                        if (intents != null) {
18277                            if (stickyIntents == null) {
18278                                stickyIntents = new ArrayList<Intent>();
18279                            }
18280                            stickyIntents.addAll(intents);
18281                        }
18282                    }
18283                }
18284            }
18285        }
18286
18287        ArrayList<Intent> allSticky = null;
18288        if (stickyIntents != null) {
18289            final ContentResolver resolver = mContext.getContentResolver();
18290            // Look for any matching sticky broadcasts...
18291            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18292                Intent intent = stickyIntents.get(i);
18293                // Don't provided intents that aren't available to instant apps.
18294                if (instantApp &&
18295                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18296                    continue;
18297                }
18298                // If intent has scheme "content", it will need to acccess
18299                // provider that needs to lock mProviderMap in ActivityThread
18300                // and also it may need to wait application response, so we
18301                // cannot lock ActivityManagerService here.
18302                if (filter.match(resolver, intent, true, TAG) >= 0) {
18303                    if (allSticky == null) {
18304                        allSticky = new ArrayList<Intent>();
18305                    }
18306                    allSticky.add(intent);
18307                }
18308            }
18309        }
18310
18311        // The first sticky in the list is returned directly back to the client.
18312        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18313        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18314        if (receiver == null) {
18315            return sticky;
18316        }
18317
18318        synchronized (this) {
18319            if (callerApp != null && (callerApp.thread == null
18320                    || callerApp.thread.asBinder() != caller.asBinder())) {
18321                // Original caller already died
18322                return null;
18323            }
18324            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18325            if (rl == null) {
18326                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18327                        userId, receiver);
18328                if (rl.app != null) {
18329                    rl.app.receivers.add(rl);
18330                } else {
18331                    try {
18332                        receiver.asBinder().linkToDeath(rl, 0);
18333                    } catch (RemoteException e) {
18334                        return sticky;
18335                    }
18336                    rl.linkedToDeath = true;
18337                }
18338                mRegisteredReceivers.put(receiver.asBinder(), rl);
18339            } else if (rl.uid != callingUid) {
18340                throw new IllegalArgumentException(
18341                        "Receiver requested to register for uid " + callingUid
18342                        + " was previously registered for uid " + rl.uid
18343                        + " callerPackage is " + callerPackage);
18344            } else if (rl.pid != callingPid) {
18345                throw new IllegalArgumentException(
18346                        "Receiver requested to register for pid " + callingPid
18347                        + " was previously registered for pid " + rl.pid
18348                        + " callerPackage is " + callerPackage);
18349            } else if (rl.userId != userId) {
18350                throw new IllegalArgumentException(
18351                        "Receiver requested to register for user " + userId
18352                        + " was previously registered for user " + rl.userId
18353                        + " callerPackage is " + callerPackage);
18354            }
18355            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18356                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18357            rl.add(bf);
18358            if (!bf.debugCheck()) {
18359                Slog.w(TAG, "==> For Dynamic broadcast");
18360            }
18361            mReceiverResolver.addFilter(bf);
18362
18363            // Enqueue broadcasts for all existing stickies that match
18364            // this filter.
18365            if (allSticky != null) {
18366                ArrayList receivers = new ArrayList();
18367                receivers.add(bf);
18368
18369                final int stickyCount = allSticky.size();
18370                for (int i = 0; i < stickyCount; i++) {
18371                    Intent intent = allSticky.get(i);
18372                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18373                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18374                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18375                            null, 0, null, null, false, true, true, -1);
18376                    queue.enqueueParallelBroadcastLocked(r);
18377                    queue.scheduleBroadcastsLocked();
18378                }
18379            }
18380
18381            return sticky;
18382        }
18383    }
18384
18385    public void unregisterReceiver(IIntentReceiver receiver) {
18386        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18387
18388        final long origId = Binder.clearCallingIdentity();
18389        try {
18390            boolean doTrim = false;
18391
18392            synchronized(this) {
18393                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18394                if (rl != null) {
18395                    final BroadcastRecord r = rl.curBroadcast;
18396                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18397                        final boolean doNext = r.queue.finishReceiverLocked(
18398                                r, r.resultCode, r.resultData, r.resultExtras,
18399                                r.resultAbort, false);
18400                        if (doNext) {
18401                            doTrim = true;
18402                            r.queue.processNextBroadcast(false);
18403                        }
18404                    }
18405
18406                    if (rl.app != null) {
18407                        rl.app.receivers.remove(rl);
18408                    }
18409                    removeReceiverLocked(rl);
18410                    if (rl.linkedToDeath) {
18411                        rl.linkedToDeath = false;
18412                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18413                    }
18414                }
18415            }
18416
18417            // If we actually concluded any broadcasts, we might now be able
18418            // to trim the recipients' apps from our working set
18419            if (doTrim) {
18420                trimApplications();
18421                return;
18422            }
18423
18424        } finally {
18425            Binder.restoreCallingIdentity(origId);
18426        }
18427    }
18428
18429    void removeReceiverLocked(ReceiverList rl) {
18430        mRegisteredReceivers.remove(rl.receiver.asBinder());
18431        for (int i = rl.size() - 1; i >= 0; i--) {
18432            mReceiverResolver.removeFilter(rl.get(i));
18433        }
18434    }
18435
18436    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18437        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18438            ProcessRecord r = mLruProcesses.get(i);
18439            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18440                try {
18441                    r.thread.dispatchPackageBroadcast(cmd, packages);
18442                } catch (RemoteException ex) {
18443                }
18444            }
18445        }
18446    }
18447
18448    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18449            int callingUid, int[] users) {
18450        // TODO: come back and remove this assumption to triage all broadcasts
18451        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18452
18453        List<ResolveInfo> receivers = null;
18454        try {
18455            HashSet<ComponentName> singleUserReceivers = null;
18456            boolean scannedFirstReceivers = false;
18457            for (int user : users) {
18458                // Skip users that have Shell restrictions, with exception of always permitted
18459                // Shell broadcasts
18460                if (callingUid == Process.SHELL_UID
18461                        && mUserController.hasUserRestriction(
18462                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18463                        && !isPermittedShellBroadcast(intent)) {
18464                    continue;
18465                }
18466                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18467                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18468                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18469                    // If this is not the system user, we need to check for
18470                    // any receivers that should be filtered out.
18471                    for (int i=0; i<newReceivers.size(); i++) {
18472                        ResolveInfo ri = newReceivers.get(i);
18473                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18474                            newReceivers.remove(i);
18475                            i--;
18476                        }
18477                    }
18478                }
18479                if (newReceivers != null && newReceivers.size() == 0) {
18480                    newReceivers = null;
18481                }
18482                if (receivers == null) {
18483                    receivers = newReceivers;
18484                } else if (newReceivers != null) {
18485                    // We need to concatenate the additional receivers
18486                    // found with what we have do far.  This would be easy,
18487                    // but we also need to de-dup any receivers that are
18488                    // singleUser.
18489                    if (!scannedFirstReceivers) {
18490                        // Collect any single user receivers we had already retrieved.
18491                        scannedFirstReceivers = true;
18492                        for (int i=0; i<receivers.size(); i++) {
18493                            ResolveInfo ri = receivers.get(i);
18494                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18495                                ComponentName cn = new ComponentName(
18496                                        ri.activityInfo.packageName, ri.activityInfo.name);
18497                                if (singleUserReceivers == null) {
18498                                    singleUserReceivers = new HashSet<ComponentName>();
18499                                }
18500                                singleUserReceivers.add(cn);
18501                            }
18502                        }
18503                    }
18504                    // Add the new results to the existing results, tracking
18505                    // and de-dupping single user receivers.
18506                    for (int i=0; i<newReceivers.size(); i++) {
18507                        ResolveInfo ri = newReceivers.get(i);
18508                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18509                            ComponentName cn = new ComponentName(
18510                                    ri.activityInfo.packageName, ri.activityInfo.name);
18511                            if (singleUserReceivers == null) {
18512                                singleUserReceivers = new HashSet<ComponentName>();
18513                            }
18514                            if (!singleUserReceivers.contains(cn)) {
18515                                singleUserReceivers.add(cn);
18516                                receivers.add(ri);
18517                            }
18518                        } else {
18519                            receivers.add(ri);
18520                        }
18521                    }
18522                }
18523            }
18524        } catch (RemoteException ex) {
18525            // pm is in same process, this will never happen.
18526        }
18527        return receivers;
18528    }
18529
18530    private boolean isPermittedShellBroadcast(Intent intent) {
18531        // remote bugreport should always be allowed to be taken
18532        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18533    }
18534
18535    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18536            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18537        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18538            // Don't yell about broadcasts sent via shell
18539            return;
18540        }
18541
18542        final String action = intent.getAction();
18543        if (isProtectedBroadcast
18544                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18545                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18546                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18547                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18548                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18549                || Intent.ACTION_MASTER_CLEAR.equals(action)
18550                || Intent.ACTION_FACTORY_RESET.equals(action)
18551                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18552                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18553                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18554                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18555                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18556                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18557                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18558            // Broadcast is either protected, or it's a public action that
18559            // we've relaxed, so it's fine for system internals to send.
18560            return;
18561        }
18562
18563        // This broadcast may be a problem...  but there are often system components that
18564        // want to send an internal broadcast to themselves, which is annoying to have to
18565        // explicitly list each action as a protected broadcast, so we will check for that
18566        // one safe case and allow it: an explicit broadcast, only being received by something
18567        // that has protected itself.
18568        if (receivers != null && receivers.size() > 0
18569                && (intent.getPackage() != null || intent.getComponent() != null)) {
18570            boolean allProtected = true;
18571            for (int i = receivers.size()-1; i >= 0; i--) {
18572                Object target = receivers.get(i);
18573                if (target instanceof ResolveInfo) {
18574                    ResolveInfo ri = (ResolveInfo)target;
18575                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18576                        allProtected = false;
18577                        break;
18578                    }
18579                } else {
18580                    BroadcastFilter bf = (BroadcastFilter)target;
18581                    if (bf.requiredPermission == null) {
18582                        allProtected = false;
18583                        break;
18584                    }
18585                }
18586            }
18587            if (allProtected) {
18588                // All safe!
18589                return;
18590            }
18591        }
18592
18593        // The vast majority of broadcasts sent from system internals
18594        // should be protected to avoid security holes, so yell loudly
18595        // to ensure we examine these cases.
18596        if (callerApp != null) {
18597            Log.wtf(TAG, "Sending non-protected broadcast " + action
18598                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18599                    new Throwable());
18600        } else {
18601            Log.wtf(TAG, "Sending non-protected broadcast " + action
18602                            + " from system uid " + UserHandle.formatUid(callingUid)
18603                            + " pkg " + callerPackage,
18604                    new Throwable());
18605        }
18606    }
18607
18608    final int broadcastIntentLocked(ProcessRecord callerApp,
18609            String callerPackage, Intent intent, String resolvedType,
18610            IIntentReceiver resultTo, int resultCode, String resultData,
18611            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18612            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18613        intent = new Intent(intent);
18614
18615        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
18616        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
18617        if (callerInstantApp) {
18618            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
18619        }
18620
18621        // By default broadcasts do not go to stopped apps.
18622        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
18623
18624        // If we have not finished booting, don't allow this to launch new processes.
18625        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
18626            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18627        }
18628
18629        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
18630                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
18631                + " ordered=" + ordered + " userid=" + userId);
18632        if ((resultTo != null) && !ordered) {
18633            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
18634        }
18635
18636        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18637                ALLOW_NON_FULL, "broadcast", callerPackage);
18638
18639        // Make sure that the user who is receiving this broadcast is running.
18640        // If not, we will just skip it. Make an exception for shutdown broadcasts
18641        // and upgrade steps.
18642
18643        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
18644            if ((callingUid != Process.SYSTEM_UID
18645                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
18646                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
18647                Slog.w(TAG, "Skipping broadcast of " + intent
18648                        + ": user " + userId + " is stopped");
18649                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
18650            }
18651        }
18652
18653        BroadcastOptions brOptions = null;
18654        if (bOptions != null) {
18655            brOptions = new BroadcastOptions(bOptions);
18656            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18657                // See if the caller is allowed to do this.  Note we are checking against
18658                // the actual real caller (not whoever provided the operation as say a
18659                // PendingIntent), because that who is actually supplied the arguments.
18660                if (checkComponentPermission(
18661                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18662                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
18663                        != PackageManager.PERMISSION_GRANTED) {
18664                    String msg = "Permission Denial: " + intent.getAction()
18665                            + " broadcast from " + callerPackage + " (pid=" + callingPid
18666                            + ", uid=" + callingUid + ")"
18667                            + " requires "
18668                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18669                    Slog.w(TAG, msg);
18670                    throw new SecurityException(msg);
18671                }
18672            }
18673        }
18674
18675        // Verify that protected broadcasts are only being sent by system code,
18676        // and that system code is only sending protected broadcasts.
18677        final String action = intent.getAction();
18678        final boolean isProtectedBroadcast;
18679        try {
18680            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18681        } catch (RemoteException e) {
18682            Slog.w(TAG, "Remote exception", e);
18683            return ActivityManager.BROADCAST_SUCCESS;
18684        }
18685
18686        final boolean isCallerSystem;
18687        switch (UserHandle.getAppId(callingUid)) {
18688            case Process.ROOT_UID:
18689            case Process.SYSTEM_UID:
18690            case Process.PHONE_UID:
18691            case Process.BLUETOOTH_UID:
18692            case Process.NFC_UID:
18693                isCallerSystem = true;
18694                break;
18695            default:
18696                isCallerSystem = (callerApp != null) && callerApp.persistent;
18697                break;
18698        }
18699
18700        // First line security check before anything else: stop non-system apps from
18701        // sending protected broadcasts.
18702        if (!isCallerSystem) {
18703            if (isProtectedBroadcast) {
18704                String msg = "Permission Denial: not allowed to send broadcast "
18705                        + action + " from pid="
18706                        + callingPid + ", uid=" + callingUid;
18707                Slog.w(TAG, msg);
18708                throw new SecurityException(msg);
18709
18710            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18711                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18712                // Special case for compatibility: we don't want apps to send this,
18713                // but historically it has not been protected and apps may be using it
18714                // to poke their own app widget.  So, instead of making it protected,
18715                // just limit it to the caller.
18716                if (callerPackage == null) {
18717                    String msg = "Permission Denial: not allowed to send broadcast "
18718                            + action + " from unknown caller.";
18719                    Slog.w(TAG, msg);
18720                    throw new SecurityException(msg);
18721                } else if (intent.getComponent() != null) {
18722                    // They are good enough to send to an explicit component...  verify
18723                    // it is being sent to the calling app.
18724                    if (!intent.getComponent().getPackageName().equals(
18725                            callerPackage)) {
18726                        String msg = "Permission Denial: not allowed to send broadcast "
18727                                + action + " to "
18728                                + intent.getComponent().getPackageName() + " from "
18729                                + callerPackage;
18730                        Slog.w(TAG, msg);
18731                        throw new SecurityException(msg);
18732                    }
18733                } else {
18734                    // Limit broadcast to their own package.
18735                    intent.setPackage(callerPackage);
18736                }
18737            }
18738        }
18739
18740        if (action != null) {
18741            if (getBackgroundLaunchBroadcasts().contains(action)) {
18742                if (DEBUG_BACKGROUND_CHECK) {
18743                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
18744                }
18745                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
18746            }
18747
18748            switch (action) {
18749                case Intent.ACTION_UID_REMOVED:
18750                case Intent.ACTION_PACKAGE_REMOVED:
18751                case Intent.ACTION_PACKAGE_CHANGED:
18752                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18753                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18754                case Intent.ACTION_PACKAGES_SUSPENDED:
18755                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18756                    // Handle special intents: if this broadcast is from the package
18757                    // manager about a package being removed, we need to remove all of
18758                    // its activities from the history stack.
18759                    if (checkComponentPermission(
18760                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18761                            callingPid, callingUid, -1, true)
18762                            != PackageManager.PERMISSION_GRANTED) {
18763                        String msg = "Permission Denial: " + intent.getAction()
18764                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18765                                + ", uid=" + callingUid + ")"
18766                                + " requires "
18767                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18768                        Slog.w(TAG, msg);
18769                        throw new SecurityException(msg);
18770                    }
18771                    switch (action) {
18772                        case Intent.ACTION_UID_REMOVED:
18773                            final Bundle intentExtras = intent.getExtras();
18774                            final int uid = intentExtras != null
18775                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18776                            if (uid >= 0) {
18777                                mBatteryStatsService.removeUid(uid);
18778                                mAppOpsService.uidRemoved(uid);
18779                            }
18780                            break;
18781                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18782                            // If resources are unavailable just force stop all those packages
18783                            // and flush the attribute cache as well.
18784                            String list[] =
18785                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18786                            if (list != null && list.length > 0) {
18787                                for (int i = 0; i < list.length; i++) {
18788                                    forceStopPackageLocked(list[i], -1, false, true, true,
18789                                            false, false, userId, "storage unmount");
18790                                }
18791                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18792                                sendPackageBroadcastLocked(
18793                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18794                                        list, userId);
18795                            }
18796                            break;
18797                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18798                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18799                            break;
18800                        case Intent.ACTION_PACKAGE_REMOVED:
18801                        case Intent.ACTION_PACKAGE_CHANGED:
18802                            Uri data = intent.getData();
18803                            String ssp;
18804                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18805                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18806                                final boolean replacing =
18807                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18808                                final boolean killProcess =
18809                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18810                                final boolean fullUninstall = removed && !replacing;
18811                                if (removed) {
18812                                    if (killProcess) {
18813                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18814                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18815                                                false, true, true, false, fullUninstall, userId,
18816                                                removed ? "pkg removed" : "pkg changed");
18817                                    }
18818                                    final int cmd = killProcess
18819                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18820                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18821                                    sendPackageBroadcastLocked(cmd,
18822                                            new String[] {ssp}, userId);
18823                                    if (fullUninstall) {
18824                                        mAppOpsService.packageRemoved(
18825                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18826
18827                                        // Remove all permissions granted from/to this package
18828                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18829
18830                                        removeTasksByPackageNameLocked(ssp, userId);
18831
18832                                        // Hide the "unsupported display" dialog if necessary.
18833                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18834                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18835                                            mUnsupportedDisplaySizeDialog.dismiss();
18836                                            mUnsupportedDisplaySizeDialog = null;
18837                                        }
18838                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18839                                        mBatteryStatsService.notePackageUninstalled(ssp);
18840                                    }
18841                                } else {
18842                                    if (killProcess) {
18843                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18844                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18845                                                userId, ProcessList.INVALID_ADJ,
18846                                                false, true, true, false, "change " + ssp);
18847                                    }
18848                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18849                                            intent.getStringArrayExtra(
18850                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18851                                }
18852                            }
18853                            break;
18854                        case Intent.ACTION_PACKAGES_SUSPENDED:
18855                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18856                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18857                                    intent.getAction());
18858                            final String[] packageNames = intent.getStringArrayExtra(
18859                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18860                            final int userHandle = intent.getIntExtra(
18861                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18862
18863                            synchronized(ActivityManagerService.this) {
18864                                mRecentTasks.onPackagesSuspendedChanged(
18865                                        packageNames, suspended, userHandle);
18866                            }
18867                            break;
18868                    }
18869                    break;
18870                case Intent.ACTION_PACKAGE_REPLACED:
18871                {
18872                    final Uri data = intent.getData();
18873                    final String ssp;
18874                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18875                        final ApplicationInfo aInfo =
18876                                getPackageManagerInternalLocked().getApplicationInfo(
18877                                        ssp,
18878                                        userId);
18879                        if (aInfo == null) {
18880                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18881                                    + " ssp=" + ssp + " data=" + data);
18882                            return ActivityManager.BROADCAST_SUCCESS;
18883                        }
18884                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18885                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
18886                                new String[] {ssp}, userId);
18887                    }
18888                    break;
18889                }
18890                case Intent.ACTION_PACKAGE_ADDED:
18891                {
18892                    // Special case for adding a package: by default turn on compatibility mode.
18893                    Uri data = intent.getData();
18894                    String ssp;
18895                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18896                        final boolean replacing =
18897                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18898                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18899
18900                        try {
18901                            ApplicationInfo ai = AppGlobals.getPackageManager().
18902                                    getApplicationInfo(ssp, 0, 0);
18903                            mBatteryStatsService.notePackageInstalled(ssp,
18904                                    ai != null ? ai.versionCode : 0);
18905                        } catch (RemoteException e) {
18906                        }
18907                    }
18908                    break;
18909                }
18910                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18911                {
18912                    Uri data = intent.getData();
18913                    String ssp;
18914                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18915                        // Hide the "unsupported display" dialog if necessary.
18916                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18917                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18918                            mUnsupportedDisplaySizeDialog.dismiss();
18919                            mUnsupportedDisplaySizeDialog = null;
18920                        }
18921                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18922                    }
18923                    break;
18924                }
18925                case Intent.ACTION_TIMEZONE_CHANGED:
18926                    // If this is the time zone changed action, queue up a message that will reset
18927                    // the timezone of all currently running processes. This message will get
18928                    // queued up before the broadcast happens.
18929                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18930                    break;
18931                case Intent.ACTION_TIME_CHANGED:
18932                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
18933                    // the tri-state value it may contain and "unknown".
18934                    // For convenience we re-use the Intent extra values.
18935                    final int NO_EXTRA_VALUE_FOUND = -1;
18936                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
18937                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
18938                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
18939                    // Only send a message if the time preference is available.
18940                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
18941                        Message updateTimePreferenceMsg =
18942                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
18943                                        timeFormatPreferenceMsgValue, 0);
18944                        mHandler.sendMessage(updateTimePreferenceMsg);
18945                    }
18946                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18947                    synchronized (stats) {
18948                        stats.noteCurrentTimeChangedLocked();
18949                    }
18950                    break;
18951                case Intent.ACTION_CLEAR_DNS_CACHE:
18952                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18953                    break;
18954                case Proxy.PROXY_CHANGE_ACTION:
18955                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18956                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18957                    break;
18958                case android.hardware.Camera.ACTION_NEW_PICTURE:
18959                case android.hardware.Camera.ACTION_NEW_VIDEO:
18960                    // These broadcasts are no longer allowed by the system, since they can
18961                    // cause significant thrashing at a crictical point (using the camera).
18962                    // Apps should use JobScehduler to monitor for media provider changes.
18963                    Slog.w(TAG, action + " no longer allowed; dropping from "
18964                            + UserHandle.formatUid(callingUid));
18965                    if (resultTo != null) {
18966                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18967                        try {
18968                            queue.performReceiveLocked(callerApp, resultTo, intent,
18969                                    Activity.RESULT_CANCELED, null, null,
18970                                    false, false, userId);
18971                        } catch (RemoteException e) {
18972                            Slog.w(TAG, "Failure ["
18973                                    + queue.mQueueName + "] sending broadcast result of "
18974                                    + intent, e);
18975
18976                        }
18977                    }
18978                    // Lie; we don't want to crash the app.
18979                    return ActivityManager.BROADCAST_SUCCESS;
18980                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18981                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18982                    break;
18983            }
18984        }
18985
18986        // Add to the sticky list if requested.
18987        if (sticky) {
18988            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18989                    callingPid, callingUid)
18990                    != PackageManager.PERMISSION_GRANTED) {
18991                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18992                        + callingPid + ", uid=" + callingUid
18993                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18994                Slog.w(TAG, msg);
18995                throw new SecurityException(msg);
18996            }
18997            if (requiredPermissions != null && requiredPermissions.length > 0) {
18998                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18999                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19000                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19001            }
19002            if (intent.getComponent() != null) {
19003                throw new SecurityException(
19004                        "Sticky broadcasts can't target a specific component");
19005            }
19006            // We use userId directly here, since the "all" target is maintained
19007            // as a separate set of sticky broadcasts.
19008            if (userId != UserHandle.USER_ALL) {
19009                // But first, if this is not a broadcast to all users, then
19010                // make sure it doesn't conflict with an existing broadcast to
19011                // all users.
19012                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19013                        UserHandle.USER_ALL);
19014                if (stickies != null) {
19015                    ArrayList<Intent> list = stickies.get(intent.getAction());
19016                    if (list != null) {
19017                        int N = list.size();
19018                        int i;
19019                        for (i=0; i<N; i++) {
19020                            if (intent.filterEquals(list.get(i))) {
19021                                throw new IllegalArgumentException(
19022                                        "Sticky broadcast " + intent + " for user "
19023                                        + userId + " conflicts with existing global broadcast");
19024                            }
19025                        }
19026                    }
19027                }
19028            }
19029            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19030            if (stickies == null) {
19031                stickies = new ArrayMap<>();
19032                mStickyBroadcasts.put(userId, stickies);
19033            }
19034            ArrayList<Intent> list = stickies.get(intent.getAction());
19035            if (list == null) {
19036                list = new ArrayList<>();
19037                stickies.put(intent.getAction(), list);
19038            }
19039            final int stickiesCount = list.size();
19040            int i;
19041            for (i = 0; i < stickiesCount; i++) {
19042                if (intent.filterEquals(list.get(i))) {
19043                    // This sticky already exists, replace it.
19044                    list.set(i, new Intent(intent));
19045                    break;
19046                }
19047            }
19048            if (i >= stickiesCount) {
19049                list.add(new Intent(intent));
19050            }
19051        }
19052
19053        int[] users;
19054        if (userId == UserHandle.USER_ALL) {
19055            // Caller wants broadcast to go to all started users.
19056            users = mUserController.getStartedUserArrayLocked();
19057        } else {
19058            // Caller wants broadcast to go to one specific user.
19059            users = new int[] {userId};
19060        }
19061
19062        // Figure out who all will receive this broadcast.
19063        List receivers = null;
19064        List<BroadcastFilter> registeredReceivers = null;
19065        // Need to resolve the intent to interested receivers...
19066        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19067                 == 0) {
19068            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19069        }
19070        if (intent.getComponent() == null) {
19071            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
19072                // Query one target user at a time, excluding shell-restricted users
19073                for (int i = 0; i < users.length; i++) {
19074                    if (mUserController.hasUserRestriction(
19075                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19076                        continue;
19077                    }
19078                    List<BroadcastFilter> registeredReceiversForUser =
19079                            mReceiverResolver.queryIntent(intent,
19080                                    resolvedType, false /*defaultOnly*/, users[i]);
19081                    if (registeredReceivers == null) {
19082                        registeredReceivers = registeredReceiversForUser;
19083                    } else if (registeredReceiversForUser != null) {
19084                        registeredReceivers.addAll(registeredReceiversForUser);
19085                    }
19086                }
19087            } else {
19088                registeredReceivers = mReceiverResolver.queryIntent(intent,
19089                        resolvedType, false /*defaultOnly*/, userId);
19090            }
19091        }
19092
19093        final boolean replacePending =
19094                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19095
19096        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19097                + " replacePending=" + replacePending);
19098
19099        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19100        if (!ordered && NR > 0) {
19101            // If we are not serializing this broadcast, then send the
19102            // registered receivers separately so they don't wait for the
19103            // components to be launched.
19104            if (isCallerSystem) {
19105                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19106                        isProtectedBroadcast, registeredReceivers);
19107            }
19108            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19109            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19110                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19111                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19112                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19113            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19114            final boolean replaced = replacePending
19115                    && (queue.replaceParallelBroadcastLocked(r) != null);
19116            // Note: We assume resultTo is null for non-ordered broadcasts.
19117            if (!replaced) {
19118                queue.enqueueParallelBroadcastLocked(r);
19119                queue.scheduleBroadcastsLocked();
19120            }
19121            registeredReceivers = null;
19122            NR = 0;
19123        }
19124
19125        // Merge into one list.
19126        int ir = 0;
19127        if (receivers != null) {
19128            // A special case for PACKAGE_ADDED: do not allow the package
19129            // being added to see this broadcast.  This prevents them from
19130            // using this as a back door to get run as soon as they are
19131            // installed.  Maybe in the future we want to have a special install
19132            // broadcast or such for apps, but we'd like to deliberately make
19133            // this decision.
19134            String skipPackages[] = null;
19135            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19136                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19137                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19138                Uri data = intent.getData();
19139                if (data != null) {
19140                    String pkgName = data.getSchemeSpecificPart();
19141                    if (pkgName != null) {
19142                        skipPackages = new String[] { pkgName };
19143                    }
19144                }
19145            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19146                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19147            }
19148            if (skipPackages != null && (skipPackages.length > 0)) {
19149                for (String skipPackage : skipPackages) {
19150                    if (skipPackage != null) {
19151                        int NT = receivers.size();
19152                        for (int it=0; it<NT; it++) {
19153                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19154                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19155                                receivers.remove(it);
19156                                it--;
19157                                NT--;
19158                            }
19159                        }
19160                    }
19161                }
19162            }
19163
19164            int NT = receivers != null ? receivers.size() : 0;
19165            int it = 0;
19166            ResolveInfo curt = null;
19167            BroadcastFilter curr = null;
19168            while (it < NT && ir < NR) {
19169                if (curt == null) {
19170                    curt = (ResolveInfo)receivers.get(it);
19171                }
19172                if (curr == null) {
19173                    curr = registeredReceivers.get(ir);
19174                }
19175                if (curr.getPriority() >= curt.priority) {
19176                    // Insert this broadcast record into the final list.
19177                    receivers.add(it, curr);
19178                    ir++;
19179                    curr = null;
19180                    it++;
19181                    NT++;
19182                } else {
19183                    // Skip to the next ResolveInfo in the final list.
19184                    it++;
19185                    curt = null;
19186                }
19187            }
19188        }
19189        while (ir < NR) {
19190            if (receivers == null) {
19191                receivers = new ArrayList();
19192            }
19193            receivers.add(registeredReceivers.get(ir));
19194            ir++;
19195        }
19196
19197        if (isCallerSystem) {
19198            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19199                    isProtectedBroadcast, receivers);
19200        }
19201
19202        if ((receivers != null && receivers.size() > 0)
19203                || resultTo != null) {
19204            BroadcastQueue queue = broadcastQueueForIntent(intent);
19205            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19206                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19207                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19208                    resultData, resultExtras, ordered, sticky, false, userId);
19209
19210            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19211                    + ": prev had " + queue.mOrderedBroadcasts.size());
19212            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19213                    "Enqueueing broadcast " + r.intent.getAction());
19214
19215            final BroadcastRecord oldRecord =
19216                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19217            if (oldRecord != null) {
19218                // Replaced, fire the result-to receiver.
19219                if (oldRecord.resultTo != null) {
19220                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19221                    try {
19222                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19223                                oldRecord.intent,
19224                                Activity.RESULT_CANCELED, null, null,
19225                                false, false, oldRecord.userId);
19226                    } catch (RemoteException e) {
19227                        Slog.w(TAG, "Failure ["
19228                                + queue.mQueueName + "] sending broadcast result of "
19229                                + intent, e);
19230
19231                    }
19232                }
19233            } else {
19234                queue.enqueueOrderedBroadcastLocked(r);
19235                queue.scheduleBroadcastsLocked();
19236            }
19237        } else {
19238            // There was nobody interested in the broadcast, but we still want to record
19239            // that it happened.
19240            if (intent.getComponent() == null && intent.getPackage() == null
19241                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19242                // This was an implicit broadcast... let's record it for posterity.
19243                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19244            }
19245        }
19246
19247        return ActivityManager.BROADCAST_SUCCESS;
19248    }
19249
19250    final void rotateBroadcastStatsIfNeededLocked() {
19251        final long now = SystemClock.elapsedRealtime();
19252        if (mCurBroadcastStats == null ||
19253                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19254            mLastBroadcastStats = mCurBroadcastStats;
19255            if (mLastBroadcastStats != null) {
19256                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19257                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19258            }
19259            mCurBroadcastStats = new BroadcastStats();
19260        }
19261    }
19262
19263    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19264            int skipCount, long dispatchTime) {
19265        rotateBroadcastStatsIfNeededLocked();
19266        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19267    }
19268
19269    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19270        rotateBroadcastStatsIfNeededLocked();
19271        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19272    }
19273
19274    final Intent verifyBroadcastLocked(Intent intent) {
19275        // Refuse possible leaked file descriptors
19276        if (intent != null && intent.hasFileDescriptors() == true) {
19277            throw new IllegalArgumentException("File descriptors passed in Intent");
19278        }
19279
19280        int flags = intent.getFlags();
19281
19282        if (!mProcessesReady) {
19283            // if the caller really truly claims to know what they're doing, go
19284            // ahead and allow the broadcast without launching any receivers
19285            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19286                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19287            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19288                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19289                        + " before boot completion");
19290                throw new IllegalStateException("Cannot broadcast before boot completed");
19291            }
19292        }
19293
19294        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19295            throw new IllegalArgumentException(
19296                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19297        }
19298
19299        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19300            switch (Binder.getCallingUid()) {
19301                case Process.ROOT_UID:
19302                case Process.SHELL_UID:
19303                    break;
19304                default:
19305                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19306                            + Binder.getCallingUid());
19307                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19308                    break;
19309            }
19310        }
19311
19312        return intent;
19313    }
19314
19315    public final int broadcastIntent(IApplicationThread caller,
19316            Intent intent, String resolvedType, IIntentReceiver resultTo,
19317            int resultCode, String resultData, Bundle resultExtras,
19318            String[] requiredPermissions, int appOp, Bundle bOptions,
19319            boolean serialized, boolean sticky, int userId) {
19320        enforceNotIsolatedCaller("broadcastIntent");
19321        synchronized(this) {
19322            intent = verifyBroadcastLocked(intent);
19323
19324            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19325            final int callingPid = Binder.getCallingPid();
19326            final int callingUid = Binder.getCallingUid();
19327            final long origId = Binder.clearCallingIdentity();
19328            int res = broadcastIntentLocked(callerApp,
19329                    callerApp != null ? callerApp.info.packageName : null,
19330                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19331                    requiredPermissions, appOp, bOptions, serialized, sticky,
19332                    callingPid, callingUid, userId);
19333            Binder.restoreCallingIdentity(origId);
19334            return res;
19335        }
19336    }
19337
19338
19339    int broadcastIntentInPackage(String packageName, int uid,
19340            Intent intent, String resolvedType, IIntentReceiver resultTo,
19341            int resultCode, String resultData, Bundle resultExtras,
19342            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19343            int userId) {
19344        synchronized(this) {
19345            intent = verifyBroadcastLocked(intent);
19346
19347            final long origId = Binder.clearCallingIdentity();
19348            String[] requiredPermissions = requiredPermission == null ? null
19349                    : new String[] {requiredPermission};
19350            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19351                    resultTo, resultCode, resultData, resultExtras,
19352                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19353                    sticky, -1, uid, userId);
19354            Binder.restoreCallingIdentity(origId);
19355            return res;
19356        }
19357    }
19358
19359    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19360        // Refuse possible leaked file descriptors
19361        if (intent != null && intent.hasFileDescriptors() == true) {
19362            throw new IllegalArgumentException("File descriptors passed in Intent");
19363        }
19364
19365        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19366                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19367
19368        synchronized(this) {
19369            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19370                    != PackageManager.PERMISSION_GRANTED) {
19371                String msg = "Permission Denial: unbroadcastIntent() from pid="
19372                        + Binder.getCallingPid()
19373                        + ", uid=" + Binder.getCallingUid()
19374                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19375                Slog.w(TAG, msg);
19376                throw new SecurityException(msg);
19377            }
19378            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19379            if (stickies != null) {
19380                ArrayList<Intent> list = stickies.get(intent.getAction());
19381                if (list != null) {
19382                    int N = list.size();
19383                    int i;
19384                    for (i=0; i<N; i++) {
19385                        if (intent.filterEquals(list.get(i))) {
19386                            list.remove(i);
19387                            break;
19388                        }
19389                    }
19390                    if (list.size() <= 0) {
19391                        stickies.remove(intent.getAction());
19392                    }
19393                }
19394                if (stickies.size() <= 0) {
19395                    mStickyBroadcasts.remove(userId);
19396                }
19397            }
19398        }
19399    }
19400
19401    void backgroundServicesFinishedLocked(int userId) {
19402        for (BroadcastQueue queue : mBroadcastQueues) {
19403            queue.backgroundServicesFinishedLocked(userId);
19404        }
19405    }
19406
19407    public void finishReceiver(IBinder who, int resultCode, String resultData,
19408            Bundle resultExtras, boolean resultAbort, int flags) {
19409        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19410
19411        // Refuse possible leaked file descriptors
19412        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19413            throw new IllegalArgumentException("File descriptors passed in Bundle");
19414        }
19415
19416        final long origId = Binder.clearCallingIdentity();
19417        try {
19418            boolean doNext = false;
19419            BroadcastRecord r;
19420
19421            synchronized(this) {
19422                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19423                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19424                r = queue.getMatchingOrderedReceiver(who);
19425                if (r != null) {
19426                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19427                        resultData, resultExtras, resultAbort, true);
19428                }
19429            }
19430
19431            if (doNext) {
19432                r.queue.processNextBroadcast(false);
19433            }
19434            trimApplications();
19435        } finally {
19436            Binder.restoreCallingIdentity(origId);
19437        }
19438    }
19439
19440    // =========================================================
19441    // INSTRUMENTATION
19442    // =========================================================
19443
19444    public boolean startInstrumentation(ComponentName className,
19445            String profileFile, int flags, Bundle arguments,
19446            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19447            int userId, String abiOverride) {
19448        enforceNotIsolatedCaller("startInstrumentation");
19449        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19450                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19451        // Refuse possible leaked file descriptors
19452        if (arguments != null && arguments.hasFileDescriptors()) {
19453            throw new IllegalArgumentException("File descriptors passed in Bundle");
19454        }
19455
19456        synchronized(this) {
19457            InstrumentationInfo ii = null;
19458            ApplicationInfo ai = null;
19459            try {
19460                ii = mContext.getPackageManager().getInstrumentationInfo(
19461                    className, STOCK_PM_FLAGS);
19462                ai = AppGlobals.getPackageManager().getApplicationInfo(
19463                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19464            } catch (PackageManager.NameNotFoundException e) {
19465            } catch (RemoteException e) {
19466            }
19467            if (ii == null) {
19468                reportStartInstrumentationFailureLocked(watcher, className,
19469                        "Unable to find instrumentation info for: " + className);
19470                return false;
19471            }
19472            if (ai == null) {
19473                reportStartInstrumentationFailureLocked(watcher, className,
19474                        "Unable to find instrumentation target package: " + ii.targetPackage);
19475                return false;
19476            }
19477            if (!ai.hasCode()) {
19478                reportStartInstrumentationFailureLocked(watcher, className,
19479                        "Instrumentation target has no code: " + ii.targetPackage);
19480                return false;
19481            }
19482
19483            int match = mContext.getPackageManager().checkSignatures(
19484                    ii.targetPackage, ii.packageName);
19485            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19486                String msg = "Permission Denial: starting instrumentation "
19487                        + className + " from pid="
19488                        + Binder.getCallingPid()
19489                        + ", uid=" + Binder.getCallingPid()
19490                        + " not allowed because package " + ii.packageName
19491                        + " does not have a signature matching the target "
19492                        + ii.targetPackage;
19493                reportStartInstrumentationFailureLocked(watcher, className, msg);
19494                throw new SecurityException(msg);
19495            }
19496
19497            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19498            activeInstr.mClass = className;
19499            String defProcess = ai.processName;;
19500            if (ii.targetProcess == null) {
19501                activeInstr.mTargetProcesses = new String[]{ai.processName};
19502            } else if (ii.targetProcess.equals("*")) {
19503                activeInstr.mTargetProcesses = new String[0];
19504            } else {
19505                activeInstr.mTargetProcesses = ii.targetProcess.split(",");
19506                defProcess = activeInstr.mTargetProcesses[0];
19507            }
19508            activeInstr.mTargetInfo = ai;
19509            activeInstr.mProfileFile = profileFile;
19510            activeInstr.mArguments = arguments;
19511            activeInstr.mWatcher = watcher;
19512            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19513            activeInstr.mResultClass = className;
19514
19515            final long origId = Binder.clearCallingIdentity();
19516            // Instrumentation can kill and relaunch even persistent processes
19517            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19518                    "start instr");
19519            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19520            app.instr = activeInstr;
19521            activeInstr.mFinished = false;
19522            activeInstr.mRunningProcesses.add(app);
19523            if (!mActiveInstrumentation.contains(activeInstr)) {
19524                mActiveInstrumentation.add(activeInstr);
19525            }
19526            Binder.restoreCallingIdentity(origId);
19527        }
19528
19529        return true;
19530    }
19531
19532    /**
19533     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19534     * error to the logs, but if somebody is watching, send the report there too.  This enables
19535     * the "am" command to report errors with more information.
19536     *
19537     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19538     * @param cn The component name of the instrumentation.
19539     * @param report The error report.
19540     */
19541    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19542            ComponentName cn, String report) {
19543        Slog.w(TAG, report);
19544        if (watcher != null) {
19545            Bundle results = new Bundle();
19546            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19547            results.putString("Error", report);
19548            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19549        }
19550    }
19551
19552    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19553        if (app.instr == null) {
19554            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19555            return;
19556        }
19557
19558        if (!app.instr.mFinished && results != null) {
19559            if (app.instr.mCurResults == null) {
19560                app.instr.mCurResults = new Bundle(results);
19561            } else {
19562                app.instr.mCurResults.putAll(results);
19563            }
19564        }
19565    }
19566
19567    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19568        int userId = UserHandle.getCallingUserId();
19569        // Refuse possible leaked file descriptors
19570        if (results != null && results.hasFileDescriptors()) {
19571            throw new IllegalArgumentException("File descriptors passed in Intent");
19572        }
19573
19574        synchronized(this) {
19575            ProcessRecord app = getRecordForAppLocked(target);
19576            if (app == null) {
19577                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19578                return;
19579            }
19580            final long origId = Binder.clearCallingIdentity();
19581            addInstrumentationResultsLocked(app, results);
19582            Binder.restoreCallingIdentity(origId);
19583        }
19584    }
19585
19586    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
19587        if (app.instr == null) {
19588            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19589            return;
19590        }
19591
19592        if (!app.instr.mFinished) {
19593            if (app.instr.mWatcher != null) {
19594                Bundle finalResults = app.instr.mCurResults;
19595                if (finalResults != null) {
19596                    if (app.instr.mCurResults != null && results != null) {
19597                        finalResults.putAll(results);
19598                    }
19599                } else {
19600                    finalResults = results;
19601                }
19602                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
19603                        app.instr.mClass, resultCode, finalResults);
19604            }
19605
19606            // Can't call out of the system process with a lock held, so post a message.
19607            if (app.instr.mUiAutomationConnection != null) {
19608                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
19609                        app.instr.mUiAutomationConnection).sendToTarget();
19610            }
19611            app.instr.mFinished = true;
19612        }
19613
19614        app.instr.removeProcess(app);
19615        app.instr = null;
19616
19617        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
19618                "finished inst");
19619    }
19620
19621    public void finishInstrumentation(IApplicationThread target,
19622            int resultCode, Bundle results) {
19623        int userId = UserHandle.getCallingUserId();
19624        // Refuse possible leaked file descriptors
19625        if (results != null && results.hasFileDescriptors()) {
19626            throw new IllegalArgumentException("File descriptors passed in Intent");
19627        }
19628
19629        synchronized(this) {
19630            ProcessRecord app = getRecordForAppLocked(target);
19631            if (app == null) {
19632                Slog.w(TAG, "finishInstrumentation: no app for " + target);
19633                return;
19634            }
19635            final long origId = Binder.clearCallingIdentity();
19636            finishInstrumentationLocked(app, resultCode, results);
19637            Binder.restoreCallingIdentity(origId);
19638        }
19639    }
19640
19641    // =========================================================
19642    // CONFIGURATION
19643    // =========================================================
19644
19645    public ConfigurationInfo getDeviceConfigurationInfo() {
19646        ConfigurationInfo config = new ConfigurationInfo();
19647        synchronized (this) {
19648            final Configuration globalConfig = getGlobalConfiguration();
19649            config.reqTouchScreen = globalConfig.touchscreen;
19650            config.reqKeyboardType = globalConfig.keyboard;
19651            config.reqNavigation = globalConfig.navigation;
19652            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
19653                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
19654                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
19655            }
19656            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
19657                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
19658                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
19659            }
19660            config.reqGlEsVersion = GL_ES_VERSION;
19661        }
19662        return config;
19663    }
19664
19665    ActivityStack getFocusedStack() {
19666        return mStackSupervisor.getFocusedStack();
19667    }
19668
19669    @Override
19670    public int getFocusedStackId() throws RemoteException {
19671        ActivityStack focusedStack = getFocusedStack();
19672        if (focusedStack != null) {
19673            return focusedStack.getStackId();
19674        }
19675        return -1;
19676    }
19677
19678    public Configuration getConfiguration() {
19679        Configuration ci;
19680        synchronized(this) {
19681            ci = new Configuration(getGlobalConfiguration());
19682            ci.userSetLocale = false;
19683        }
19684        return ci;
19685    }
19686
19687    @Override
19688    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
19689        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
19690        synchronized (this) {
19691            mSuppressResizeConfigChanges = suppress;
19692        }
19693    }
19694
19695    @Override
19696    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
19697        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
19698        if (StackId.isHomeOrRecentsStack(fromStackId)) {
19699            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
19700        }
19701        synchronized (this) {
19702            final long origId = Binder.clearCallingIdentity();
19703            try {
19704                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
19705            } finally {
19706                Binder.restoreCallingIdentity(origId);
19707            }
19708        }
19709    }
19710
19711    @Override
19712    public void updatePersistentConfiguration(Configuration values) {
19713        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
19714        enforceWriteSettingsPermission("updatePersistentConfiguration()");
19715        if (values == null) {
19716            throw new NullPointerException("Configuration must not be null");
19717        }
19718
19719        int userId = UserHandle.getCallingUserId();
19720
19721        synchronized(this) {
19722            updatePersistentConfigurationLocked(values, userId);
19723        }
19724    }
19725
19726    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
19727        final long origId = Binder.clearCallingIdentity();
19728        try {
19729            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
19730        } finally {
19731            Binder.restoreCallingIdentity(origId);
19732        }
19733    }
19734
19735    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
19736        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
19737                FONT_SCALE, 1.0f, userId);
19738
19739        synchronized (this) {
19740            if (getGlobalConfiguration().fontScale == scaleFactor) {
19741                return;
19742            }
19743
19744            final Configuration configuration
19745                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19746            configuration.fontScale = scaleFactor;
19747            updatePersistentConfigurationLocked(configuration, userId);
19748        }
19749    }
19750
19751    private void enforceWriteSettingsPermission(String func) {
19752        int uid = Binder.getCallingUid();
19753        if (uid == Process.ROOT_UID) {
19754            return;
19755        }
19756
19757        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
19758                Settings.getPackageNameForUid(mContext, uid), false)) {
19759            return;
19760        }
19761
19762        String msg = "Permission Denial: " + func + " from pid="
19763                + Binder.getCallingPid()
19764                + ", uid=" + uid
19765                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
19766        Slog.w(TAG, msg);
19767        throw new SecurityException(msg);
19768    }
19769
19770    @Override
19771    public boolean updateConfiguration(Configuration values) {
19772        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19773
19774        synchronized(this) {
19775            if (values == null && mWindowManager != null) {
19776                // sentinel: fetch the current configuration from the window manager
19777                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19778            }
19779
19780            if (mWindowManager != null) {
19781                // Update OOM levels based on display size.
19782                mProcessList.applyDisplaySize(mWindowManager);
19783            }
19784
19785            final long origId = Binder.clearCallingIdentity();
19786            try {
19787                if (values != null) {
19788                    Settings.System.clearConfiguration(values);
19789                }
19790                updateConfigurationLocked(values, null, false, false /* persistent */,
19791                        UserHandle.USER_NULL, false /* deferResume */,
19792                        mTmpUpdateConfigurationResult);
19793                return mTmpUpdateConfigurationResult.changes != 0;
19794            } finally {
19795                Binder.restoreCallingIdentity(origId);
19796            }
19797        }
19798    }
19799
19800    void updateUserConfigurationLocked() {
19801        final Configuration configuration = new Configuration(getGlobalConfiguration());
19802        final int currentUserId = mUserController.getCurrentUserIdLocked();
19803        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
19804                currentUserId, Settings.System.canWrite(mContext));
19805        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
19806                false /* persistent */, currentUserId, false /* deferResume */);
19807    }
19808
19809    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19810            boolean initLocale) {
19811        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19812    }
19813
19814    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19815            boolean initLocale, boolean deferResume) {
19816        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19817        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19818                UserHandle.USER_NULL, deferResume);
19819    }
19820
19821    // To cache the list of supported system locales
19822    private String[] mSupportedSystemLocales = null;
19823
19824    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19825            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19826        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
19827                deferResume, null /* result */);
19828    }
19829
19830    /**
19831     * Do either or both things: (1) change the current configuration, and (2)
19832     * make sure the given activity is running with the (now) current
19833     * configuration.  Returns true if the activity has been left running, or
19834     * false if <var>starting</var> is being destroyed to match the new
19835     * configuration.
19836     *
19837     * @param userId is only used when persistent parameter is set to true to persist configuration
19838     *               for that particular user
19839     */
19840    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19841            boolean initLocale, boolean persistent, int userId, boolean deferResume,
19842            UpdateConfigurationResult result) {
19843        int changes = 0;
19844        boolean kept = true;
19845
19846        if (mWindowManager != null) {
19847            mWindowManager.deferSurfaceLayout();
19848        }
19849        try {
19850            if (values != null) {
19851                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
19852                        deferResume);
19853            }
19854
19855            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19856        } finally {
19857            if (mWindowManager != null) {
19858                mWindowManager.continueSurfaceLayout();
19859            }
19860        }
19861
19862        if (result != null) {
19863            result.changes = changes;
19864            result.activityRelaunched = !kept;
19865        }
19866        return kept;
19867    }
19868
19869    /** Update default (global) configuration and notify listeners about changes. */
19870    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
19871            boolean persistent, int userId, boolean deferResume) {
19872        mTempConfig.setTo(getGlobalConfiguration());
19873        final int changes = mTempConfig.updateFrom(values);
19874        if (changes == 0) {
19875            return 0;
19876        }
19877
19878        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19879                "Updating global configuration to: " + values);
19880
19881        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19882
19883        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19884            final LocaleList locales = values.getLocales();
19885            int bestLocaleIndex = 0;
19886            if (locales.size() > 1) {
19887                if (mSupportedSystemLocales == null) {
19888                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
19889                }
19890                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
19891            }
19892            SystemProperties.set("persist.sys.locale",
19893                    locales.get(bestLocaleIndex).toLanguageTag());
19894            LocaleList.setDefault(locales, bestLocaleIndex);
19895            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19896                    locales.get(bestLocaleIndex)));
19897        }
19898
19899        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
19900        mTempConfig.seq = mConfigurationSeq;
19901
19902        // Update stored global config and notify everyone about the change.
19903        mStackSupervisor.onConfigurationChanged(mTempConfig);
19904
19905        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
19906        // TODO(multi-display): Update UsageEvents#Event to include displayId.
19907        mUsageStatsService.reportConfigurationChange(mTempConfig,
19908                mUserController.getCurrentUserIdLocked());
19909
19910        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
19911        mShowDialogs = shouldShowDialogs(mTempConfig, mVrState != NON_VR_MODE);
19912
19913        AttributeCache ac = AttributeCache.instance();
19914        if (ac != null) {
19915            ac.updateConfiguration(mTempConfig);
19916        }
19917
19918        // Make sure all resources in our process are updated right now, so that anyone who is going
19919        // to retrieve resource values after we return will be sure to get the new ones. This is
19920        // especially important during boot, where the first config change needs to guarantee all
19921        // resources have that config before following boot code is executed.
19922        mSystemThread.applyConfigurationToResources(mTempConfig);
19923
19924        // We need another copy of global config because we're scheduling some calls instead of
19925        // running them in place. We need to be sure that object we send will be handled unchanged.
19926        final Configuration configCopy = new Configuration(mTempConfig);
19927        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19928            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19929            msg.obj = configCopy;
19930            msg.arg1 = userId;
19931            mHandler.sendMessage(msg);
19932        }
19933
19934        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19935            ProcessRecord app = mLruProcesses.get(i);
19936            try {
19937                if (app.thread != null) {
19938                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19939                            + app.processName + " new config " + configCopy);
19940                    app.thread.scheduleConfigurationChanged(configCopy);
19941                }
19942            } catch (Exception e) {
19943            }
19944        }
19945
19946        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19947        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
19948                | Intent.FLAG_RECEIVER_FOREGROUND
19949                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19950        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19951                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19952                UserHandle.USER_ALL);
19953        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
19954            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19955            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
19956                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
19957                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19958            if (initLocale || !mProcessesReady) {
19959                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19960            }
19961            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19962                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19963                    UserHandle.USER_ALL);
19964        }
19965
19966        // Override configuration of the default display duplicates global config, so we need to
19967        // update it also. This will also notify WindowManager about changes.
19968        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
19969                DEFAULT_DISPLAY);
19970
19971        return changes;
19972    }
19973
19974    @Override
19975    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
19976        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
19977
19978        synchronized (this) {
19979            // Check if display is initialized in AM.
19980            if (!mStackSupervisor.isDisplayAdded(displayId)) {
19981                // Call might come when display is not yet added or has already been removed.
19982                if (DEBUG_CONFIGURATION) {
19983                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
19984                            + displayId);
19985                }
19986                return false;
19987            }
19988
19989            if (values == null && mWindowManager != null) {
19990                // sentinel: fetch the current configuration from the window manager
19991                values = mWindowManager.computeNewConfiguration(displayId);
19992            }
19993
19994            if (mWindowManager != null) {
19995                // Update OOM levels based on display size.
19996                mProcessList.applyDisplaySize(mWindowManager);
19997            }
19998
19999            final long origId = Binder.clearCallingIdentity();
20000            try {
20001                if (values != null) {
20002                    Settings.System.clearConfiguration(values);
20003                }
20004                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20005                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20006                return mTmpUpdateConfigurationResult.changes != 0;
20007            } finally {
20008                Binder.restoreCallingIdentity(origId);
20009            }
20010        }
20011    }
20012
20013    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20014            boolean deferResume, int displayId) {
20015        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20016                displayId, null /* result */);
20017    }
20018
20019    /**
20020     * Updates override configuration specific for the selected display. If no config is provided,
20021     * new one will be computed in WM based on current display info.
20022     */
20023    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20024            ActivityRecord starting, boolean deferResume, int displayId,
20025            UpdateConfigurationResult result) {
20026        int changes = 0;
20027        boolean kept = true;
20028
20029        if (mWindowManager != null) {
20030            mWindowManager.deferSurfaceLayout();
20031        }
20032        try {
20033            if (values != null) {
20034                if (displayId == DEFAULT_DISPLAY) {
20035                    // Override configuration of the default display duplicates global config, so
20036                    // we're calling global config update instead for default display. It will also
20037                    // apply the correct override config.
20038                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20039                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20040                } else {
20041                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20042                }
20043            }
20044
20045            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20046        } finally {
20047            if (mWindowManager != null) {
20048                mWindowManager.continueSurfaceLayout();
20049            }
20050        }
20051
20052        if (result != null) {
20053            result.changes = changes;
20054            result.activityRelaunched = !kept;
20055        }
20056        return kept;
20057    }
20058
20059    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20060            int displayId) {
20061        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20062        final int changes = mTempConfig.updateFrom(values);
20063        if (changes == 0) {
20064            return 0;
20065        }
20066
20067        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
20068                + " for displayId=" + displayId);
20069        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20070
20071        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20072        if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20073            // Reset the unsupported display size dialog.
20074            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20075
20076            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20077        }
20078
20079        // Update the configuration with WM first and check if any of the stacks need to be resized
20080        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20081        // necessary. This way we don't need to relaunch again afterwards in
20082        // ensureActivityConfigurationLocked().
20083        if (mWindowManager != null) {
20084            final int[] resizedStacks =
20085                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20086            if (resizedStacks != null) {
20087                for (int stackId : resizedStacks) {
20088                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20089                }
20090            }
20091        }
20092
20093        return changes;
20094    }
20095
20096    /** Applies latest configuration and/or visibility updates if needed. */
20097    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20098        boolean kept = true;
20099        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20100        // mainStack is null during startup.
20101        if (mainStack != null) {
20102            if (changes != 0 && starting == null) {
20103                // If the configuration changed, and the caller is not already
20104                // in the process of starting an activity, then find the top
20105                // activity to check if its configuration needs to change.
20106                starting = mainStack.topRunningActivityLocked();
20107            }
20108
20109            if (starting != null) {
20110                kept = starting.ensureActivityConfigurationLocked(changes,
20111                        false /* preserveWindow */);
20112                // And we need to make sure at this point that all other activities
20113                // are made visible with the correct configuration.
20114                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20115                        !PRESERVE_WINDOWS);
20116            }
20117        }
20118
20119        return kept;
20120    }
20121
20122    /** Helper method that requests bounds from WM and applies them to stack. */
20123    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20124        final Rect newStackBounds = new Rect();
20125        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20126        mStackSupervisor.resizeStackLocked(
20127                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20128                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20129                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20130    }
20131
20132    /**
20133     * Decide based on the configuration whether we should show the ANR,
20134     * crash, etc dialogs.  The idea is that if there is no affordance to
20135     * press the on-screen buttons, or the user experience would be more
20136     * greatly impacted than the crash itself, we shouldn't show the dialog.
20137     *
20138     * A thought: SystemUI might also want to get told about this, the Power
20139     * dialog / global actions also might want different behaviors.
20140     */
20141    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
20142        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20143                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20144                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20145        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20146        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20147                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20148                && modeType != Configuration.UI_MODE_TYPE_TELEVISION);
20149        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
20150    }
20151
20152    @Override
20153    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20154        synchronized (this) {
20155            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20156            if (srec != null) {
20157                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20158            }
20159        }
20160        return false;
20161    }
20162
20163    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20164            Intent resultData) {
20165
20166        synchronized (this) {
20167            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20168            if (r != null) {
20169                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20170            }
20171            return false;
20172        }
20173    }
20174
20175    public int getLaunchedFromUid(IBinder activityToken) {
20176        ActivityRecord srec;
20177        synchronized (this) {
20178            srec = ActivityRecord.forTokenLocked(activityToken);
20179        }
20180        if (srec == null) {
20181            return -1;
20182        }
20183        return srec.launchedFromUid;
20184    }
20185
20186    public String getLaunchedFromPackage(IBinder activityToken) {
20187        ActivityRecord srec;
20188        synchronized (this) {
20189            srec = ActivityRecord.forTokenLocked(activityToken);
20190        }
20191        if (srec == null) {
20192            return null;
20193        }
20194        return srec.launchedFromPackage;
20195    }
20196
20197    // =========================================================
20198    // LIFETIME MANAGEMENT
20199    // =========================================================
20200
20201    // Returns whether the app is receiving broadcast.
20202    // If receiving, fetch all broadcast queues which the app is
20203    // the current [or imminent] receiver on.
20204    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20205            ArraySet<BroadcastQueue> receivingQueues) {
20206        if (!app.curReceivers.isEmpty()) {
20207            for (BroadcastRecord r : app.curReceivers) {
20208                receivingQueues.add(r.queue);
20209            }
20210            return true;
20211        }
20212
20213        // It's not the current receiver, but it might be starting up to become one
20214        for (BroadcastQueue queue : mBroadcastQueues) {
20215            final BroadcastRecord r = queue.mPendingBroadcast;
20216            if (r != null && r.curApp == app) {
20217                // found it; report which queue it's in
20218                receivingQueues.add(queue);
20219            }
20220        }
20221
20222        return !receivingQueues.isEmpty();
20223    }
20224
20225    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20226            int targetUid, ComponentName targetComponent, String targetProcess) {
20227        if (!mTrackingAssociations) {
20228            return null;
20229        }
20230        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20231                = mAssociations.get(targetUid);
20232        if (components == null) {
20233            components = new ArrayMap<>();
20234            mAssociations.put(targetUid, components);
20235        }
20236        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20237        if (sourceUids == null) {
20238            sourceUids = new SparseArray<>();
20239            components.put(targetComponent, sourceUids);
20240        }
20241        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20242        if (sourceProcesses == null) {
20243            sourceProcesses = new ArrayMap<>();
20244            sourceUids.put(sourceUid, sourceProcesses);
20245        }
20246        Association ass = sourceProcesses.get(sourceProcess);
20247        if (ass == null) {
20248            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20249                    targetProcess);
20250            sourceProcesses.put(sourceProcess, ass);
20251        }
20252        ass.mCount++;
20253        ass.mNesting++;
20254        if (ass.mNesting == 1) {
20255            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20256            ass.mLastState = sourceState;
20257        }
20258        return ass;
20259    }
20260
20261    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20262            ComponentName targetComponent) {
20263        if (!mTrackingAssociations) {
20264            return;
20265        }
20266        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20267                = mAssociations.get(targetUid);
20268        if (components == null) {
20269            return;
20270        }
20271        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20272        if (sourceUids == null) {
20273            return;
20274        }
20275        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20276        if (sourceProcesses == null) {
20277            return;
20278        }
20279        Association ass = sourceProcesses.get(sourceProcess);
20280        if (ass == null || ass.mNesting <= 0) {
20281            return;
20282        }
20283        ass.mNesting--;
20284        if (ass.mNesting == 0) {
20285            long uptime = SystemClock.uptimeMillis();
20286            ass.mTime += uptime - ass.mStartTime;
20287            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20288                    += uptime - ass.mLastStateUptime;
20289            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20290        }
20291    }
20292
20293    private void noteUidProcessState(final int uid, final int state) {
20294        mBatteryStatsService.noteUidProcessState(uid, state);
20295        if (mTrackingAssociations) {
20296            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20297                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20298                        = mAssociations.valueAt(i1);
20299                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20300                    SparseArray<ArrayMap<String, Association>> sourceUids
20301                            = targetComponents.valueAt(i2);
20302                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20303                    if (sourceProcesses != null) {
20304                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20305                            Association ass = sourceProcesses.valueAt(i4);
20306                            if (ass.mNesting >= 1) {
20307                                // currently associated
20308                                long uptime = SystemClock.uptimeMillis();
20309                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20310                                        += uptime - ass.mLastStateUptime;
20311                                ass.mLastState = state;
20312                                ass.mLastStateUptime = uptime;
20313                            }
20314                        }
20315                    }
20316                }
20317            }
20318        }
20319    }
20320
20321    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20322            boolean doingAll, long now) {
20323        if (mAdjSeq == app.adjSeq) {
20324            // This adjustment has already been computed.
20325            return app.curRawAdj;
20326        }
20327
20328        if (app.thread == null) {
20329            app.adjSeq = mAdjSeq;
20330            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20331            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20332            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20333        }
20334
20335        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20336        app.adjSource = null;
20337        app.adjTarget = null;
20338        app.empty = false;
20339        app.cached = false;
20340
20341        final int activitiesSize = app.activities.size();
20342
20343        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20344            // The max adjustment doesn't allow this app to be anything
20345            // below foreground, so it is not worth doing work for it.
20346            app.adjType = "fixed";
20347            app.adjSeq = mAdjSeq;
20348            app.curRawAdj = app.maxAdj;
20349            app.foregroundActivities = false;
20350            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20351            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20352            // System processes can do UI, and when they do we want to have
20353            // them trim their memory after the user leaves the UI.  To
20354            // facilitate this, here we need to determine whether or not it
20355            // is currently showing UI.
20356            app.systemNoUi = true;
20357            if (app == TOP_APP) {
20358                app.systemNoUi = false;
20359                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20360                app.adjType = "pers-top-activity";
20361            } else if (app.hasTopUi) {
20362                app.systemNoUi = false;
20363                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20364                app.adjType = "pers-top-ui";
20365            } else if (activitiesSize > 0) {
20366                for (int j = 0; j < activitiesSize; j++) {
20367                    final ActivityRecord r = app.activities.get(j);
20368                    if (r.visible) {
20369                        app.systemNoUi = false;
20370                    }
20371                }
20372            }
20373            if (!app.systemNoUi) {
20374                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20375            }
20376            return (app.curAdj=app.maxAdj);
20377        }
20378
20379        app.systemNoUi = false;
20380
20381        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20382
20383        // Determine the importance of the process, starting with most
20384        // important to least, and assign an appropriate OOM adjustment.
20385        int adj;
20386        int schedGroup;
20387        int procState;
20388        boolean foregroundActivities = false;
20389        mTmpBroadcastQueue.clear();
20390        if (app == TOP_APP) {
20391            // The last app on the list is the foreground app.
20392            adj = ProcessList.FOREGROUND_APP_ADJ;
20393            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20394            app.adjType = "top-activity";
20395            foregroundActivities = true;
20396            procState = PROCESS_STATE_CUR_TOP;
20397        } else if (app.instr != null) {
20398            // Don't want to kill running instrumentation.
20399            adj = ProcessList.FOREGROUND_APP_ADJ;
20400            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20401            app.adjType = "instrumentation";
20402            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20403        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20404            // An app that is currently receiving a broadcast also
20405            // counts as being in the foreground for OOM killer purposes.
20406            // It's placed in a sched group based on the nature of the
20407            // broadcast as reflected by which queue it's active in.
20408            adj = ProcessList.FOREGROUND_APP_ADJ;
20409            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20410                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20411            app.adjType = "broadcast";
20412            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20413        } else if (app.executingServices.size() > 0) {
20414            // An app that is currently executing a service callback also
20415            // counts as being in the foreground.
20416            adj = ProcessList.FOREGROUND_APP_ADJ;
20417            schedGroup = app.execServicesFg ?
20418                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20419            app.adjType = "exec-service";
20420            procState = ActivityManager.PROCESS_STATE_SERVICE;
20421            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20422        } else {
20423            // As far as we know the process is empty.  We may change our mind later.
20424            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20425            // At this point we don't actually know the adjustment.  Use the cached adj
20426            // value that the caller wants us to.
20427            adj = cachedAdj;
20428            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20429            app.cached = true;
20430            app.empty = true;
20431            app.adjType = "cch-empty";
20432        }
20433
20434        // Examine all activities if not already foreground.
20435        if (!foregroundActivities && activitiesSize > 0) {
20436            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20437            for (int j = 0; j < activitiesSize; j++) {
20438                final ActivityRecord r = app.activities.get(j);
20439                if (r.app != app) {
20440                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20441                            + " instead of expected " + app);
20442                    if (r.app == null || (r.app.uid == app.uid)) {
20443                        // Only fix things up when they look sane
20444                        r.app = app;
20445                    } else {
20446                        continue;
20447                    }
20448                }
20449                if (r.visible) {
20450                    // App has a visible activity; only upgrade adjustment.
20451                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20452                        adj = ProcessList.VISIBLE_APP_ADJ;
20453                        app.adjType = "visible";
20454                    }
20455                    if (procState > PROCESS_STATE_CUR_TOP) {
20456                        procState = PROCESS_STATE_CUR_TOP;
20457                    }
20458                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20459                    app.cached = false;
20460                    app.empty = false;
20461                    foregroundActivities = true;
20462                    if (r.task != null && minLayer > 0) {
20463                        final int layer = r.task.mLayerRank;
20464                        if (layer >= 0 && minLayer > layer) {
20465                            minLayer = layer;
20466                        }
20467                    }
20468                    break;
20469                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20470                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20471                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20472                        app.adjType = "pausing";
20473                    }
20474                    if (procState > PROCESS_STATE_CUR_TOP) {
20475                        procState = PROCESS_STATE_CUR_TOP;
20476                    }
20477                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20478                    app.cached = false;
20479                    app.empty = false;
20480                    foregroundActivities = true;
20481                } else if (r.state == ActivityState.STOPPING) {
20482                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20483                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20484                        app.adjType = "stopping";
20485                    }
20486                    // For the process state, we will at this point consider the
20487                    // process to be cached.  It will be cached either as an activity
20488                    // or empty depending on whether the activity is finishing.  We do
20489                    // this so that we can treat the process as cached for purposes of
20490                    // memory trimming (determing current memory level, trim command to
20491                    // send to process) since there can be an arbitrary number of stopping
20492                    // processes and they should soon all go into the cached state.
20493                    if (!r.finishing) {
20494                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20495                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20496                        }
20497                    }
20498                    app.cached = false;
20499                    app.empty = false;
20500                    foregroundActivities = true;
20501                } else {
20502                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20503                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20504                        app.adjType = "cch-act";
20505                    }
20506                }
20507            }
20508            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20509                adj += minLayer;
20510            }
20511        }
20512
20513        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20514                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20515            if (app.foregroundServices) {
20516                // The user is aware of this app, so make it visible.
20517                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20518                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20519                app.cached = false;
20520                app.adjType = "fg-service";
20521                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20522            } else if (app.forcingToForeground != null) {
20523                // The user is aware of this app, so make it visible.
20524                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20525                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20526                app.cached = false;
20527                app.adjType = "force-fg";
20528                app.adjSource = app.forcingToForeground;
20529                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20530            } else if (app.hasOverlayUi) {
20531                // The process is display an overlay UI.
20532                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20533                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20534                app.cached = false;
20535                app.adjType = "has-overlay-ui";
20536                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20537            }
20538        }
20539
20540        if (app == mHeavyWeightProcess) {
20541            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20542                // We don't want to kill the current heavy-weight process.
20543                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20544                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20545                app.cached = false;
20546                app.adjType = "heavy";
20547            }
20548            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20549                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
20550            }
20551        }
20552
20553        if (app == mHomeProcess) {
20554            if (adj > ProcessList.HOME_APP_ADJ) {
20555                // This process is hosting what we currently consider to be the
20556                // home app, so we don't want to let it go into the background.
20557                adj = ProcessList.HOME_APP_ADJ;
20558                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20559                app.cached = false;
20560                app.adjType = "home";
20561            }
20562            if (procState > ActivityManager.PROCESS_STATE_HOME) {
20563                procState = ActivityManager.PROCESS_STATE_HOME;
20564            }
20565        }
20566
20567        if (app == mPreviousProcess && app.activities.size() > 0) {
20568            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20569                // This was the previous process that showed UI to the user.
20570                // We want to try to keep it around more aggressively, to give
20571                // a good experience around switching between two apps.
20572                adj = ProcessList.PREVIOUS_APP_ADJ;
20573                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20574                app.cached = false;
20575                app.adjType = "previous";
20576            }
20577            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20578                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20579            }
20580        }
20581
20582        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
20583                + " reason=" + app.adjType);
20584
20585        // By default, we use the computed adjustment.  It may be changed if
20586        // there are applications dependent on our services or providers, but
20587        // this gives us a baseline and makes sure we don't get into an
20588        // infinite recursion.
20589        app.adjSeq = mAdjSeq;
20590        app.curRawAdj = adj;
20591        app.hasStartedServices = false;
20592
20593        if (mBackupTarget != null && app == mBackupTarget.app) {
20594            // If possible we want to avoid killing apps while they're being backed up
20595            if (adj > ProcessList.BACKUP_APP_ADJ) {
20596                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
20597                adj = ProcessList.BACKUP_APP_ADJ;
20598                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20599                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20600                }
20601                app.adjType = "backup";
20602                app.cached = false;
20603            }
20604            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
20605                procState = ActivityManager.PROCESS_STATE_BACKUP;
20606            }
20607        }
20608
20609        boolean mayBeTop = false;
20610
20611        for (int is = app.services.size()-1;
20612                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20613                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20614                        || procState > ActivityManager.PROCESS_STATE_TOP);
20615                is--) {
20616            ServiceRecord s = app.services.valueAt(is);
20617            if (s.startRequested) {
20618                app.hasStartedServices = true;
20619                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
20620                    procState = ActivityManager.PROCESS_STATE_SERVICE;
20621                }
20622                if (app.hasShownUi && app != mHomeProcess) {
20623                    // If this process has shown some UI, let it immediately
20624                    // go to the LRU list because it may be pretty heavy with
20625                    // UI stuff.  We'll tag it with a label just to help
20626                    // debug and understand what is going on.
20627                    if (adj > ProcessList.SERVICE_ADJ) {
20628                        app.adjType = "cch-started-ui-services";
20629                    }
20630                } else {
20631                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20632                        // This service has seen some activity within
20633                        // recent memory, so we will keep its process ahead
20634                        // of the background processes.
20635                        if (adj > ProcessList.SERVICE_ADJ) {
20636                            adj = ProcessList.SERVICE_ADJ;
20637                            app.adjType = "started-services";
20638                            app.cached = false;
20639                        }
20640                    }
20641                    // If we have let the service slide into the background
20642                    // state, still have some text describing what it is doing
20643                    // even though the service no longer has an impact.
20644                    if (adj > ProcessList.SERVICE_ADJ) {
20645                        app.adjType = "cch-started-services";
20646                    }
20647                }
20648            }
20649
20650            for (int conni = s.connections.size()-1;
20651                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20652                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20653                            || procState > ActivityManager.PROCESS_STATE_TOP);
20654                    conni--) {
20655                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
20656                for (int i = 0;
20657                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
20658                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20659                                || procState > ActivityManager.PROCESS_STATE_TOP);
20660                        i++) {
20661                    // XXX should compute this based on the max of
20662                    // all connected clients.
20663                    ConnectionRecord cr = clist.get(i);
20664                    if (cr.binding.client == app) {
20665                        // Binding to ourself is not interesting.
20666                        continue;
20667                    }
20668
20669                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
20670                        ProcessRecord client = cr.binding.client;
20671                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
20672                                TOP_APP, doingAll, now);
20673                        int clientProcState = client.curProcState;
20674                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20675                            // If the other app is cached for any reason, for purposes here
20676                            // we are going to consider it empty.  The specific cached state
20677                            // doesn't propagate except under certain conditions.
20678                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20679                        }
20680                        String adjType = null;
20681                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
20682                            // Not doing bind OOM management, so treat
20683                            // this guy more like a started service.
20684                            if (app.hasShownUi && app != mHomeProcess) {
20685                                // If this process has shown some UI, let it immediately
20686                                // go to the LRU list because it may be pretty heavy with
20687                                // UI stuff.  We'll tag it with a label just to help
20688                                // debug and understand what is going on.
20689                                if (adj > clientAdj) {
20690                                    adjType = "cch-bound-ui-services";
20691                                }
20692                                app.cached = false;
20693                                clientAdj = adj;
20694                                clientProcState = procState;
20695                            } else {
20696                                if (now >= (s.lastActivity
20697                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20698                                    // This service has not seen activity within
20699                                    // recent memory, so allow it to drop to the
20700                                    // LRU list if there is no other reason to keep
20701                                    // it around.  We'll also tag it with a label just
20702                                    // to help debug and undertand what is going on.
20703                                    if (adj > clientAdj) {
20704                                        adjType = "cch-bound-services";
20705                                    }
20706                                    clientAdj = adj;
20707                                }
20708                            }
20709                        }
20710                        if (adj > clientAdj) {
20711                            // If this process has recently shown UI, and
20712                            // the process that is binding to it is less
20713                            // important than being visible, then we don't
20714                            // care about the binding as much as we care
20715                            // about letting this process get into the LRU
20716                            // list to be killed and restarted if needed for
20717                            // memory.
20718                            if (app.hasShownUi && app != mHomeProcess
20719                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20720                                adjType = "cch-bound-ui-services";
20721                            } else {
20722                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
20723                                        |Context.BIND_IMPORTANT)) != 0) {
20724                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
20725                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
20726                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
20727                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
20728                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20729                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20730                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
20731                                    adj = clientAdj;
20732                                } else {
20733                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20734                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
20735                                    }
20736                                }
20737                                if (!client.cached) {
20738                                    app.cached = false;
20739                                }
20740                                adjType = "service";
20741                            }
20742                        }
20743                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20744                            // This will treat important bound services identically to
20745                            // the top app, which may behave differently than generic
20746                            // foreground work.
20747                            if (client.curSchedGroup > schedGroup) {
20748                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20749                                    schedGroup = client.curSchedGroup;
20750                                } else {
20751                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20752                                }
20753                            }
20754                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20755                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20756                                    // Special handling of clients who are in the top state.
20757                                    // We *may* want to consider this process to be in the
20758                                    // top state as well, but only if there is not another
20759                                    // reason for it to be running.  Being on the top is a
20760                                    // special state, meaning you are specifically running
20761                                    // for the current top app.  If the process is already
20762                                    // running in the background for some other reason, it
20763                                    // is more important to continue considering it to be
20764                                    // in the background state.
20765                                    mayBeTop = true;
20766                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20767                                } else {
20768                                    // Special handling for above-top states (persistent
20769                                    // processes).  These should not bring the current process
20770                                    // into the top state, since they are not on top.  Instead
20771                                    // give them the best state after that.
20772                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
20773                                        clientProcState =
20774                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20775                                    } else if (mWakefulness
20776                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
20777                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
20778                                                    != 0) {
20779                                        clientProcState =
20780                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20781                                    } else {
20782                                        clientProcState =
20783                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20784                                    }
20785                                }
20786                            }
20787                        } else {
20788                            if (clientProcState <
20789                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20790                                clientProcState =
20791                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20792                            }
20793                        }
20794                        if (procState > clientProcState) {
20795                            procState = clientProcState;
20796                        }
20797                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20798                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
20799                            app.pendingUiClean = true;
20800                        }
20801                        if (adjType != null) {
20802                            app.adjType = adjType;
20803                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20804                                    .REASON_SERVICE_IN_USE;
20805                            app.adjSource = cr.binding.client;
20806                            app.adjSourceProcState = clientProcState;
20807                            app.adjTarget = s.name;
20808                        }
20809                    }
20810                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
20811                        app.treatLikeActivity = true;
20812                    }
20813                    final ActivityRecord a = cr.activity;
20814                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
20815                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
20816                            (a.visible || a.state == ActivityState.RESUMED ||
20817                             a.state == ActivityState.PAUSING)) {
20818                            adj = ProcessList.FOREGROUND_APP_ADJ;
20819                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20820                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20821                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
20822                                } else {
20823                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20824                                }
20825                            }
20826                            app.cached = false;
20827                            app.adjType = "service";
20828                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20829                                    .REASON_SERVICE_IN_USE;
20830                            app.adjSource = a;
20831                            app.adjSourceProcState = procState;
20832                            app.adjTarget = s.name;
20833                        }
20834                    }
20835                }
20836            }
20837        }
20838
20839        for (int provi = app.pubProviders.size()-1;
20840                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20841                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20842                        || procState > ActivityManager.PROCESS_STATE_TOP);
20843                provi--) {
20844            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
20845            for (int i = cpr.connections.size()-1;
20846                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20847                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20848                            || procState > ActivityManager.PROCESS_STATE_TOP);
20849                    i--) {
20850                ContentProviderConnection conn = cpr.connections.get(i);
20851                ProcessRecord client = conn.client;
20852                if (client == app) {
20853                    // Being our own client is not interesting.
20854                    continue;
20855                }
20856                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
20857                int clientProcState = client.curProcState;
20858                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20859                    // If the other app is cached for any reason, for purposes here
20860                    // we are going to consider it empty.
20861                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20862                }
20863                if (adj > clientAdj) {
20864                    if (app.hasShownUi && app != mHomeProcess
20865                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20866                        app.adjType = "cch-ui-provider";
20867                    } else {
20868                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
20869                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
20870                        app.adjType = "provider";
20871                    }
20872                    app.cached &= client.cached;
20873                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20874                            .REASON_PROVIDER_IN_USE;
20875                    app.adjSource = client;
20876                    app.adjSourceProcState = clientProcState;
20877                    app.adjTarget = cpr.name;
20878                }
20879                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20880                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20881                        // Special handling of clients who are in the top state.
20882                        // We *may* want to consider this process to be in the
20883                        // top state as well, but only if there is not another
20884                        // reason for it to be running.  Being on the top is a
20885                        // special state, meaning you are specifically running
20886                        // for the current top app.  If the process is already
20887                        // running in the background for some other reason, it
20888                        // is more important to continue considering it to be
20889                        // in the background state.
20890                        mayBeTop = true;
20891                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20892                    } else {
20893                        // Special handling for above-top states (persistent
20894                        // processes).  These should not bring the current process
20895                        // into the top state, since they are not on top.  Instead
20896                        // give them the best state after that.
20897                        clientProcState =
20898                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20899                    }
20900                }
20901                if (procState > clientProcState) {
20902                    procState = clientProcState;
20903                }
20904                if (client.curSchedGroup > schedGroup) {
20905                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20906                }
20907            }
20908            // If the provider has external (non-framework) process
20909            // dependencies, ensure that its adjustment is at least
20910            // FOREGROUND_APP_ADJ.
20911            if (cpr.hasExternalProcessHandles()) {
20912                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
20913                    adj = ProcessList.FOREGROUND_APP_ADJ;
20914                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20915                    app.cached = false;
20916                    app.adjType = "provider";
20917                    app.adjTarget = cpr.name;
20918                }
20919                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20920                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20921                }
20922            }
20923        }
20924
20925        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
20926            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20927                adj = ProcessList.PREVIOUS_APP_ADJ;
20928                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20929                app.cached = false;
20930                app.adjType = "provider";
20931            }
20932            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20933                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20934            }
20935        }
20936
20937        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
20938            // A client of one of our services or providers is in the top state.  We
20939            // *may* want to be in the top state, but not if we are already running in
20940            // the background for some other reason.  For the decision here, we are going
20941            // to pick out a few specific states that we want to remain in when a client
20942            // is top (states that tend to be longer-term) and otherwise allow it to go
20943            // to the top state.
20944            switch (procState) {
20945                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
20946                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
20947                case ActivityManager.PROCESS_STATE_SERVICE:
20948                    // These all are longer-term states, so pull them up to the top
20949                    // of the background states, but not all the way to the top state.
20950                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20951                    break;
20952                default:
20953                    // Otherwise, top is a better choice, so take it.
20954                    procState = ActivityManager.PROCESS_STATE_TOP;
20955                    break;
20956            }
20957        }
20958
20959        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
20960            if (app.hasClientActivities) {
20961                // This is a cached process, but with client activities.  Mark it so.
20962                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
20963                app.adjType = "cch-client-act";
20964            } else if (app.treatLikeActivity) {
20965                // This is a cached process, but somebody wants us to treat it like it has
20966                // an activity, okay!
20967                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20968                app.adjType = "cch-as-act";
20969            }
20970        }
20971
20972        if (adj == ProcessList.SERVICE_ADJ) {
20973            if (doingAll) {
20974                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20975                mNewNumServiceProcs++;
20976                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20977                if (!app.serviceb) {
20978                    // This service isn't far enough down on the LRU list to
20979                    // normally be a B service, but if we are low on RAM and it
20980                    // is large we want to force it down since we would prefer to
20981                    // keep launcher over it.
20982                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20983                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20984                        app.serviceHighRam = true;
20985                        app.serviceb = true;
20986                        //Slog.i(TAG, "ADJ " + app + " high ram!");
20987                    } else {
20988                        mNewNumAServiceProcs++;
20989                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
20990                    }
20991                } else {
20992                    app.serviceHighRam = false;
20993                }
20994            }
20995            if (app.serviceb) {
20996                adj = ProcessList.SERVICE_B_ADJ;
20997            }
20998        }
20999
21000        app.curRawAdj = adj;
21001
21002        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21003        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21004        if (adj > app.maxAdj) {
21005            adj = app.maxAdj;
21006            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21007                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21008            }
21009        }
21010
21011        // Do final modification to adj.  Everything we do between here and applying
21012        // the final setAdj must be done in this function, because we will also use
21013        // it when computing the final cached adj later.  Note that we don't need to
21014        // worry about this for max adj above, since max adj will always be used to
21015        // keep it out of the cached vaues.
21016        app.curAdj = app.modifyRawOomAdj(adj);
21017        app.curSchedGroup = schedGroup;
21018        app.curProcState = procState;
21019        app.foregroundActivities = foregroundActivities;
21020
21021        return app.curRawAdj;
21022    }
21023
21024    /**
21025     * Record new PSS sample for a process.
21026     */
21027    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21028            long now) {
21029        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21030                swapPss * 1024);
21031        proc.lastPssTime = now;
21032        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21033        if (DEBUG_PSS) Slog.d(TAG_PSS,
21034                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21035                + " state=" + ProcessList.makeProcStateString(procState));
21036        if (proc.initialIdlePss == 0) {
21037            proc.initialIdlePss = pss;
21038        }
21039        proc.lastPss = pss;
21040        proc.lastSwapPss = swapPss;
21041        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21042            proc.lastCachedPss = pss;
21043            proc.lastCachedSwapPss = swapPss;
21044        }
21045
21046        final SparseArray<Pair<Long, String>> watchUids
21047                = mMemWatchProcesses.getMap().get(proc.processName);
21048        Long check = null;
21049        if (watchUids != null) {
21050            Pair<Long, String> val = watchUids.get(proc.uid);
21051            if (val == null) {
21052                val = watchUids.get(0);
21053            }
21054            if (val != null) {
21055                check = val.first;
21056            }
21057        }
21058        if (check != null) {
21059            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21060                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21061                if (!isDebuggable) {
21062                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21063                        isDebuggable = true;
21064                    }
21065                }
21066                if (isDebuggable) {
21067                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21068                    final ProcessRecord myProc = proc;
21069                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21070                    mMemWatchDumpProcName = proc.processName;
21071                    mMemWatchDumpFile = heapdumpFile.toString();
21072                    mMemWatchDumpPid = proc.pid;
21073                    mMemWatchDumpUid = proc.uid;
21074                    BackgroundThread.getHandler().post(new Runnable() {
21075                        @Override
21076                        public void run() {
21077                            revokeUriPermission(ActivityThread.currentActivityThread()
21078                                            .getApplicationThread(),
21079                                    DumpHeapActivity.JAVA_URI,
21080                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21081                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21082                                    UserHandle.myUserId());
21083                            ParcelFileDescriptor fd = null;
21084                            try {
21085                                heapdumpFile.delete();
21086                                fd = ParcelFileDescriptor.open(heapdumpFile,
21087                                        ParcelFileDescriptor.MODE_CREATE |
21088                                                ParcelFileDescriptor.MODE_TRUNCATE |
21089                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21090                                                ParcelFileDescriptor.MODE_APPEND);
21091                                IApplicationThread thread = myProc.thread;
21092                                if (thread != null) {
21093                                    try {
21094                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21095                                                "Requesting dump heap from "
21096                                                + myProc + " to " + heapdumpFile);
21097                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
21098                                    } catch (RemoteException e) {
21099                                    }
21100                                }
21101                            } catch (FileNotFoundException e) {
21102                                e.printStackTrace();
21103                            } finally {
21104                                if (fd != null) {
21105                                    try {
21106                                        fd.close();
21107                                    } catch (IOException e) {
21108                                    }
21109                                }
21110                            }
21111                        }
21112                    });
21113                } else {
21114                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21115                            + ", but debugging not enabled");
21116                }
21117            }
21118        }
21119    }
21120
21121    /**
21122     * Schedule PSS collection of a process.
21123     */
21124    void requestPssLocked(ProcessRecord proc, int procState) {
21125        if (mPendingPssProcesses.contains(proc)) {
21126            return;
21127        }
21128        if (mPendingPssProcesses.size() == 0) {
21129            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21130        }
21131        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21132        proc.pssProcState = procState;
21133        mPendingPssProcesses.add(proc);
21134    }
21135
21136    /**
21137     * Schedule PSS collection of all processes.
21138     */
21139    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21140        if (!always) {
21141            if (now < (mLastFullPssTime +
21142                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
21143                return;
21144            }
21145        }
21146        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21147        mLastFullPssTime = now;
21148        mFullPssPending = true;
21149        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21150        mPendingPssProcesses.clear();
21151        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21152            ProcessRecord app = mLruProcesses.get(i);
21153            if (app.thread == null
21154                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21155                continue;
21156            }
21157            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21158                app.pssProcState = app.setProcState;
21159                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21160                        mTestPssMode, isSleepingLocked(), now);
21161                mPendingPssProcesses.add(app);
21162            }
21163        }
21164        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21165    }
21166
21167    public void setTestPssMode(boolean enabled) {
21168        synchronized (this) {
21169            mTestPssMode = enabled;
21170            if (enabled) {
21171                // Whenever we enable the mode, we want to take a snapshot all of current
21172                // process mem use.
21173                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21174            }
21175        }
21176    }
21177
21178    /**
21179     * Ask a given process to GC right now.
21180     */
21181    final void performAppGcLocked(ProcessRecord app) {
21182        try {
21183            app.lastRequestedGc = SystemClock.uptimeMillis();
21184            if (app.thread != null) {
21185                if (app.reportLowMemory) {
21186                    app.reportLowMemory = false;
21187                    app.thread.scheduleLowMemory();
21188                } else {
21189                    app.thread.processInBackground();
21190                }
21191            }
21192        } catch (Exception e) {
21193            // whatever.
21194        }
21195    }
21196
21197    /**
21198     * Returns true if things are idle enough to perform GCs.
21199     */
21200    private final boolean canGcNowLocked() {
21201        boolean processingBroadcasts = false;
21202        for (BroadcastQueue q : mBroadcastQueues) {
21203            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21204                processingBroadcasts = true;
21205            }
21206        }
21207        return !processingBroadcasts
21208                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21209    }
21210
21211    /**
21212     * Perform GCs on all processes that are waiting for it, but only
21213     * if things are idle.
21214     */
21215    final void performAppGcsLocked() {
21216        final int N = mProcessesToGc.size();
21217        if (N <= 0) {
21218            return;
21219        }
21220        if (canGcNowLocked()) {
21221            while (mProcessesToGc.size() > 0) {
21222                ProcessRecord proc = mProcessesToGc.remove(0);
21223                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21224                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
21225                            <= SystemClock.uptimeMillis()) {
21226                        // To avoid spamming the system, we will GC processes one
21227                        // at a time, waiting a few seconds between each.
21228                        performAppGcLocked(proc);
21229                        scheduleAppGcsLocked();
21230                        return;
21231                    } else {
21232                        // It hasn't been long enough since we last GCed this
21233                        // process...  put it in the list to wait for its time.
21234                        addProcessToGcListLocked(proc);
21235                        break;
21236                    }
21237                }
21238            }
21239
21240            scheduleAppGcsLocked();
21241        }
21242    }
21243
21244    /**
21245     * If all looks good, perform GCs on all processes waiting for them.
21246     */
21247    final void performAppGcsIfAppropriateLocked() {
21248        if (canGcNowLocked()) {
21249            performAppGcsLocked();
21250            return;
21251        }
21252        // Still not idle, wait some more.
21253        scheduleAppGcsLocked();
21254    }
21255
21256    /**
21257     * Schedule the execution of all pending app GCs.
21258     */
21259    final void scheduleAppGcsLocked() {
21260        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21261
21262        if (mProcessesToGc.size() > 0) {
21263            // Schedule a GC for the time to the next process.
21264            ProcessRecord proc = mProcessesToGc.get(0);
21265            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21266
21267            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
21268            long now = SystemClock.uptimeMillis();
21269            if (when < (now+GC_TIMEOUT)) {
21270                when = now + GC_TIMEOUT;
21271            }
21272            mHandler.sendMessageAtTime(msg, when);
21273        }
21274    }
21275
21276    /**
21277     * Add a process to the array of processes waiting to be GCed.  Keeps the
21278     * list in sorted order by the last GC time.  The process can't already be
21279     * on the list.
21280     */
21281    final void addProcessToGcListLocked(ProcessRecord proc) {
21282        boolean added = false;
21283        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21284            if (mProcessesToGc.get(i).lastRequestedGc <
21285                    proc.lastRequestedGc) {
21286                added = true;
21287                mProcessesToGc.add(i+1, proc);
21288                break;
21289            }
21290        }
21291        if (!added) {
21292            mProcessesToGc.add(0, proc);
21293        }
21294    }
21295
21296    /**
21297     * Set up to ask a process to GC itself.  This will either do it
21298     * immediately, or put it on the list of processes to gc the next
21299     * time things are idle.
21300     */
21301    final void scheduleAppGcLocked(ProcessRecord app) {
21302        long now = SystemClock.uptimeMillis();
21303        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
21304            return;
21305        }
21306        if (!mProcessesToGc.contains(app)) {
21307            addProcessToGcListLocked(app);
21308            scheduleAppGcsLocked();
21309        }
21310    }
21311
21312    final void checkExcessivePowerUsageLocked(boolean doKills) {
21313        updateCpuStatsNow();
21314
21315        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21316        boolean doWakeKills = doKills;
21317        boolean doCpuKills = doKills;
21318        if (mLastPowerCheckRealtime == 0) {
21319            doWakeKills = false;
21320        }
21321        if (mLastPowerCheckUptime == 0) {
21322            doCpuKills = false;
21323        }
21324        if (stats.isScreenOn()) {
21325            doWakeKills = false;
21326        }
21327        final long curRealtime = SystemClock.elapsedRealtime();
21328        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21329        final long curUptime = SystemClock.uptimeMillis();
21330        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21331        mLastPowerCheckRealtime = curRealtime;
21332        mLastPowerCheckUptime = curUptime;
21333        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
21334            doWakeKills = false;
21335        }
21336        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
21337            doCpuKills = false;
21338        }
21339        int i = mLruProcesses.size();
21340        while (i > 0) {
21341            i--;
21342            ProcessRecord app = mLruProcesses.get(i);
21343            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21344                long wtime;
21345                synchronized (stats) {
21346                    wtime = stats.getProcessWakeTime(app.info.uid,
21347                            app.pid, curRealtime);
21348                }
21349                long wtimeUsed = wtime - app.lastWakeTime;
21350                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21351                if (DEBUG_POWER) {
21352                    StringBuilder sb = new StringBuilder(128);
21353                    sb.append("Wake for ");
21354                    app.toShortString(sb);
21355                    sb.append(": over ");
21356                    TimeUtils.formatDuration(realtimeSince, sb);
21357                    sb.append(" used ");
21358                    TimeUtils.formatDuration(wtimeUsed, sb);
21359                    sb.append(" (");
21360                    sb.append((wtimeUsed*100)/realtimeSince);
21361                    sb.append("%)");
21362                    Slog.i(TAG_POWER, sb.toString());
21363                    sb.setLength(0);
21364                    sb.append("CPU for ");
21365                    app.toShortString(sb);
21366                    sb.append(": over ");
21367                    TimeUtils.formatDuration(uptimeSince, sb);
21368                    sb.append(" used ");
21369                    TimeUtils.formatDuration(cputimeUsed, sb);
21370                    sb.append(" (");
21371                    sb.append((cputimeUsed*100)/uptimeSince);
21372                    sb.append("%)");
21373                    Slog.i(TAG_POWER, sb.toString());
21374                }
21375                // If a process has held a wake lock for more
21376                // than 50% of the time during this period,
21377                // that sounds bad.  Kill!
21378                if (doWakeKills && realtimeSince > 0
21379                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
21380                    synchronized (stats) {
21381                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21382                                realtimeSince, wtimeUsed);
21383                    }
21384                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21385                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21386                } else if (doCpuKills && uptimeSince > 0
21387                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
21388                    synchronized (stats) {
21389                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21390                                uptimeSince, cputimeUsed);
21391                    }
21392                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21393                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21394                } else {
21395                    app.lastWakeTime = wtime;
21396                    app.lastCpuTime = app.curCpuTime;
21397                }
21398            }
21399        }
21400    }
21401
21402    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21403            long nowElapsed) {
21404        boolean success = true;
21405
21406        if (app.curRawAdj != app.setRawAdj) {
21407            app.setRawAdj = app.curRawAdj;
21408        }
21409
21410        int changes = 0;
21411
21412        if (app.curAdj != app.setAdj) {
21413            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21414            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21415                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21416                    + app.adjType);
21417            app.setAdj = app.curAdj;
21418            app.verifiedAdj = ProcessList.INVALID_ADJ;
21419        }
21420
21421        if (app.setSchedGroup != app.curSchedGroup) {
21422            int oldSchedGroup = app.setSchedGroup;
21423            app.setSchedGroup = app.curSchedGroup;
21424            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21425                    "Setting sched group of " + app.processName
21426                    + " to " + app.curSchedGroup);
21427            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21428                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21429                app.kill(app.waitingToKill, true);
21430                success = false;
21431            } else {
21432                int processGroup;
21433                switch (app.curSchedGroup) {
21434                    case ProcessList.SCHED_GROUP_BACKGROUND:
21435                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
21436                        break;
21437                    case ProcessList.SCHED_GROUP_TOP_APP:
21438                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21439                        processGroup = Process.THREAD_GROUP_TOP_APP;
21440                        break;
21441                    default:
21442                        processGroup = Process.THREAD_GROUP_DEFAULT;
21443                        break;
21444                }
21445                long oldId = Binder.clearCallingIdentity();
21446                try {
21447                    Process.setProcessGroup(app.pid, processGroup);
21448                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21449                        // do nothing if we already switched to RT
21450                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21451                            // Switch VR thread for app to SCHED_FIFO
21452                            if (mVrState == VR_MODE && app.vrThreadTid != 0) {
21453                                try {
21454                                    Process.setThreadScheduler(app.vrThreadTid,
21455                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21456                                    mTopAppVrThreadTid = app.vrThreadTid;
21457                                } catch (IllegalArgumentException e) {
21458                                    // thread died, ignore
21459                                }
21460                            }
21461                            if (mUseFifoUiScheduling) {
21462                                // Switch UI pipeline for app to SCHED_FIFO
21463                                app.savedPriority = Process.getThreadPriority(app.pid);
21464                                try {
21465                                    Process.setThreadScheduler(app.pid,
21466                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21467                                } catch (IllegalArgumentException e) {
21468                                    // thread died, ignore
21469                                }
21470                                if (app.renderThreadTid != 0) {
21471                                    try {
21472                                        Process.setThreadScheduler(app.renderThreadTid,
21473                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21474                                    } catch (IllegalArgumentException e) {
21475                                        // thread died, ignore
21476                                    }
21477                                    if (DEBUG_OOM_ADJ) {
21478                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
21479                                            app.renderThreadTid + ") to FIFO");
21480                                    }
21481                                } else {
21482                                    if (DEBUG_OOM_ADJ) {
21483                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
21484                                    }
21485                                }
21486                            } else {
21487                                // Boost priority for top app UI and render threads
21488                                Process.setThreadPriority(app.pid, -10);
21489                                if (app.renderThreadTid != 0) {
21490                                    try {
21491                                        Process.setThreadPriority(app.renderThreadTid, -10);
21492                                    } catch (IllegalArgumentException e) {
21493                                        // thread died, ignore
21494                                    }
21495                                }
21496                            }
21497                        }
21498                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21499                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21500                        // Reset VR thread to SCHED_OTHER
21501                        // Safe to do even if we're not in VR mode
21502                        if (app.vrThreadTid != 0) {
21503                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
21504                            mTopAppVrThreadTid = 0;
21505                        }
21506                        if (mUseFifoUiScheduling) {
21507                            // Reset UI pipeline to SCHED_OTHER
21508                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
21509                            Process.setThreadPriority(app.pid, app.savedPriority);
21510                            if (app.renderThreadTid != 0) {
21511                                Process.setThreadScheduler(app.renderThreadTid,
21512                                    Process.SCHED_OTHER, 0);
21513                                Process.setThreadPriority(app.renderThreadTid, -4);
21514                            }
21515                        } else {
21516                            // Reset priority for top app UI and render threads
21517                            Process.setThreadPriority(app.pid, 0);
21518                            if (app.renderThreadTid != 0) {
21519                                Process.setThreadPriority(app.renderThreadTid, 0);
21520                            }
21521                        }
21522                    }
21523                } catch (Exception e) {
21524                    Slog.w(TAG, "Failed setting process group of " + app.pid
21525                            + " to " + app.curSchedGroup);
21526                    e.printStackTrace();
21527                } finally {
21528                    Binder.restoreCallingIdentity(oldId);
21529                }
21530            }
21531        }
21532        if (app.repForegroundActivities != app.foregroundActivities) {
21533            app.repForegroundActivities = app.foregroundActivities;
21534            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
21535        }
21536        if (app.repProcState != app.curProcState) {
21537            app.repProcState = app.curProcState;
21538            if (app.thread != null) {
21539                try {
21540                    if (false) {
21541                        //RuntimeException h = new RuntimeException("here");
21542                        Slog.i(TAG, "Sending new process state " + app.repProcState
21543                                + " to " + app /*, h*/);
21544                    }
21545                    app.thread.setProcessState(app.repProcState);
21546                } catch (RemoteException e) {
21547                }
21548            }
21549        }
21550        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
21551                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
21552            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
21553                // Experimental code to more aggressively collect pss while
21554                // running test...  the problem is that this tends to collect
21555                // the data right when a process is transitioning between process
21556                // states, which well tend to give noisy data.
21557                long start = SystemClock.uptimeMillis();
21558                long pss = Debug.getPss(app.pid, mTmpLong, null);
21559                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
21560                mPendingPssProcesses.remove(app);
21561                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
21562                        + " to " + app.curProcState + ": "
21563                        + (SystemClock.uptimeMillis()-start) + "ms");
21564            }
21565            app.lastStateTime = now;
21566            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21567                    mTestPssMode, isSleepingLocked(), now);
21568            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
21569                    + ProcessList.makeProcStateString(app.setProcState) + " to "
21570                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
21571                    + (app.nextPssTime-now) + ": " + app);
21572        } else {
21573            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
21574                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
21575                    mTestPssMode)))) {
21576                requestPssLocked(app, app.setProcState);
21577                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
21578                        mTestPssMode, isSleepingLocked(), now);
21579            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
21580                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
21581        }
21582        if (app.setProcState != app.curProcState) {
21583            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21584                    "Proc state change of " + app.processName
21585                            + " to " + app.curProcState);
21586            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
21587            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
21588            if (setImportant && !curImportant) {
21589                // This app is no longer something we consider important enough to allow to
21590                // use arbitrary amounts of battery power.  Note
21591                // its current wake lock time to later know to kill it if
21592                // it is not behaving well.
21593                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21594                synchronized (stats) {
21595                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
21596                            app.pid, nowElapsed);
21597                }
21598                app.lastCpuTime = app.curCpuTime;
21599
21600            }
21601            // Inform UsageStats of important process state change
21602            // Must be called before updating setProcState
21603            maybeUpdateUsageStatsLocked(app, nowElapsed);
21604
21605            app.setProcState = app.curProcState;
21606            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21607                app.notCachedSinceIdle = false;
21608            }
21609            if (!doingAll) {
21610                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
21611            } else {
21612                app.procStateChanged = true;
21613            }
21614        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
21615                > USAGE_STATS_INTERACTION_INTERVAL) {
21616            // For apps that sit around for a long time in the interactive state, we need
21617            // to report this at least once a day so they don't go idle.
21618            maybeUpdateUsageStatsLocked(app, nowElapsed);
21619        }
21620
21621        if (changes != 0) {
21622            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21623                    "Changes in " + app + ": " + changes);
21624            int i = mPendingProcessChanges.size()-1;
21625            ProcessChangeItem item = null;
21626            while (i >= 0) {
21627                item = mPendingProcessChanges.get(i);
21628                if (item.pid == app.pid) {
21629                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21630                            "Re-using existing item: " + item);
21631                    break;
21632                }
21633                i--;
21634            }
21635            if (i < 0) {
21636                // No existing item in pending changes; need a new one.
21637                final int NA = mAvailProcessChanges.size();
21638                if (NA > 0) {
21639                    item = mAvailProcessChanges.remove(NA-1);
21640                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21641                            "Retrieving available item: " + item);
21642                } else {
21643                    item = new ProcessChangeItem();
21644                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21645                            "Allocating new item: " + item);
21646                }
21647                item.changes = 0;
21648                item.pid = app.pid;
21649                item.uid = app.info.uid;
21650                if (mPendingProcessChanges.size() == 0) {
21651                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21652                            "*** Enqueueing dispatch processes changed!");
21653                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
21654                }
21655                mPendingProcessChanges.add(item);
21656            }
21657            item.changes |= changes;
21658            item.foregroundActivities = app.repForegroundActivities;
21659            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21660                    "Item " + Integer.toHexString(System.identityHashCode(item))
21661                    + " " + app.toShortString() + ": changes=" + item.changes
21662                    + " foreground=" + item.foregroundActivities
21663                    + " type=" + app.adjType + " source=" + app.adjSource
21664                    + " target=" + app.adjTarget);
21665        }
21666
21667        return success;
21668    }
21669
21670    private boolean isEphemeralLocked(int uid) {
21671        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
21672        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
21673            return false;
21674        }
21675        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
21676                packages[0]);
21677    }
21678
21679    @VisibleForTesting
21680    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
21681        final UidRecord.ChangeItem pendingChange;
21682        if (uidRec == null || uidRec.pendingChange == null) {
21683            if (mPendingUidChanges.size() == 0) {
21684                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21685                        "*** Enqueueing dispatch uid changed!");
21686                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
21687            }
21688            final int NA = mAvailUidChanges.size();
21689            if (NA > 0) {
21690                pendingChange = mAvailUidChanges.remove(NA-1);
21691                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21692                        "Retrieving available item: " + pendingChange);
21693            } else {
21694                pendingChange = new UidRecord.ChangeItem();
21695                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21696                        "Allocating new item: " + pendingChange);
21697            }
21698            if (uidRec != null) {
21699                uidRec.pendingChange = pendingChange;
21700                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
21701                    // If this uid is going away, and we haven't yet reported it is gone,
21702                    // then do so now.
21703                    change = UidRecord.CHANGE_GONE_IDLE;
21704                }
21705            } else if (uid < 0) {
21706                throw new IllegalArgumentException("No UidRecord or uid");
21707            }
21708            pendingChange.uidRecord = uidRec;
21709            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
21710            mPendingUidChanges.add(pendingChange);
21711        } else {
21712            pendingChange = uidRec.pendingChange;
21713            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
21714                change = UidRecord.CHANGE_GONE_IDLE;
21715            }
21716        }
21717        pendingChange.change = change;
21718        pendingChange.processState = uidRec != null
21719                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
21720        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
21721        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
21722        if (uidRec != null) {
21723            uidRec.updateLastDispatchedProcStateSeq(change);
21724        }
21725
21726        // Directly update the power manager, since we sit on top of it and it is critical
21727        // it be kept in sync (so wake locks will be held as soon as appropriate).
21728        if (mLocalPowerManager != null) {
21729            switch (change) {
21730                case UidRecord.CHANGE_GONE:
21731                case UidRecord.CHANGE_GONE_IDLE:
21732                    mLocalPowerManager.uidGone(pendingChange.uid);
21733                    break;
21734                case UidRecord.CHANGE_IDLE:
21735                    mLocalPowerManager.uidIdle(pendingChange.uid);
21736                    break;
21737                case UidRecord.CHANGE_ACTIVE:
21738                    mLocalPowerManager.uidActive(pendingChange.uid);
21739                    break;
21740                default:
21741                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
21742                            pendingChange.processState);
21743                    break;
21744            }
21745        }
21746    }
21747
21748    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
21749            String authority) {
21750        if (app == null) return;
21751        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21752            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
21753            if (userState == null) return;
21754            final long now = SystemClock.elapsedRealtime();
21755            Long lastReported = userState.mProviderLastReportedFg.get(authority);
21756            if (lastReported == null || lastReported < now - 60 * 1000L) {
21757                if (mSystemReady) {
21758                    // Cannot touch the user stats if not system ready
21759                    mUsageStatsService.reportContentProviderUsage(
21760                            authority, providerPkgName, app.userId);
21761                }
21762                userState.mProviderLastReportedFg.put(authority, now);
21763            }
21764        }
21765    }
21766
21767    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
21768        if (DEBUG_USAGE_STATS) {
21769            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
21770                    + "] state changes: old = " + app.setProcState + ", new = "
21771                    + app.curProcState);
21772        }
21773        if (mUsageStatsService == null) {
21774            return;
21775        }
21776        boolean isInteraction;
21777        // To avoid some abuse patterns, we are going to be careful about what we consider
21778        // to be an app interaction.  Being the top activity doesn't count while the display
21779        // is sleeping, nor do short foreground services.
21780        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
21781            isInteraction = true;
21782            app.fgInteractionTime = 0;
21783        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
21784            if (app.fgInteractionTime == 0) {
21785                app.fgInteractionTime = nowElapsed;
21786                isInteraction = false;
21787            } else {
21788                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
21789            }
21790        } else {
21791            // If the app was being forced to the foreground, by say a Toast, then
21792            // no need to treat it as an interaction
21793            isInteraction = app.forcingToForeground == null
21794                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21795            app.fgInteractionTime = 0;
21796        }
21797        if (isInteraction && (!app.reportedInteraction
21798                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
21799            app.interactionEventTime = nowElapsed;
21800            String[] packages = app.getPackageList();
21801            if (packages != null) {
21802                for (int i = 0; i < packages.length; i++) {
21803                    mUsageStatsService.reportEvent(packages[i], app.userId,
21804                            UsageEvents.Event.SYSTEM_INTERACTION);
21805                }
21806            }
21807        }
21808        app.reportedInteraction = isInteraction;
21809        if (!isInteraction) {
21810            app.interactionEventTime = 0;
21811        }
21812    }
21813
21814    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
21815        if (proc.thread != null) {
21816            if (proc.baseProcessTracker != null) {
21817                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
21818            }
21819        }
21820    }
21821
21822    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
21823            ProcessRecord TOP_APP, boolean doingAll, long now) {
21824        if (app.thread == null) {
21825            return false;
21826        }
21827
21828        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
21829
21830        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
21831    }
21832
21833    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
21834            boolean oomAdj) {
21835        if (isForeground != proc.foregroundServices) {
21836            proc.foregroundServices = isForeground;
21837            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
21838                    proc.info.uid);
21839            if (isForeground) {
21840                if (curProcs == null) {
21841                    curProcs = new ArrayList<ProcessRecord>();
21842                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
21843                }
21844                if (!curProcs.contains(proc)) {
21845                    curProcs.add(proc);
21846                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
21847                            proc.info.packageName, proc.info.uid);
21848                }
21849            } else {
21850                if (curProcs != null) {
21851                    if (curProcs.remove(proc)) {
21852                        mBatteryStatsService.noteEvent(
21853                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
21854                                proc.info.packageName, proc.info.uid);
21855                        if (curProcs.size() <= 0) {
21856                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
21857                        }
21858                    }
21859                }
21860            }
21861            if (oomAdj) {
21862                updateOomAdjLocked();
21863            }
21864        }
21865    }
21866
21867    private final ActivityRecord resumedAppLocked() {
21868        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
21869        String pkg;
21870        int uid;
21871        if (act != null) {
21872            pkg = act.packageName;
21873            uid = act.info.applicationInfo.uid;
21874        } else {
21875            pkg = null;
21876            uid = -1;
21877        }
21878        // Has the UID or resumed package name changed?
21879        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
21880                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
21881            if (mCurResumedPackage != null) {
21882                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
21883                        mCurResumedPackage, mCurResumedUid);
21884            }
21885            mCurResumedPackage = pkg;
21886            mCurResumedUid = uid;
21887            if (mCurResumedPackage != null) {
21888                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
21889                        mCurResumedPackage, mCurResumedUid);
21890            }
21891        }
21892        return act;
21893    }
21894
21895    final boolean updateOomAdjLocked(ProcessRecord app) {
21896        final ActivityRecord TOP_ACT = resumedAppLocked();
21897        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21898        final boolean wasCached = app.cached;
21899
21900        mAdjSeq++;
21901
21902        // This is the desired cached adjusment we want to tell it to use.
21903        // If our app is currently cached, we know it, and that is it.  Otherwise,
21904        // we don't know it yet, and it needs to now be cached we will then
21905        // need to do a complete oom adj.
21906        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
21907                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
21908        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
21909                SystemClock.uptimeMillis());
21910        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
21911            // Changed to/from cached state, so apps after it in the LRU
21912            // list may also be changed.
21913            updateOomAdjLocked();
21914        }
21915        return success;
21916    }
21917
21918    final void updateOomAdjLocked() {
21919        final ActivityRecord TOP_ACT = resumedAppLocked();
21920        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21921        final long now = SystemClock.uptimeMillis();
21922        final long nowElapsed = SystemClock.elapsedRealtime();
21923        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
21924        final int N = mLruProcesses.size();
21925
21926        if (false) {
21927            RuntimeException e = new RuntimeException();
21928            e.fillInStackTrace();
21929            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
21930        }
21931
21932        // Reset state in all uid records.
21933        for (int i=mActiveUids.size()-1; i>=0; i--) {
21934            final UidRecord uidRec = mActiveUids.valueAt(i);
21935            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21936                    "Starting update of " + uidRec);
21937            uidRec.reset();
21938        }
21939
21940        mStackSupervisor.rankTaskLayersIfNeeded();
21941
21942        mAdjSeq++;
21943        mNewNumServiceProcs = 0;
21944        mNewNumAServiceProcs = 0;
21945
21946        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
21947        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
21948
21949        // Let's determine how many processes we have running vs.
21950        // how many slots we have for background processes; we may want
21951        // to put multiple processes in a slot of there are enough of
21952        // them.
21953        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
21954                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
21955        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
21956        if (numEmptyProcs > cachedProcessLimit) {
21957            // If there are more empty processes than our limit on cached
21958            // processes, then use the cached process limit for the factor.
21959            // This ensures that the really old empty processes get pushed
21960            // down to the bottom, so if we are running low on memory we will
21961            // have a better chance at keeping around more cached processes
21962            // instead of a gazillion empty processes.
21963            numEmptyProcs = cachedProcessLimit;
21964        }
21965        int emptyFactor = numEmptyProcs/numSlots;
21966        if (emptyFactor < 1) emptyFactor = 1;
21967        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
21968        if (cachedFactor < 1) cachedFactor = 1;
21969        int stepCached = 0;
21970        int stepEmpty = 0;
21971        int numCached = 0;
21972        int numEmpty = 0;
21973        int numTrimming = 0;
21974
21975        mNumNonCachedProcs = 0;
21976        mNumCachedHiddenProcs = 0;
21977
21978        // First update the OOM adjustment for each of the
21979        // application processes based on their current state.
21980        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
21981        int nextCachedAdj = curCachedAdj+1;
21982        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
21983        int nextEmptyAdj = curEmptyAdj+2;
21984        for (int i=N-1; i>=0; i--) {
21985            ProcessRecord app = mLruProcesses.get(i);
21986            if (!app.killedByAm && app.thread != null) {
21987                app.procStateChanged = false;
21988                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21989
21990                // If we haven't yet assigned the final cached adj
21991                // to the process, do that now.
21992                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21993                    switch (app.curProcState) {
21994                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21995                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21996                            // This process is a cached process holding activities...
21997                            // assign it the next cached value for that type, and then
21998                            // step that cached level.
21999                            app.curRawAdj = curCachedAdj;
22000                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22001                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22002                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22003                                    + ")");
22004                            if (curCachedAdj != nextCachedAdj) {
22005                                stepCached++;
22006                                if (stepCached >= cachedFactor) {
22007                                    stepCached = 0;
22008                                    curCachedAdj = nextCachedAdj;
22009                                    nextCachedAdj += 2;
22010                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22011                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22012                                    }
22013                                }
22014                            }
22015                            break;
22016                        default:
22017                            // For everything else, assign next empty cached process
22018                            // level and bump that up.  Note that this means that
22019                            // long-running services that have dropped down to the
22020                            // cached level will be treated as empty (since their process
22021                            // state is still as a service), which is what we want.
22022                            app.curRawAdj = curEmptyAdj;
22023                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22024                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22025                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22026                                    + ")");
22027                            if (curEmptyAdj != nextEmptyAdj) {
22028                                stepEmpty++;
22029                                if (stepEmpty >= emptyFactor) {
22030                                    stepEmpty = 0;
22031                                    curEmptyAdj = nextEmptyAdj;
22032                                    nextEmptyAdj += 2;
22033                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22034                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22035                                    }
22036                                }
22037                            }
22038                            break;
22039                    }
22040                }
22041
22042                applyOomAdjLocked(app, true, now, nowElapsed);
22043
22044                // Count the number of process types.
22045                switch (app.curProcState) {
22046                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22047                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22048                        mNumCachedHiddenProcs++;
22049                        numCached++;
22050                        if (numCached > cachedProcessLimit) {
22051                            app.kill("cached #" + numCached, true);
22052                        }
22053                        break;
22054                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22055                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22056                                && app.lastActivityTime < oldTime) {
22057                            app.kill("empty for "
22058                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22059                                    / 1000) + "s", true);
22060                        } else {
22061                            numEmpty++;
22062                            if (numEmpty > emptyProcessLimit) {
22063                                app.kill("empty #" + numEmpty, true);
22064                            }
22065                        }
22066                        break;
22067                    default:
22068                        mNumNonCachedProcs++;
22069                        break;
22070                }
22071
22072                if (app.isolated && app.services.size() <= 0) {
22073                    // If this is an isolated process, and there are no
22074                    // services running in it, then the process is no longer
22075                    // needed.  We agressively kill these because we can by
22076                    // definition not re-use the same process again, and it is
22077                    // good to avoid having whatever code was running in them
22078                    // left sitting around after no longer needed.
22079                    app.kill("isolated not needed", true);
22080                } else {
22081                    // Keeping this process, update its uid.
22082                    final UidRecord uidRec = app.uidRecord;
22083                    if (uidRec != null) {
22084                        uidRec.ephemeral = app.info.isInstantApp();
22085                        if (uidRec.curProcState > app.curProcState) {
22086                            uidRec.curProcState = app.curProcState;
22087                        }
22088                    }
22089                }
22090
22091                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22092                        && !app.killedByAm) {
22093                    numTrimming++;
22094                }
22095            }
22096        }
22097
22098        incrementProcStateSeqAndNotifyAppsLocked();
22099
22100        mNumServiceProcs = mNewNumServiceProcs;
22101
22102        // Now determine the memory trimming level of background processes.
22103        // Unfortunately we need to start at the back of the list to do this
22104        // properly.  We only do this if the number of background apps we
22105        // are managing to keep around is less than half the maximum we desire;
22106        // if we are keeping a good number around, we'll let them use whatever
22107        // memory they want.
22108        final int numCachedAndEmpty = numCached + numEmpty;
22109        int memFactor;
22110        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22111                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22112            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22113                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22114            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22115                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22116            } else {
22117                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22118            }
22119        } else {
22120            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22121        }
22122        // We always allow the memory level to go up (better).  We only allow it to go
22123        // down if we are in a state where that is allowed, *and* the total number of processes
22124        // has gone down since last time.
22125        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22126                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22127                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22128        if (memFactor > mLastMemoryLevel) {
22129            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22130                memFactor = mLastMemoryLevel;
22131                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22132            }
22133        }
22134        if (memFactor != mLastMemoryLevel) {
22135            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22136        }
22137        mLastMemoryLevel = memFactor;
22138        mLastNumProcesses = mLruProcesses.size();
22139        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22140        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22141        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22142            if (mLowRamStartTime == 0) {
22143                mLowRamStartTime = now;
22144            }
22145            int step = 0;
22146            int fgTrimLevel;
22147            switch (memFactor) {
22148                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22149                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22150                    break;
22151                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22152                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22153                    break;
22154                default:
22155                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22156                    break;
22157            }
22158            int factor = numTrimming/3;
22159            int minFactor = 2;
22160            if (mHomeProcess != null) minFactor++;
22161            if (mPreviousProcess != null) minFactor++;
22162            if (factor < minFactor) factor = minFactor;
22163            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22164            for (int i=N-1; i>=0; i--) {
22165                ProcessRecord app = mLruProcesses.get(i);
22166                if (allChanged || app.procStateChanged) {
22167                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22168                    app.procStateChanged = false;
22169                }
22170                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22171                        && !app.killedByAm) {
22172                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22173                        try {
22174                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22175                                    "Trimming memory of " + app.processName + " to " + curLevel);
22176                            app.thread.scheduleTrimMemory(curLevel);
22177                        } catch (RemoteException e) {
22178                        }
22179                        if (false) {
22180                            // For now we won't do this; our memory trimming seems
22181                            // to be good enough at this point that destroying
22182                            // activities causes more harm than good.
22183                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22184                                    && app != mHomeProcess && app != mPreviousProcess) {
22185                                // Need to do this on its own message because the stack may not
22186                                // be in a consistent state at this point.
22187                                // For these apps we will also finish their activities
22188                                // to help them free memory.
22189                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22190                            }
22191                        }
22192                    }
22193                    app.trimMemoryLevel = curLevel;
22194                    step++;
22195                    if (step >= factor) {
22196                        step = 0;
22197                        switch (curLevel) {
22198                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22199                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22200                                break;
22201                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22202                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22203                                break;
22204                        }
22205                    }
22206                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22207                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22208                            && app.thread != null) {
22209                        try {
22210                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22211                                    "Trimming memory of heavy-weight " + app.processName
22212                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22213                            app.thread.scheduleTrimMemory(
22214                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22215                        } catch (RemoteException e) {
22216                        }
22217                    }
22218                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22219                } else {
22220                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22221                            || app.systemNoUi) && app.pendingUiClean) {
22222                        // If this application is now in the background and it
22223                        // had done UI, then give it the special trim level to
22224                        // have it free UI resources.
22225                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22226                        if (app.trimMemoryLevel < level && app.thread != null) {
22227                            try {
22228                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22229                                        "Trimming memory of bg-ui " + app.processName
22230                                        + " to " + level);
22231                                app.thread.scheduleTrimMemory(level);
22232                            } catch (RemoteException e) {
22233                            }
22234                        }
22235                        app.pendingUiClean = false;
22236                    }
22237                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22238                        try {
22239                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22240                                    "Trimming memory of fg " + app.processName
22241                                    + " to " + fgTrimLevel);
22242                            app.thread.scheduleTrimMemory(fgTrimLevel);
22243                        } catch (RemoteException e) {
22244                        }
22245                    }
22246                    app.trimMemoryLevel = fgTrimLevel;
22247                }
22248            }
22249        } else {
22250            if (mLowRamStartTime != 0) {
22251                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22252                mLowRamStartTime = 0;
22253            }
22254            for (int i=N-1; i>=0; i--) {
22255                ProcessRecord app = mLruProcesses.get(i);
22256                if (allChanged || app.procStateChanged) {
22257                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22258                    app.procStateChanged = false;
22259                }
22260                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22261                        || app.systemNoUi) && app.pendingUiClean) {
22262                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22263                            && app.thread != null) {
22264                        try {
22265                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22266                                    "Trimming memory of ui hidden " + app.processName
22267                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22268                            app.thread.scheduleTrimMemory(
22269                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22270                        } catch (RemoteException e) {
22271                        }
22272                    }
22273                    app.pendingUiClean = false;
22274                }
22275                app.trimMemoryLevel = 0;
22276            }
22277        }
22278
22279        if (mAlwaysFinishActivities) {
22280            // Need to do this on its own message because the stack may not
22281            // be in a consistent state at this point.
22282            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22283        }
22284
22285        if (allChanged) {
22286            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22287        }
22288
22289        // Update from any uid changes.
22290        if (mLocalPowerManager != null) {
22291            mLocalPowerManager.startUidChanges();
22292        }
22293        for (int i=mActiveUids.size()-1; i>=0; i--) {
22294            final UidRecord uidRec = mActiveUids.valueAt(i);
22295            int uidChange = UidRecord.CHANGE_PROCSTATE;
22296            if (uidRec.setProcState != uidRec.curProcState
22297                    || uidRec.setWhitelist != uidRec.curWhitelist) {
22298                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22299                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22300                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22301                        + " to " + uidRec.curWhitelist);
22302                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22303                        && !uidRec.curWhitelist) {
22304                    // UID is now in the background (and not on the temp whitelist).  Was it
22305                    // previously in the foreground (or on the temp whitelist)?
22306                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22307                            || uidRec.setWhitelist) {
22308                        uidRec.lastBackgroundTime = nowElapsed;
22309                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22310                            // Note: the background settle time is in elapsed realtime, while
22311                            // the handler time base is uptime.  All this means is that we may
22312                            // stop background uids later than we had intended, but that only
22313                            // happens because the device was sleeping so we are okay anyway.
22314                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
22315                        }
22316                    }
22317                } else {
22318                    if (uidRec.idle) {
22319                        uidChange = UidRecord.CHANGE_ACTIVE;
22320                        uidRec.idle = false;
22321                    }
22322                    uidRec.lastBackgroundTime = 0;
22323                }
22324                uidRec.setProcState = uidRec.curProcState;
22325                uidRec.setWhitelist = uidRec.curWhitelist;
22326                enqueueUidChangeLocked(uidRec, -1, uidChange);
22327                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22328            }
22329        }
22330        if (mLocalPowerManager != null) {
22331            mLocalPowerManager.finishUidChanges();
22332        }
22333
22334        if (mProcessStats.shouldWriteNowLocked(now)) {
22335            mHandler.post(new Runnable() {
22336                @Override public void run() {
22337                    synchronized (ActivityManagerService.this) {
22338                        mProcessStats.writeStateAsyncLocked();
22339                    }
22340                }
22341            });
22342        }
22343
22344        if (DEBUG_OOM_ADJ) {
22345            final long duration = SystemClock.uptimeMillis() - now;
22346            if (false) {
22347                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22348                        new RuntimeException("here").fillInStackTrace());
22349            } else {
22350                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22351            }
22352        }
22353    }
22354
22355    @Override
22356    public void makePackageIdle(String packageName, int userId) {
22357        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22358                != PackageManager.PERMISSION_GRANTED) {
22359            String msg = "Permission Denial: makePackageIdle() from pid="
22360                    + Binder.getCallingPid()
22361                    + ", uid=" + Binder.getCallingUid()
22362                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22363            Slog.w(TAG, msg);
22364            throw new SecurityException(msg);
22365        }
22366        final int callingPid = Binder.getCallingPid();
22367        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22368                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22369        long callingId = Binder.clearCallingIdentity();
22370        synchronized(this) {
22371            try {
22372                IPackageManager pm = AppGlobals.getPackageManager();
22373                int pkgUid = -1;
22374                try {
22375                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22376                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22377                } catch (RemoteException e) {
22378                }
22379                if (pkgUid == -1) {
22380                    throw new IllegalArgumentException("Unknown package name " + packageName);
22381                }
22382
22383                if (mLocalPowerManager != null) {
22384                    mLocalPowerManager.startUidChanges();
22385                }
22386                final int appId = UserHandle.getAppId(pkgUid);
22387                final int N = mActiveUids.size();
22388                for (int i=N-1; i>=0; i--) {
22389                    final UidRecord uidRec = mActiveUids.valueAt(i);
22390                    final long bgTime = uidRec.lastBackgroundTime;
22391                    if (bgTime > 0 && !uidRec.idle) {
22392                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22393                            if (userId == UserHandle.USER_ALL ||
22394                                    userId == UserHandle.getUserId(uidRec.uid)) {
22395                                uidRec.idle = true;
22396                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22397                                        + " from package " + packageName + " user " + userId);
22398                                doStopUidLocked(uidRec.uid, uidRec);
22399                            }
22400                        }
22401                    }
22402                }
22403            } finally {
22404                if (mLocalPowerManager != null) {
22405                    mLocalPowerManager.finishUidChanges();
22406                }
22407                Binder.restoreCallingIdentity(callingId);
22408            }
22409        }
22410    }
22411
22412    final void idleUids() {
22413        synchronized (this) {
22414            final int N = mActiveUids.size();
22415            if (N <= 0) {
22416                return;
22417            }
22418            final long nowElapsed = SystemClock.elapsedRealtime();
22419            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
22420            long nextTime = 0;
22421            if (mLocalPowerManager != null) {
22422                mLocalPowerManager.startUidChanges();
22423            }
22424            for (int i=N-1; i>=0; i--) {
22425                final UidRecord uidRec = mActiveUids.valueAt(i);
22426                final long bgTime = uidRec.lastBackgroundTime;
22427                if (bgTime > 0 && !uidRec.idle) {
22428                    if (bgTime <= maxBgTime) {
22429                        uidRec.idle = true;
22430                        doStopUidLocked(uidRec.uid, uidRec);
22431                    } else {
22432                        if (nextTime == 0 || nextTime > bgTime) {
22433                            nextTime = bgTime;
22434                        }
22435                    }
22436                }
22437            }
22438            if (mLocalPowerManager != null) {
22439                mLocalPowerManager.finishUidChanges();
22440            }
22441            if (nextTime > 0) {
22442                mHandler.removeMessages(IDLE_UIDS_MSG);
22443                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22444                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
22445            }
22446        }
22447    }
22448
22449    /**
22450     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
22451     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
22452     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
22453     */
22454    @VisibleForTesting
22455    @GuardedBy("this")
22456    void incrementProcStateSeqAndNotifyAppsLocked() {
22457        // Used for identifying which uids need to block for network.
22458        ArrayList<Integer> blockingUids = null;
22459        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
22460            final UidRecord uidRec = mActiveUids.valueAt(i);
22461            // If the network is not restricted for uid, then nothing to do here.
22462            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
22463                continue;
22464            }
22465            // If process state is not changed, then there's nothing to do.
22466            if (uidRec.setProcState == uidRec.curProcState) {
22467                continue;
22468            }
22469            final int blockState = getBlockStateForUid(uidRec);
22470            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
22471            // there's nothing the app needs to do in this scenario.
22472            if (blockState == NETWORK_STATE_NO_CHANGE) {
22473                continue;
22474            }
22475            synchronized (uidRec.lock) {
22476                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
22477                if (blockState == NETWORK_STATE_BLOCK) {
22478                    if (blockingUids == null) {
22479                        blockingUids = new ArrayList<>();
22480                    }
22481                    blockingUids.add(uidRec.uid);
22482                } else {
22483                    if (DEBUG_NETWORK) {
22484                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
22485                                + " threads for uid: " + uidRec);
22486                    }
22487                    if (uidRec.waitingForNetwork) {
22488                        uidRec.lock.notifyAll();
22489                    }
22490                }
22491            }
22492        }
22493
22494        // There are no uids that need to block, so nothing more to do.
22495        if (blockingUids == null) {
22496            return;
22497        }
22498
22499        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
22500            final ProcessRecord app = mLruProcesses.get(i);
22501            if (!blockingUids.contains(app.uid)) {
22502                continue;
22503            }
22504            if (!app.killedByAm && app.thread != null) {
22505                final UidRecord uidRec = mActiveUids.get(app.uid);
22506                try {
22507                    if (DEBUG_NETWORK) {
22508                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
22509                                + uidRec);
22510                    }
22511                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
22512                } catch (RemoteException ignored) {
22513                }
22514            }
22515        }
22516    }
22517
22518    /**
22519     * Checks if the uid is coming from background to foreground or vice versa and returns
22520     * appropriate block state based on this.
22521     *
22522     * @return blockState based on whether the uid is coming from background to foreground or
22523     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
22524     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
22525     *         {@link #NETWORK_STATE_NO_CHANGE}.
22526     */
22527    @VisibleForTesting
22528    int getBlockStateForUid(UidRecord uidRec) {
22529        // Denotes whether uid's process state is currently allowed network access.
22530        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
22531                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
22532        // Denotes whether uid's process state was previously allowed network access.
22533        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
22534                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
22535
22536        // When the uid is coming to foreground, AMS should inform the app thread that it should
22537        // block for the network rules to get updated before launching an activity.
22538        if (!wasAllowed && isAllowed) {
22539            return NETWORK_STATE_BLOCK;
22540        }
22541        // When the uid is going to background, AMS should inform the app thread that if an
22542        // activity launch is blocked for the network rules to get updated, it should be unblocked.
22543        if (wasAllowed && !isAllowed) {
22544            return NETWORK_STATE_UNBLOCK;
22545        }
22546        return NETWORK_STATE_NO_CHANGE;
22547    }
22548
22549    final void runInBackgroundDisabled(int uid) {
22550        synchronized (this) {
22551            UidRecord uidRec = mActiveUids.get(uid);
22552            if (uidRec != null) {
22553                // This uid is actually running...  should it be considered background now?
22554                if (uidRec.idle) {
22555                    doStopUidLocked(uidRec.uid, uidRec);
22556                }
22557            } else {
22558                // This uid isn't actually running...  still send a report about it being "stopped".
22559                doStopUidLocked(uid, null);
22560            }
22561        }
22562    }
22563
22564    final void doStopUidLocked(int uid, final UidRecord uidRec) {
22565        mServices.stopInBackgroundLocked(uid);
22566        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
22567    }
22568
22569    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
22570        boolean changed = false;
22571        for (int i=mActiveUids.size()-1; i>=0; i--) {
22572            final UidRecord uidRec = mActiveUids.valueAt(i);
22573            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
22574                uidRec.curWhitelist = onWhitelist;
22575                changed = true;
22576            }
22577        }
22578        if (changed) {
22579            updateOomAdjLocked();
22580        }
22581    }
22582
22583    final void trimApplications() {
22584        synchronized (this) {
22585            int i;
22586
22587            // First remove any unused application processes whose package
22588            // has been removed.
22589            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
22590                final ProcessRecord app = mRemovedProcesses.get(i);
22591                if (app.activities.size() == 0
22592                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
22593                    Slog.i(
22594                        TAG, "Exiting empty application process "
22595                        + app.toShortString() + " ("
22596                        + (app.thread != null ? app.thread.asBinder() : null)
22597                        + ")\n");
22598                    if (app.pid > 0 && app.pid != MY_PID) {
22599                        app.kill("empty", false);
22600                    } else {
22601                        try {
22602                            app.thread.scheduleExit();
22603                        } catch (Exception e) {
22604                            // Ignore exceptions.
22605                        }
22606                    }
22607                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
22608                    mRemovedProcesses.remove(i);
22609
22610                    if (app.persistent) {
22611                        addAppLocked(app.info, null, false, null /* ABI override */);
22612                    }
22613                }
22614            }
22615
22616            // Now update the oom adj for all processes.
22617            updateOomAdjLocked();
22618        }
22619    }
22620
22621    /** This method sends the specified signal to each of the persistent apps */
22622    public void signalPersistentProcesses(int sig) throws RemoteException {
22623        if (sig != Process.SIGNAL_USR1) {
22624            throw new SecurityException("Only SIGNAL_USR1 is allowed");
22625        }
22626
22627        synchronized (this) {
22628            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
22629                    != PackageManager.PERMISSION_GRANTED) {
22630                throw new SecurityException("Requires permission "
22631                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
22632            }
22633
22634            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
22635                ProcessRecord r = mLruProcesses.get(i);
22636                if (r.thread != null && r.persistent) {
22637                    Process.sendSignal(r.pid, sig);
22638                }
22639            }
22640        }
22641    }
22642
22643    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
22644        if (proc == null || proc == mProfileProc) {
22645            proc = mProfileProc;
22646            profileType = mProfileType;
22647            clearProfilerLocked();
22648        }
22649        if (proc == null) {
22650            return;
22651        }
22652        try {
22653            proc.thread.profilerControl(false, null, profileType);
22654        } catch (RemoteException e) {
22655            throw new IllegalStateException("Process disappeared");
22656        }
22657    }
22658
22659    private void clearProfilerLocked() {
22660        if (mProfileFd != null) {
22661            try {
22662                mProfileFd.close();
22663            } catch (IOException e) {
22664            }
22665        }
22666        mProfileApp = null;
22667        mProfileProc = null;
22668        mProfileFile = null;
22669        mProfileType = 0;
22670        mAutoStopProfiler = false;
22671        mStreamingOutput = false;
22672        mSamplingInterval = 0;
22673    }
22674
22675    public boolean profileControl(String process, int userId, boolean start,
22676            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
22677
22678        try {
22679            synchronized (this) {
22680                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22681                // its own permission.
22682                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22683                        != PackageManager.PERMISSION_GRANTED) {
22684                    throw new SecurityException("Requires permission "
22685                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22686                }
22687
22688                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
22689                    throw new IllegalArgumentException("null profile info or fd");
22690                }
22691
22692                ProcessRecord proc = null;
22693                if (process != null) {
22694                    proc = findProcessLocked(process, userId, "profileControl");
22695                }
22696
22697                if (start && (proc == null || proc.thread == null)) {
22698                    throw new IllegalArgumentException("Unknown process: " + process);
22699                }
22700
22701                if (start) {
22702                    stopProfilerLocked(null, 0);
22703                    setProfileApp(proc.info, proc.processName, profilerInfo);
22704                    mProfileProc = proc;
22705                    mProfileType = profileType;
22706                    ParcelFileDescriptor fd = profilerInfo.profileFd;
22707                    try {
22708                        fd = fd.dup();
22709                    } catch (IOException e) {
22710                        fd = null;
22711                    }
22712                    profilerInfo.profileFd = fd;
22713                    proc.thread.profilerControl(start, profilerInfo, profileType);
22714                    fd = null;
22715                    try {
22716                        mProfileFd.close();
22717                    } catch (IOException e) {
22718                    }
22719                    mProfileFd = null;
22720                } else {
22721                    stopProfilerLocked(proc, profileType);
22722                    if (profilerInfo != null && profilerInfo.profileFd != null) {
22723                        try {
22724                            profilerInfo.profileFd.close();
22725                        } catch (IOException e) {
22726                        }
22727                    }
22728                }
22729
22730                return true;
22731            }
22732        } catch (RemoteException e) {
22733            throw new IllegalStateException("Process disappeared");
22734        } finally {
22735            if (profilerInfo != null && profilerInfo.profileFd != null) {
22736                try {
22737                    profilerInfo.profileFd.close();
22738                } catch (IOException e) {
22739                }
22740            }
22741        }
22742    }
22743
22744    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
22745        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22746                userId, true, ALLOW_FULL_ONLY, callName, null);
22747        ProcessRecord proc = null;
22748        try {
22749            int pid = Integer.parseInt(process);
22750            synchronized (mPidsSelfLocked) {
22751                proc = mPidsSelfLocked.get(pid);
22752            }
22753        } catch (NumberFormatException e) {
22754        }
22755
22756        if (proc == null) {
22757            ArrayMap<String, SparseArray<ProcessRecord>> all
22758                    = mProcessNames.getMap();
22759            SparseArray<ProcessRecord> procs = all.get(process);
22760            if (procs != null && procs.size() > 0) {
22761                proc = procs.valueAt(0);
22762                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
22763                    for (int i=1; i<procs.size(); i++) {
22764                        ProcessRecord thisProc = procs.valueAt(i);
22765                        if (thisProc.userId == userId) {
22766                            proc = thisProc;
22767                            break;
22768                        }
22769                    }
22770                }
22771            }
22772        }
22773
22774        return proc;
22775    }
22776
22777    public boolean dumpHeap(String process, int userId, boolean managed,
22778            String path, ParcelFileDescriptor fd) throws RemoteException {
22779
22780        try {
22781            synchronized (this) {
22782                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22783                // its own permission (same as profileControl).
22784                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22785                        != PackageManager.PERMISSION_GRANTED) {
22786                    throw new SecurityException("Requires permission "
22787                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22788                }
22789
22790                if (fd == null) {
22791                    throw new IllegalArgumentException("null fd");
22792                }
22793
22794                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
22795                if (proc == null || proc.thread == null) {
22796                    throw new IllegalArgumentException("Unknown process: " + process);
22797                }
22798
22799                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22800                if (!isDebuggable) {
22801                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22802                        throw new SecurityException("Process not debuggable: " + proc);
22803                    }
22804                }
22805
22806                proc.thread.dumpHeap(managed, path, fd);
22807                fd = null;
22808                return true;
22809            }
22810        } catch (RemoteException e) {
22811            throw new IllegalStateException("Process disappeared");
22812        } finally {
22813            if (fd != null) {
22814                try {
22815                    fd.close();
22816                } catch (IOException e) {
22817                }
22818            }
22819        }
22820    }
22821
22822    @Override
22823    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
22824            String reportPackage) {
22825        if (processName != null) {
22826            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
22827                    "setDumpHeapDebugLimit()");
22828        } else {
22829            synchronized (mPidsSelfLocked) {
22830                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
22831                if (proc == null) {
22832                    throw new SecurityException("No process found for calling pid "
22833                            + Binder.getCallingPid());
22834                }
22835                if (!Build.IS_DEBUGGABLE
22836                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22837                    throw new SecurityException("Not running a debuggable build");
22838                }
22839                processName = proc.processName;
22840                uid = proc.uid;
22841                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
22842                    throw new SecurityException("Package " + reportPackage + " is not running in "
22843                            + proc);
22844                }
22845            }
22846        }
22847        synchronized (this) {
22848            if (maxMemSize > 0) {
22849                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
22850            } else {
22851                if (uid != 0) {
22852                    mMemWatchProcesses.remove(processName, uid);
22853                } else {
22854                    mMemWatchProcesses.getMap().remove(processName);
22855                }
22856            }
22857        }
22858    }
22859
22860    @Override
22861    public void dumpHeapFinished(String path) {
22862        synchronized (this) {
22863            if (Binder.getCallingPid() != mMemWatchDumpPid) {
22864                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
22865                        + " does not match last pid " + mMemWatchDumpPid);
22866                return;
22867            }
22868            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
22869                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
22870                        + " does not match last path " + mMemWatchDumpFile);
22871                return;
22872            }
22873            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
22874            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
22875        }
22876    }
22877
22878    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
22879    public void monitor() {
22880        synchronized (this) { }
22881    }
22882
22883    void onCoreSettingsChange(Bundle settings) {
22884        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22885            ProcessRecord processRecord = mLruProcesses.get(i);
22886            try {
22887                if (processRecord.thread != null) {
22888                    processRecord.thread.setCoreSettings(settings);
22889                }
22890            } catch (RemoteException re) {
22891                /* ignore */
22892            }
22893        }
22894    }
22895
22896    // Multi-user methods
22897
22898    /**
22899     * Start user, if its not already running, but don't bring it to foreground.
22900     */
22901    @Override
22902    public boolean startUserInBackground(final int userId) {
22903        return mUserController.startUser(userId, /* foreground */ false);
22904    }
22905
22906    @Override
22907    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
22908        return mUserController.unlockUser(userId, token, secret, listener);
22909    }
22910
22911    @Override
22912    public boolean switchUser(final int targetUserId) {
22913        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
22914        int currentUserId;
22915        UserInfo targetUserInfo;
22916        synchronized (this) {
22917            currentUserId = mUserController.getCurrentUserIdLocked();
22918            targetUserInfo = mUserController.getUserInfo(targetUserId);
22919            if (targetUserId == currentUserId) {
22920                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
22921                return true;
22922            }
22923            if (targetUserInfo == null) {
22924                Slog.w(TAG, "No user info for user #" + targetUserId);
22925                return false;
22926            }
22927            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
22928                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
22929                        + " when device is in demo mode");
22930                return false;
22931            }
22932            if (!targetUserInfo.supportsSwitchTo()) {
22933                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
22934                return false;
22935            }
22936            if (targetUserInfo.isManagedProfile()) {
22937                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
22938                return false;
22939            }
22940            mUserController.setTargetUserIdLocked(targetUserId);
22941        }
22942        if (mUserController.mUserSwitchUiEnabled) {
22943            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
22944            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
22945            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
22946            mUiHandler.sendMessage(mHandler.obtainMessage(
22947                    START_USER_SWITCH_UI_MSG, userNames));
22948        } else {
22949            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
22950            mHandler.sendMessage(mHandler.obtainMessage(
22951                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
22952        }
22953        return true;
22954    }
22955
22956    void scheduleStartProfilesLocked() {
22957        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
22958            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
22959                    DateUtils.SECOND_IN_MILLIS);
22960        }
22961    }
22962
22963    @Override
22964    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
22965        return mUserController.stopUser(userId, force, callback);
22966    }
22967
22968    @Override
22969    public UserInfo getCurrentUser() {
22970        return mUserController.getCurrentUser();
22971    }
22972
22973    String getStartedUserState(int userId) {
22974        synchronized (this) {
22975            final UserState userState = mUserController.getStartedUserStateLocked(userId);
22976            return UserState.stateToString(userState.state);
22977        }
22978    }
22979
22980    @Override
22981    public boolean isUserRunning(int userId, int flags) {
22982        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
22983                && checkCallingPermission(INTERACT_ACROSS_USERS)
22984                    != PackageManager.PERMISSION_GRANTED) {
22985            String msg = "Permission Denial: isUserRunning() from pid="
22986                    + Binder.getCallingPid()
22987                    + ", uid=" + Binder.getCallingUid()
22988                    + " requires " + INTERACT_ACROSS_USERS;
22989            Slog.w(TAG, msg);
22990            throw new SecurityException(msg);
22991        }
22992        synchronized (this) {
22993            return mUserController.isUserRunningLocked(userId, flags);
22994        }
22995    }
22996
22997    @Override
22998    public int[] getRunningUserIds() {
22999        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23000                != PackageManager.PERMISSION_GRANTED) {
23001            String msg = "Permission Denial: isUserRunning() from pid="
23002                    + Binder.getCallingPid()
23003                    + ", uid=" + Binder.getCallingUid()
23004                    + " requires " + INTERACT_ACROSS_USERS;
23005            Slog.w(TAG, msg);
23006            throw new SecurityException(msg);
23007        }
23008        synchronized (this) {
23009            return mUserController.getStartedUserArrayLocked();
23010        }
23011    }
23012
23013    @Override
23014    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23015        mUserController.registerUserSwitchObserver(observer, name);
23016    }
23017
23018    @Override
23019    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23020        mUserController.unregisterUserSwitchObserver(observer);
23021    }
23022
23023    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23024        if (info == null) return null;
23025        ApplicationInfo newInfo = new ApplicationInfo(info);
23026        newInfo.initForUser(userId);
23027        return newInfo;
23028    }
23029
23030    public boolean isUserStopped(int userId) {
23031        synchronized (this) {
23032            return mUserController.getStartedUserStateLocked(userId) == null;
23033        }
23034    }
23035
23036    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23037        if (aInfo == null
23038                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23039            return aInfo;
23040        }
23041
23042        ActivityInfo info = new ActivityInfo(aInfo);
23043        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23044        return info;
23045    }
23046
23047    private boolean processSanityChecksLocked(ProcessRecord process) {
23048        if (process == null || process.thread == null) {
23049            return false;
23050        }
23051
23052        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23053        if (!isDebuggable) {
23054            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23055                return false;
23056            }
23057        }
23058
23059        return true;
23060    }
23061
23062    public boolean startBinderTracking() throws RemoteException {
23063        synchronized (this) {
23064            mBinderTransactionTrackingEnabled = true;
23065            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23066            // permission (same as profileControl).
23067            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23068                    != PackageManager.PERMISSION_GRANTED) {
23069                throw new SecurityException("Requires permission "
23070                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23071            }
23072
23073            for (int i = 0; i < mLruProcesses.size(); i++) {
23074                ProcessRecord process = mLruProcesses.get(i);
23075                if (!processSanityChecksLocked(process)) {
23076                    continue;
23077                }
23078                try {
23079                    process.thread.startBinderTracking();
23080                } catch (RemoteException e) {
23081                    Log.v(TAG, "Process disappared");
23082                }
23083            }
23084            return true;
23085        }
23086    }
23087
23088    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23089        try {
23090            synchronized (this) {
23091                mBinderTransactionTrackingEnabled = false;
23092                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23093                // permission (same as profileControl).
23094                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23095                        != PackageManager.PERMISSION_GRANTED) {
23096                    throw new SecurityException("Requires permission "
23097                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23098                }
23099
23100                if (fd == null) {
23101                    throw new IllegalArgumentException("null fd");
23102                }
23103
23104                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23105                pw.println("Binder transaction traces for all processes.\n");
23106                for (ProcessRecord process : mLruProcesses) {
23107                    if (!processSanityChecksLocked(process)) {
23108                        continue;
23109                    }
23110
23111                    pw.println("Traces for process: " + process.processName);
23112                    pw.flush();
23113                    try {
23114                        TransferPipe tp = new TransferPipe();
23115                        try {
23116                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23117                            tp.go(fd.getFileDescriptor());
23118                        } finally {
23119                            tp.kill();
23120                        }
23121                    } catch (IOException e) {
23122                        pw.println("Failure while dumping IPC traces from " + process +
23123                                ".  Exception: " + e);
23124                        pw.flush();
23125                    } catch (RemoteException e) {
23126                        pw.println("Got a RemoteException while dumping IPC traces from " +
23127                                process + ".  Exception: " + e);
23128                        pw.flush();
23129                    }
23130                }
23131                fd = null;
23132                return true;
23133            }
23134        } finally {
23135            if (fd != null) {
23136                try {
23137                    fd.close();
23138                } catch (IOException e) {
23139                }
23140            }
23141        }
23142    }
23143
23144    @VisibleForTesting
23145    final class LocalService extends ActivityManagerInternal {
23146        @Override
23147        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23148                int targetUserId) {
23149            synchronized (ActivityManagerService.this) {
23150                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23151                        targetPkg, intent, null, targetUserId);
23152            }
23153        }
23154
23155        @Override
23156        public String checkContentProviderAccess(String authority, int userId) {
23157            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23158        }
23159
23160        @Override
23161        public void onWakefulnessChanged(int wakefulness) {
23162            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23163        }
23164
23165        @Override
23166        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23167                String processName, String abiOverride, int uid, Runnable crashHandler) {
23168            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23169                    processName, abiOverride, uid, crashHandler);
23170        }
23171
23172        @Override
23173        public SleepToken acquireSleepToken(String tag) {
23174            Preconditions.checkNotNull(tag);
23175
23176            synchronized (ActivityManagerService.this) {
23177                SleepTokenImpl token = new SleepTokenImpl(tag);
23178                mSleepTokens.add(token);
23179                updateSleepIfNeededLocked();
23180                return token;
23181            }
23182        }
23183
23184        @Override
23185        public ComponentName getHomeActivityForUser(int userId) {
23186            synchronized (ActivityManagerService.this) {
23187                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23188                return homeActivity == null ? null : homeActivity.realActivity;
23189            }
23190        }
23191
23192        @Override
23193        public void onUserRemoved(int userId) {
23194            synchronized (ActivityManagerService.this) {
23195                ActivityManagerService.this.onUserStoppedLocked(userId);
23196            }
23197        }
23198
23199        @Override
23200        public void onLocalVoiceInteractionStarted(IBinder activity,
23201                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23202            synchronized (ActivityManagerService.this) {
23203                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23204                        voiceSession, voiceInteractor);
23205            }
23206        }
23207
23208        @Override
23209        public void notifyAppTransitionStarting(SparseIntArray reasons) {
23210            synchronized (ActivityManagerService.this) {
23211                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reasons);
23212            }
23213        }
23214
23215        @Override
23216        public void notifyAppTransitionFinished() {
23217            synchronized (ActivityManagerService.this) {
23218                mStackSupervisor.notifyAppTransitionDone();
23219            }
23220        }
23221
23222        @Override
23223        public void notifyAppTransitionCancelled() {
23224            synchronized (ActivityManagerService.this) {
23225                mStackSupervisor.notifyAppTransitionDone();
23226            }
23227        }
23228
23229        @Override
23230        public List<IBinder> getTopVisibleActivities() {
23231            synchronized (ActivityManagerService.this) {
23232                return mStackSupervisor.getTopVisibleActivities();
23233            }
23234        }
23235
23236        @Override
23237        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23238            synchronized (ActivityManagerService.this) {
23239                mStackSupervisor.setDockedStackMinimized(minimized);
23240            }
23241        }
23242
23243        @Override
23244        public void killForegroundAppsForUser(int userHandle) {
23245            synchronized (ActivityManagerService.this) {
23246                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23247                final int NP = mProcessNames.getMap().size();
23248                for (int ip = 0; ip < NP; ip++) {
23249                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23250                    final int NA = apps.size();
23251                    for (int ia = 0; ia < NA; ia++) {
23252                        final ProcessRecord app = apps.valueAt(ia);
23253                        if (app.persistent) {
23254                            // We don't kill persistent processes.
23255                            continue;
23256                        }
23257                        if (app.removed) {
23258                            procs.add(app);
23259                        } else if (app.userId == userHandle && app.foregroundActivities) {
23260                            app.removed = true;
23261                            procs.add(app);
23262                        }
23263                    }
23264                }
23265
23266                final int N = procs.size();
23267                for (int i = 0; i < N; i++) {
23268                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
23269                }
23270            }
23271        }
23272
23273        @Override
23274        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
23275            if (!(target instanceof PendingIntentRecord)) {
23276                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23277                return;
23278            }
23279            ((PendingIntentRecord) target).setWhitelistDuration(duration);
23280        }
23281
23282        @Override
23283        public void setDeviceIdleWhitelist(int[] appids) {
23284            synchronized (ActivityManagerService.this) {
23285                mDeviceIdleWhitelist = appids;
23286            }
23287        }
23288
23289        @Override
23290        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23291            synchronized (ActivityManagerService.this) {
23292                mDeviceIdleTempWhitelist = appids;
23293                setAppIdTempWhitelistStateLocked(changingAppId, adding);
23294            }
23295        }
23296
23297        @Override
23298        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23299                int userId) {
23300            Preconditions.checkNotNull(values, "Configuration must not be null");
23301            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23302            synchronized (ActivityManagerService.this) {
23303                updateConfigurationLocked(values, null, false, true, userId,
23304                        false /* deferResume */);
23305            }
23306        }
23307
23308        @Override
23309        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23310                Bundle bOptions) {
23311            Preconditions.checkNotNull(intents, "intents");
23312            final String[] resolvedTypes = new String[intents.length];
23313            for (int i = 0; i < intents.length; i++) {
23314                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23315            }
23316
23317            // UID of the package on user userId.
23318            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23319            // packageUid may not be initialized.
23320            int packageUid = 0;
23321            try {
23322                packageUid = AppGlobals.getPackageManager().getPackageUid(
23323                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23324            } catch (RemoteException e) {
23325                // Shouldn't happen.
23326            }
23327
23328            synchronized (ActivityManagerService.this) {
23329                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23330                        /*resultTo*/ null, bOptions, userId);
23331            }
23332        }
23333
23334        @Override
23335        public int getUidProcessState(int uid) {
23336            return getUidState(uid);
23337        }
23338
23339        @Override
23340        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23341            synchronized (ActivityManagerService.this) {
23342
23343                // We might change the visibilities here, so prepare an empty app transition which
23344                // might be overridden later if we actually change visibilities.
23345                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23346                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23347                mWindowManager.executeAppTransition();
23348            }
23349            if (callback != null) {
23350                callback.run();
23351            }
23352        }
23353
23354        @Override
23355        public boolean isSystemReady() {
23356            // no need to synchronize(this) just to read & return the value
23357            return mSystemReady;
23358        }
23359
23360        @Override
23361        public void notifyKeyguardTrustedChanged() {
23362            synchronized (ActivityManagerService.this) {
23363                if (mKeyguardController.isKeyguardShowing()) {
23364                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23365                }
23366            }
23367        }
23368
23369        /**
23370         * Sets if the given pid has an overlay UI or not.
23371         *
23372         * @param pid The pid we are setting overlay UI for.
23373         * @param hasOverlayUi True if the process has overlay UI.
23374         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
23375         */
23376        @Override
23377        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
23378            synchronized (ActivityManagerService.this) {
23379                final ProcessRecord pr;
23380                synchronized (mPidsSelfLocked) {
23381                    pr = mPidsSelfLocked.get(pid);
23382                    if (pr == null) {
23383                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
23384                        return;
23385                    }
23386                }
23387                if (pr.hasOverlayUi == hasOverlayUi) {
23388                    return;
23389                }
23390                pr.hasOverlayUi = hasOverlayUi;
23391                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
23392                updateOomAdjLocked(pr);
23393            }
23394        }
23395
23396        /**
23397         * Called after the network policy rules are updated by
23398         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
23399         * and {@param procStateSeq}.
23400         */
23401        @Override
23402        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
23403            if (DEBUG_NETWORK) {
23404                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
23405                        + uid + " seq: " + procStateSeq);
23406            }
23407            UidRecord record;
23408            synchronized (ActivityManagerService.this) {
23409                record = mActiveUids.get(uid);
23410                if (record == null) {
23411                    if (DEBUG_NETWORK) {
23412                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
23413                                + " procStateSeq: " + procStateSeq);
23414                    }
23415                    return;
23416                }
23417            }
23418            synchronized (record.lock) {
23419                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23420                    if (DEBUG_NETWORK) {
23421                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
23422                                + " been handled for uid: " + uid);
23423                    }
23424                    return;
23425                }
23426                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
23427                if (record.curProcStateSeq > procStateSeq) {
23428                    if (DEBUG_NETWORK) {
23429                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
23430                                + ", curProcstateSeq: " + record.curProcStateSeq
23431                                + ", procStateSeq: " + procStateSeq);
23432                    }
23433                    return;
23434                }
23435                if (record.waitingForNetwork) {
23436                    if (DEBUG_NETWORK) {
23437                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
23438                                + ", procStateSeq: " + procStateSeq);
23439                    }
23440                    record.lock.notifyAll();
23441                }
23442            }
23443        }
23444    }
23445
23446    /**
23447     * Called by app main thread to wait for the network policy rules to get udpated.
23448     *
23449     * @param procStateSeq The sequence number indicating the process state change that the main
23450     *                     thread is interested in.
23451     */
23452    @Override
23453    public void waitForNetworkStateUpdate(long procStateSeq) {
23454        final int callingUid = Binder.getCallingUid();
23455        if (DEBUG_NETWORK) {
23456            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
23457        }
23458        UidRecord record;
23459        synchronized (this) {
23460            record = mActiveUids.get(callingUid);
23461            if (record == null) {
23462                return;
23463            }
23464        }
23465        synchronized (record.lock) {
23466            if (record.lastDispatchedProcStateSeq < procStateSeq) {
23467                if (DEBUG_NETWORK) {
23468                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
23469                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
23470                            + " lastProcStateSeqDispatchedToObservers: "
23471                            + record.lastDispatchedProcStateSeq);
23472                }
23473                return;
23474            }
23475            if (record.curProcStateSeq > procStateSeq) {
23476                if (DEBUG_NETWORK) {
23477                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
23478                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
23479                            + ", procStateSeq: " + procStateSeq);
23480                }
23481                return;
23482            }
23483            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23484                if (DEBUG_NETWORK) {
23485                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
23486                            + procStateSeq + ", so no need to wait. Uid: "
23487                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
23488                            + record.lastNetworkUpdatedProcStateSeq);
23489                }
23490                return;
23491            }
23492            try {
23493                if (DEBUG_NETWORK) {
23494                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
23495                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
23496                }
23497                final long startTime = SystemClock.uptimeMillis();
23498                record.waitingForNetwork = true;
23499                record.lock.wait(WAIT_FOR_NETWORK_TIMEOUT_MS);
23500                record.waitingForNetwork = false;
23501                final long totalTime = SystemClock.uptimeMillis() - startTime;
23502                if (DEBUG_NETWORK ||  totalTime > WAIT_FOR_NETWORK_TIMEOUT_MS / 2) {
23503                    Slog.d(TAG_NETWORK, "Total time waited for network rules to get updated: "
23504                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
23505                            + procStateSeq);
23506                }
23507            } catch (InterruptedException e) {
23508                Thread.currentThread().interrupt();
23509            }
23510        }
23511    }
23512
23513    private final class SleepTokenImpl extends SleepToken {
23514        private final String mTag;
23515        private final long mAcquireTime;
23516
23517        public SleepTokenImpl(String tag) {
23518            mTag = tag;
23519            mAcquireTime = SystemClock.uptimeMillis();
23520        }
23521
23522        @Override
23523        public void release() {
23524            synchronized (ActivityManagerService.this) {
23525                if (mSleepTokens.remove(this)) {
23526                    updateSleepIfNeededLocked();
23527                }
23528            }
23529        }
23530
23531        @Override
23532        public String toString() {
23533            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
23534        }
23535    }
23536
23537    /**
23538     * An implementation of IAppTask, that allows an app to manage its own tasks via
23539     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
23540     * only the process that calls getAppTasks() can call the AppTask methods.
23541     */
23542    class AppTaskImpl extends IAppTask.Stub {
23543        private int mTaskId;
23544        private int mCallingUid;
23545
23546        public AppTaskImpl(int taskId, int callingUid) {
23547            mTaskId = taskId;
23548            mCallingUid = callingUid;
23549        }
23550
23551        private void checkCaller() {
23552            if (mCallingUid != Binder.getCallingUid()) {
23553                throw new SecurityException("Caller " + mCallingUid
23554                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
23555            }
23556        }
23557
23558        @Override
23559        public void finishAndRemoveTask() {
23560            checkCaller();
23561
23562            synchronized (ActivityManagerService.this) {
23563                long origId = Binder.clearCallingIdentity();
23564                try {
23565                    // We remove the task from recents to preserve backwards
23566                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
23567                            REMOVE_FROM_RECENTS)) {
23568                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23569                    }
23570                } finally {
23571                    Binder.restoreCallingIdentity(origId);
23572                }
23573            }
23574        }
23575
23576        @Override
23577        public ActivityManager.RecentTaskInfo getTaskInfo() {
23578            checkCaller();
23579
23580            synchronized (ActivityManagerService.this) {
23581                long origId = Binder.clearCallingIdentity();
23582                try {
23583                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23584                    if (tr == null) {
23585                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23586                    }
23587                    return createRecentTaskInfoFromTaskRecord(tr);
23588                } finally {
23589                    Binder.restoreCallingIdentity(origId);
23590                }
23591            }
23592        }
23593
23594        @Override
23595        public void moveToFront() {
23596            checkCaller();
23597            // Will bring task to front if it already has a root activity.
23598            final long origId = Binder.clearCallingIdentity();
23599            try {
23600                synchronized (this) {
23601                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
23602                }
23603            } finally {
23604                Binder.restoreCallingIdentity(origId);
23605            }
23606        }
23607
23608        @Override
23609        public int startActivity(IBinder whoThread, String callingPackage,
23610                Intent intent, String resolvedType, Bundle bOptions) {
23611            checkCaller();
23612
23613            int callingUser = UserHandle.getCallingUserId();
23614            TaskRecord tr;
23615            IApplicationThread appThread;
23616            synchronized (ActivityManagerService.this) {
23617                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23618                if (tr == null) {
23619                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23620                }
23621                appThread = IApplicationThread.Stub.asInterface(whoThread);
23622                if (appThread == null) {
23623                    throw new IllegalArgumentException("Bad app thread " + appThread);
23624                }
23625            }
23626            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
23627                    resolvedType, null, null, null, null, 0, 0, null, null,
23628                    null, bOptions, false, callingUser, null, tr);
23629        }
23630
23631        @Override
23632        public void setExcludeFromRecents(boolean exclude) {
23633            checkCaller();
23634
23635            synchronized (ActivityManagerService.this) {
23636                long origId = Binder.clearCallingIdentity();
23637                try {
23638                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23639                    if (tr == null) {
23640                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23641                    }
23642                    Intent intent = tr.getBaseIntent();
23643                    if (exclude) {
23644                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23645                    } else {
23646                        intent.setFlags(intent.getFlags()
23647                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23648                    }
23649                } finally {
23650                    Binder.restoreCallingIdentity(origId);
23651                }
23652            }
23653        }
23654    }
23655
23656    /**
23657     * Kill processes for the user with id userId and that depend on the package named packageName
23658     */
23659    @Override
23660    public void killPackageDependents(String packageName, int userId) {
23661        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
23662        if (packageName == null) {
23663            throw new NullPointerException(
23664                    "Cannot kill the dependents of a package without its name.");
23665        }
23666
23667        long callingId = Binder.clearCallingIdentity();
23668        IPackageManager pm = AppGlobals.getPackageManager();
23669        int pkgUid = -1;
23670        try {
23671            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
23672        } catch (RemoteException e) {
23673        }
23674        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
23675            throw new IllegalArgumentException(
23676                    "Cannot kill dependents of non-existing package " + packageName);
23677        }
23678        try {
23679            synchronized(this) {
23680                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
23681                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
23682                        "dep: " + packageName);
23683            }
23684        } finally {
23685            Binder.restoreCallingIdentity(callingId);
23686        }
23687    }
23688
23689    @Override
23690    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
23691        final int userId = intent.getCreatorUserHandle().getIdentifier();
23692        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
23693            return false;
23694        }
23695        IIntentSender target = intent.getTarget();
23696        if (!(target instanceof PendingIntentRecord)) {
23697            return false;
23698        }
23699        final PendingIntentRecord record = (PendingIntentRecord) target;
23700        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
23701                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
23702        // For direct boot aware activities, they can be shown without triggering a work challenge
23703        // before the profile user is unlocked.
23704        return rInfo != null && rInfo.activityInfo != null;
23705    }
23706
23707    @Override
23708    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
23709            throws RemoteException {
23710        final long callingId = Binder.clearCallingIdentity();
23711        try {
23712            mKeyguardController.dismissKeyguard(token, callback);
23713        } finally {
23714            Binder.restoreCallingIdentity(callingId);
23715        }
23716    }
23717
23718    @Override
23719    public int restartUserInBackground(final int userId) {
23720        return mUserController.restartUser(userId, /* foreground */ false);
23721    }
23722
23723    @Override
23724    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
23725        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
23726                "scheduleApplicationInfoChanged()");
23727
23728        synchronized (this) {
23729            final long origId = Binder.clearCallingIdentity();
23730            try {
23731                updateApplicationInfoLocked(packageNames, userId);
23732            } finally {
23733                Binder.restoreCallingIdentity(origId);
23734            }
23735        }
23736    }
23737
23738    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
23739        final PackageManagerInternal packageManager = getPackageManagerInternalLocked();
23740        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
23741        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23742            final ProcessRecord app = mLruProcesses.get(i);
23743            if (app.thread == null || app.pid == Process.myPid()) {
23744                continue;
23745            }
23746
23747            if (userId != UserHandle.USER_ALL && app.userId != userId) {
23748                continue;
23749            }
23750
23751            final int packageCount = app.pkgList.size();
23752            for (int j = 0; j < packageCount; j++) {
23753                final String packageName = app.pkgList.keyAt(j);
23754                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
23755                    try {
23756                        final ApplicationInfo ai = packageManager.getApplicationInfo(
23757                                packageName, app.userId);
23758                        if (ai != null) {
23759                            app.thread.scheduleApplicationInfoChanged(ai);
23760                        }
23761                    } catch (RemoteException e) {
23762                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
23763                                    packageName, app));
23764                    }
23765                }
23766            }
23767        }
23768    }
23769
23770    /**
23771     * Attach an agent to the specified process (proces name or PID)
23772     */
23773    public void attachAgent(String process, String path) {
23774        try {
23775            synchronized (this) {
23776                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
23777                if (proc == null || proc.thread == null) {
23778                    throw new IllegalArgumentException("Unknown process: " + process);
23779                }
23780
23781                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23782                if (!isDebuggable) {
23783                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23784                        throw new SecurityException("Process not debuggable: " + proc);
23785                    }
23786                }
23787
23788                proc.thread.attachAgent(path);
23789            }
23790        } catch (RemoteException e) {
23791            throw new IllegalStateException("Process disappeared");
23792        }
23793    }
23794
23795    @VisibleForTesting
23796    public static class Injector {
23797        public AppOpsService getAppOpsService(File file, Handler handler) {
23798            return new AppOpsService(file, handler);
23799        }
23800
23801        public Handler getUiHandler(ActivityManagerService service) {
23802            return service.new UiHandler();
23803        }
23804
23805        public boolean isNetworkRestrictedForUid(int uid) {
23806            // TODO: add implementation
23807            return false;
23808        }
23809    }
23810}
23811